create-template-html-css 1.9.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/COMPONENTS-GALLERY.html +735 -747
- package/README.md +179 -2
- package/bin/cli.js +15 -3
- package/package.json +1 -1
- package/templates/blackjack/index.html +97 -0
- package/templates/blackjack/script.js +381 -0
- package/templates/blackjack/style.css +452 -0
- package/templates/breakout/index.html +56 -0
- package/templates/breakout/script.js +387 -0
- package/templates/breakout/style.css +239 -0
- package/templates/connect-four/index.html +78 -0
- package/templates/connect-four/script.js +413 -0
- package/templates/connect-four/style.css +426 -0
- package/templates/dice-game/index.html +99 -0
- package/templates/dice-game/script.js +291 -0
- package/templates/dice-game/style.css +403 -0
- package/templates/flappy-bird/index.html +47 -0
- package/templates/flappy-bird/script.js +394 -0
- package/templates/flappy-bird/style.css +243 -0
- package/templates/game-2048/index.html +59 -0
- package/templates/game-2048/script.js +269 -0
- package/templates/game-2048/style.css +281 -0
- package/templates/pong/index.html +90 -0
- package/templates/pong/script.js +364 -0
- package/templates/pong/style.css +371 -0
- package/templates/rock-paper-scissors/index.html +84 -0
- package/templates/rock-paper-scissors/script.js +199 -0
- package/templates/rock-paper-scissors/style.css +295 -0
- package/templates/simon-says/index.html +64 -0
- package/templates/simon-says/script.js +206 -0
- package/templates/simon-says/style.css +250 -0
- package/templates/slot-machine/index.html +112 -0
- package/templates/slot-machine/script.js +238 -0
- package/templates/slot-machine/style.css +464 -0
- package/templates/tetris/index.html +84 -0
- package/templates/tetris/script.js +447 -0
- package/templates/tetris/style.css +286 -0
- package/templates/whack-a-mole/index.html +85 -0
- package/templates/whack-a-mole/script.js +172 -0
- package/{demo-games/snake-game → templates/whack-a-mole}/style.css +114 -97
- package/PUBLISH-GUIDE.md +0 -112
- package/create-template-html-css-1.8.0.tgz +0 -0
- package/demo-games/guess-number/index.html +0 -71
- package/demo-games/guess-number/script.js +0 -216
- package/demo-games/guess-number/style.css +0 -337
- package/demo-games/memory-game/index.html +0 -50
- package/demo-games/memory-game/script.js +0 -216
- package/demo-games/memory-game/style.css +0 -288
- package/demo-games/snake-game/index.html +0 -61
- package/demo-games/snake-game/script.js +0 -360
- package/demo-games/tic-tac-toe/index.html +0 -57
- package/demo-games/tic-tac-toe/script.js +0 -156
- package/demo-games/tic-tac-toe/style.css +0 -244
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
// Game state
|
|
2
|
+
let gameState = {
|
|
3
|
+
credits: parseInt(localStorage.getItem('blackjackCredits')) || 1000,
|
|
4
|
+
currentBet: 0,
|
|
5
|
+
wins: parseInt(localStorage.getItem('blackjackWins')) || 0,
|
|
6
|
+
deck: [],
|
|
7
|
+
playerHand: [],
|
|
8
|
+
dealerHand: [],
|
|
9
|
+
gameActive: false,
|
|
10
|
+
dealerTurn: false
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// Card suits and values
|
|
14
|
+
const suits = ['♠', '♥', '♦', '♣'];
|
|
15
|
+
const values = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
|
|
16
|
+
const suitColors = { '♠': 'black', '♥': 'red', '♦': 'red', '♣': 'black' };
|
|
17
|
+
|
|
18
|
+
// Initialize deck
|
|
19
|
+
function createDeck() {
|
|
20
|
+
const deck = [];
|
|
21
|
+
for (let suit of suits) {
|
|
22
|
+
for (let value of values) {
|
|
23
|
+
deck.push({ suit, value });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return deck;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Shuffle deck
|
|
30
|
+
function shuffleDeck(deck) {
|
|
31
|
+
for (let i = deck.length - 1; i > 0; i--) {
|
|
32
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
33
|
+
[deck[i], deck[j]] = [deck[j], deck[i]];
|
|
34
|
+
}
|
|
35
|
+
return deck;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Deal card
|
|
39
|
+
function dealCard() {
|
|
40
|
+
if (gameState.deck.length < 10) {
|
|
41
|
+
gameState.deck = shuffleDeck(createDeck());
|
|
42
|
+
}
|
|
43
|
+
return gameState.deck.pop();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Calculate hand value
|
|
47
|
+
function calculateHandValue(hand) {
|
|
48
|
+
let value = 0;
|
|
49
|
+
let aces = 0;
|
|
50
|
+
|
|
51
|
+
for (let card of hand) {
|
|
52
|
+
if (card.value === 'A') {
|
|
53
|
+
aces++;
|
|
54
|
+
value += 11;
|
|
55
|
+
} else if (['J', 'Q', 'K'].includes(card.value)) {
|
|
56
|
+
value += 10;
|
|
57
|
+
} else {
|
|
58
|
+
value += parseInt(card.value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Adjust for aces
|
|
63
|
+
while (value > 21 && aces > 0) {
|
|
64
|
+
value -= 10;
|
|
65
|
+
aces--;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check for blackjack
|
|
72
|
+
function isBlackjack(hand) {
|
|
73
|
+
return hand.length === 2 && calculateHandValue(hand) === 21;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Render card
|
|
77
|
+
function renderCard(card, hidden = false) {
|
|
78
|
+
const cardEl = document.createElement('div');
|
|
79
|
+
cardEl.className = 'card';
|
|
80
|
+
|
|
81
|
+
if (hidden) {
|
|
82
|
+
cardEl.classList.add('card-back');
|
|
83
|
+
cardEl.innerHTML = `
|
|
84
|
+
<div class="card-pattern">🂠</div>
|
|
85
|
+
`;
|
|
86
|
+
} else {
|
|
87
|
+
cardEl.classList.add('card-front');
|
|
88
|
+
const color = suitColors[card.suit];
|
|
89
|
+
cardEl.style.color = color;
|
|
90
|
+
cardEl.innerHTML = `
|
|
91
|
+
<div class="card-corner top-left">
|
|
92
|
+
<div class="card-value">${card.value}</div>
|
|
93
|
+
<div class="card-suit">${card.suit}</div>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="card-center">${card.suit}</div>
|
|
96
|
+
<div class="card-corner bottom-right">
|
|
97
|
+
<div class="card-value">${card.value}</div>
|
|
98
|
+
<div class="card-suit">${card.suit}</div>
|
|
99
|
+
</div>
|
|
100
|
+
`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Add animation
|
|
104
|
+
setTimeout(() => cardEl.classList.add('dealt'), 10);
|
|
105
|
+
|
|
106
|
+
return cardEl;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Update display
|
|
110
|
+
function updateDisplay() {
|
|
111
|
+
document.getElementById('credits').textContent = gameState.credits;
|
|
112
|
+
document.getElementById('bet').textContent = gameState.currentBet;
|
|
113
|
+
document.getElementById('wins').textContent = gameState.wins;
|
|
114
|
+
|
|
115
|
+
// Update scores
|
|
116
|
+
const playerValue = calculateHandValue(gameState.playerHand);
|
|
117
|
+
document.getElementById('playerScore').textContent = playerValue;
|
|
118
|
+
|
|
119
|
+
if (gameState.dealerTurn) {
|
|
120
|
+
const dealerValue = calculateHandValue(gameState.dealerHand);
|
|
121
|
+
document.getElementById('dealerScore').textContent = dealerValue;
|
|
122
|
+
} else {
|
|
123
|
+
document.getElementById('dealerScore').textContent = gameState.dealerHand.length > 0 ? '?' : '0';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Render hands
|
|
128
|
+
function renderHands(revealDealer = false) {
|
|
129
|
+
const playerHandEl = document.getElementById('playerHand');
|
|
130
|
+
const dealerHandEl = document.getElementById('dealerHand');
|
|
131
|
+
|
|
132
|
+
playerHandEl.innerHTML = '';
|
|
133
|
+
dealerHandEl.innerHTML = '';
|
|
134
|
+
|
|
135
|
+
// Render player hand
|
|
136
|
+
gameState.playerHand.forEach(card => {
|
|
137
|
+
playerHandEl.appendChild(renderCard(card));
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Render dealer hand
|
|
141
|
+
gameState.dealerHand.forEach((card, index) => {
|
|
142
|
+
const hideCard = index === 0 && !revealDealer;
|
|
143
|
+
dealerHandEl.appendChild(renderCard(card, hideCard));
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
updateDisplay();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Handle bet
|
|
150
|
+
document.querySelectorAll('.bet-btn').forEach(btn => {
|
|
151
|
+
btn.addEventListener('click', () => {
|
|
152
|
+
const amount = parseInt(btn.dataset.amount);
|
|
153
|
+
|
|
154
|
+
if (gameState.credits >= amount) {
|
|
155
|
+
gameState.currentBet += amount;
|
|
156
|
+
updateDisplay();
|
|
157
|
+
document.getElementById('dealBtn').disabled = false;
|
|
158
|
+
} else {
|
|
159
|
+
showMessage('אין מספיק קרדיטים!', 'error');
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Start game
|
|
165
|
+
document.getElementById('dealBtn').addEventListener('click', startGame);
|
|
166
|
+
|
|
167
|
+
function startGame() {
|
|
168
|
+
if (gameState.currentBet === 0) {
|
|
169
|
+
showMessage('בחר הימור תחילה!', 'error');
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Deduct bet from credits
|
|
174
|
+
gameState.credits -= gameState.currentBet;
|
|
175
|
+
|
|
176
|
+
// Initialize
|
|
177
|
+
gameState.deck = shuffleDeck(createDeck());
|
|
178
|
+
gameState.playerHand = [];
|
|
179
|
+
gameState.dealerHand = [];
|
|
180
|
+
gameState.gameActive = true;
|
|
181
|
+
gameState.dealerTurn = false;
|
|
182
|
+
|
|
183
|
+
// Deal initial cards
|
|
184
|
+
gameState.playerHand.push(dealCard());
|
|
185
|
+
gameState.dealerHand.push(dealCard());
|
|
186
|
+
gameState.playerHand.push(dealCard());
|
|
187
|
+
gameState.dealerHand.push(dealCard());
|
|
188
|
+
|
|
189
|
+
renderHands();
|
|
190
|
+
|
|
191
|
+
// Hide betting, show actions
|
|
192
|
+
document.getElementById('bettingArea').style.display = 'none';
|
|
193
|
+
document.getElementById('actionButtons').style.display = 'flex';
|
|
194
|
+
document.getElementById('resultMessage').textContent = '';
|
|
195
|
+
document.getElementById('nextRoundBtn').style.display = 'none';
|
|
196
|
+
|
|
197
|
+
// Check for blackjacks
|
|
198
|
+
if (isBlackjack(gameState.playerHand)) {
|
|
199
|
+
if (isBlackjack(gameState.dealerHand)) {
|
|
200
|
+
endGame('push'); // Both have blackjack
|
|
201
|
+
} else {
|
|
202
|
+
endGame('blackjack'); // Player blackjack
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
updateDisplay();
|
|
207
|
+
saveGame();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Hit
|
|
211
|
+
document.getElementById('hitBtn').addEventListener('click', () => {
|
|
212
|
+
if (!gameState.gameActive) return;
|
|
213
|
+
|
|
214
|
+
gameState.playerHand.push(dealCard());
|
|
215
|
+
renderHands();
|
|
216
|
+
|
|
217
|
+
const playerValue = calculateHandValue(gameState.playerHand);
|
|
218
|
+
|
|
219
|
+
if (playerValue > 21) {
|
|
220
|
+
endGame('bust');
|
|
221
|
+
} else if (playerValue === 21) {
|
|
222
|
+
stand();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Disable double after hit
|
|
226
|
+
document.getElementById('doubleBtn').disabled = true;
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Stand
|
|
230
|
+
document.getElementById('standBtn').addEventListener('click', stand);
|
|
231
|
+
|
|
232
|
+
function stand() {
|
|
233
|
+
if (!gameState.gameActive) return;
|
|
234
|
+
|
|
235
|
+
gameState.dealerTurn = true;
|
|
236
|
+
document.getElementById('actionButtons').style.display = 'none';
|
|
237
|
+
|
|
238
|
+
renderHands(true);
|
|
239
|
+
|
|
240
|
+
// Dealer's turn
|
|
241
|
+
dealerPlay();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Double down
|
|
245
|
+
document.getElementById('doubleBtn').addEventListener('click', () => {
|
|
246
|
+
if (!gameState.gameActive) return;
|
|
247
|
+
|
|
248
|
+
if (gameState.credits >= gameState.currentBet) {
|
|
249
|
+
gameState.credits -= gameState.currentBet;
|
|
250
|
+
gameState.currentBet *= 2;
|
|
251
|
+
updateDisplay();
|
|
252
|
+
|
|
253
|
+
gameState.playerHand.push(dealCard());
|
|
254
|
+
renderHands();
|
|
255
|
+
|
|
256
|
+
const playerValue = calculateHandValue(gameState.playerHand);
|
|
257
|
+
|
|
258
|
+
if (playerValue > 21) {
|
|
259
|
+
endGame('bust');
|
|
260
|
+
} else {
|
|
261
|
+
stand();
|
|
262
|
+
}
|
|
263
|
+
} else {
|
|
264
|
+
showMessage('אין מספיק קרדיטים להכפלה!', 'error');
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Dealer play
|
|
269
|
+
async function dealerPlay() {
|
|
270
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
271
|
+
|
|
272
|
+
while (calculateHandValue(gameState.dealerHand) < 17) {
|
|
273
|
+
await new Promise(resolve => setTimeout(resolve, 800));
|
|
274
|
+
gameState.dealerHand.push(dealCard());
|
|
275
|
+
renderHands(true);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const playerValue = calculateHandValue(gameState.playerHand);
|
|
279
|
+
const dealerValue = calculateHandValue(gameState.dealerHand);
|
|
280
|
+
|
|
281
|
+
if (dealerValue > 21) {
|
|
282
|
+
endGame('win');
|
|
283
|
+
} else if (dealerValue > playerValue) {
|
|
284
|
+
endGame('lose');
|
|
285
|
+
} else if (dealerValue < playerValue) {
|
|
286
|
+
endGame('win');
|
|
287
|
+
} else {
|
|
288
|
+
endGame('push');
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// End game
|
|
293
|
+
function endGame(result) {
|
|
294
|
+
gameState.gameActive = false;
|
|
295
|
+
gameState.dealerTurn = true;
|
|
296
|
+
renderHands(true);
|
|
297
|
+
|
|
298
|
+
let message = '';
|
|
299
|
+
let winAmount = 0;
|
|
300
|
+
|
|
301
|
+
switch (result) {
|
|
302
|
+
case 'blackjack':
|
|
303
|
+
winAmount = Math.floor(gameState.currentBet * 2.5); // 3:2 payout
|
|
304
|
+
message = '🎉 BLACKJACK! אתה מנצח!';
|
|
305
|
+
gameState.wins++;
|
|
306
|
+
break;
|
|
307
|
+
case 'win':
|
|
308
|
+
winAmount = gameState.currentBet * 2;
|
|
309
|
+
message = '🎉 ניצחת!';
|
|
310
|
+
gameState.wins++;
|
|
311
|
+
break;
|
|
312
|
+
case 'lose':
|
|
313
|
+
message = '😢 הפסדת!';
|
|
314
|
+
break;
|
|
315
|
+
case 'push':
|
|
316
|
+
winAmount = gameState.currentBet;
|
|
317
|
+
message = '🤝 תיקו!';
|
|
318
|
+
break;
|
|
319
|
+
case 'bust':
|
|
320
|
+
message = '💥 עברת את 21! הפסדת!';
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
gameState.credits += winAmount;
|
|
325
|
+
|
|
326
|
+
if (winAmount > 0) {
|
|
327
|
+
message += ` (+${winAmount})`;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
showMessage(message, result === 'lose' || result === 'bust' ? 'error' : 'success');
|
|
331
|
+
|
|
332
|
+
document.getElementById('nextRoundBtn').style.display = 'block';
|
|
333
|
+
|
|
334
|
+
updateDisplay();
|
|
335
|
+
saveGame();
|
|
336
|
+
|
|
337
|
+
// Check if out of credits
|
|
338
|
+
if (gameState.credits < 10) {
|
|
339
|
+
setTimeout(() => {
|
|
340
|
+
alert('נגמרו הקרדיטים! מקבל 1000 קרדיטים חדשים.');
|
|
341
|
+
gameState.credits = 1000;
|
|
342
|
+
updateDisplay();
|
|
343
|
+
saveGame();
|
|
344
|
+
}, 1000);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Next round
|
|
349
|
+
document.getElementById('nextRoundBtn').addEventListener('click', () => {
|
|
350
|
+
gameState.currentBet = 0;
|
|
351
|
+
gameState.playerHand = [];
|
|
352
|
+
gameState.dealerHand = [];
|
|
353
|
+
|
|
354
|
+
document.getElementById('bettingArea').style.display = 'block';
|
|
355
|
+
document.getElementById('actionButtons').style.display = 'none';
|
|
356
|
+
document.getElementById('nextRoundBtn').style.display = 'none';
|
|
357
|
+
document.getElementById('dealBtn').disabled = true;
|
|
358
|
+
document.getElementById('doubleBtn').disabled = false;
|
|
359
|
+
document.getElementById('resultMessage').textContent = '';
|
|
360
|
+
|
|
361
|
+
renderHands();
|
|
362
|
+
updateDisplay();
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// Show message
|
|
366
|
+
function showMessage(text, type = 'info') {
|
|
367
|
+
const messageEl = document.getElementById('resultMessage');
|
|
368
|
+
messageEl.textContent = text;
|
|
369
|
+
messageEl.className = `result-message ${type}`;
|
|
370
|
+
messageEl.style.display = 'block';
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Save game
|
|
374
|
+
function saveGame() {
|
|
375
|
+
localStorage.setItem('blackjackCredits', gameState.credits);
|
|
376
|
+
localStorage.setItem('blackjackWins', gameState.wins);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Initialize
|
|
380
|
+
updateDisplay();
|
|
381
|
+
renderHands();
|