create-template-html-css 1.8.1 → 2.0.0

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +179 -2
  3. package/bin/cli.js +20 -2
  4. package/package.json +1 -1
  5. package/templates/blackjack/index.html +97 -0
  6. package/templates/blackjack/script.js +381 -0
  7. package/templates/blackjack/style.css +452 -0
  8. package/templates/breakout/index.html +56 -0
  9. package/templates/breakout/script.js +387 -0
  10. package/templates/breakout/style.css +239 -0
  11. package/templates/connect-four/index.html +78 -0
  12. package/templates/connect-four/script.js +413 -0
  13. package/templates/connect-four/style.css +426 -0
  14. package/templates/dice-game/index.html +99 -0
  15. package/templates/dice-game/script.js +291 -0
  16. package/templates/dice-game/style.css +403 -0
  17. package/templates/flappy-bird/index.html +47 -0
  18. package/templates/flappy-bird/script.js +394 -0
  19. package/templates/flappy-bird/style.css +243 -0
  20. package/templates/game-2048/index.html +59 -0
  21. package/templates/game-2048/script.js +269 -0
  22. package/templates/game-2048/style.css +281 -0
  23. package/templates/guess-number/index.html +71 -0
  24. package/templates/guess-number/script.js +216 -0
  25. package/templates/guess-number/style.css +337 -0
  26. package/templates/memory-game/index.html +50 -0
  27. package/templates/memory-game/script.js +216 -0
  28. package/templates/memory-game/style.css +288 -0
  29. package/templates/pong/index.html +90 -0
  30. package/templates/pong/script.js +364 -0
  31. package/templates/pong/style.css +371 -0
  32. package/templates/rock-paper-scissors/index.html +84 -0
  33. package/templates/rock-paper-scissors/script.js +199 -0
  34. package/templates/rock-paper-scissors/style.css +295 -0
  35. package/templates/simon-says/index.html +64 -0
  36. package/templates/simon-says/script.js +206 -0
  37. package/templates/simon-says/style.css +250 -0
  38. package/templates/slot-machine/index.html +112 -0
  39. package/templates/slot-machine/script.js +238 -0
  40. package/templates/slot-machine/style.css +464 -0
  41. package/templates/snake-game/index.html +61 -0
  42. package/templates/snake-game/script.js +360 -0
  43. package/templates/snake-game/style.css +246 -0
  44. package/templates/tetris/index.html +84 -0
  45. package/templates/tetris/script.js +447 -0
  46. package/templates/tetris/style.css +286 -0
  47. package/templates/tic-tac-toe/index.html +57 -0
  48. package/templates/tic-tac-toe/script.js +156 -0
  49. package/templates/tic-tac-toe/style.css +244 -0
  50. package/templates/whack-a-mole/index.html +85 -0
  51. package/templates/whack-a-mole/script.js +172 -0
  52. package/templates/whack-a-mole/style.css +263 -0
  53. package/COMPONENTS-GALLERY.html +0 -773
  54. package/PUBLISH-GUIDE.md +0 -112
  55. package/create-template-html-css-1.8.0.tgz +0 -0
@@ -0,0 +1,61 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{name}} - Snake Game</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <div class="game-card">
12
+ <h1>Snake Game</h1>
13
+
14
+ <div class="game-info">
15
+ <div class="info-item">
16
+ <span class="label">Score:</span>
17
+ <span id="score" class="value">0</span>
18
+ </div>
19
+ <div class="info-item">
20
+ <span class="label">High Score:</span>
21
+ <span id="highScore" class="value">0</span>
22
+ </div>
23
+ <div class="info-item">
24
+ <span class="label">Speed:</span>
25
+ <span id="speed" class="value">Normal</span>
26
+ </div>
27
+ </div>
28
+
29
+ <canvas id="gameCanvas" width="400" height="400"></canvas>
30
+
31
+ <div class="message" id="message">
32
+ Press SPACE or tap Start to begin
33
+ </div>
34
+
35
+ <div class="controls">
36
+ <div class="arrow-buttons">
37
+ <button class="arrow-btn" id="upBtn">↑</button>
38
+ <div class="arrow-row">
39
+ <button class="arrow-btn" id="leftBtn">←</button>
40
+ <button class="arrow-btn" id="downBtn">↓</button>
41
+ <button class="arrow-btn" id="rightBtn">→</button>
42
+ </div>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="button-group">
47
+ <button id="startBtn" class="btn btn-success">Start</button>
48
+ <button id="pauseBtn" class="btn btn-warning">Pause</button>
49
+ <button id="resetBtn" class="btn btn-danger">Reset</button>
50
+ </div>
51
+
52
+ <div class="instructions">
53
+ <p>🎮 Use Arrow Keys or Buttons to control the snake</p>
54
+ <p>🍎 Eat apples to grow and increase score</p>
55
+ <p>⚠️ Don't hit walls or yourself!</p>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ <script src="script.js"></script>
60
+ </body>
61
+ </html>
@@ -0,0 +1,360 @@
1
+ // Snake Game Logic
2
+
3
+ const canvas = document.getElementById('gameCanvas');
4
+ const ctx = canvas.getContext('2d');
5
+ const scoreDisplay = document.getElementById('score');
6
+ const highScoreDisplay = document.getElementById('highScore');
7
+ const speedDisplay = document.getElementById('speed');
8
+ const messageDisplay = document.getElementById('message');
9
+ const startBtn = document.getElementById('startBtn');
10
+ const pauseBtn = document.getElementById('pauseBtn');
11
+ const resetBtn = document.getElementById('resetBtn');
12
+ const upBtn = document.getElementById('upBtn');
13
+ const downBtn = document.getElementById('downBtn');
14
+ const leftBtn = document.getElementById('leftBtn');
15
+ const rightBtn = document.getElementById('rightBtn');
16
+
17
+ // Game constants
18
+ const GRID_SIZE = 20;
19
+ const CELL_SIZE = canvas.width / GRID_SIZE;
20
+
21
+ // Game state
22
+ let snake = [];
23
+ let food = {};
24
+ let direction = 'right';
25
+ let nextDirection = 'right';
26
+ let score = 0;
27
+ let highScore = localStorage.getItem('snakeHighScore') || 0;
28
+ let gameLoop = null;
29
+ let gameSpeed = 150;
30
+ let isPaused = false;
31
+ let isGameOver = false;
32
+
33
+ // Initialize game
34
+ function initGame() {
35
+ snake = [
36
+ { x: 10, y: 10 },
37
+ { x: 9, y: 10 },
38
+ { x: 8, y: 10 }
39
+ ];
40
+ direction = 'right';
41
+ nextDirection = 'right';
42
+ score = 0;
43
+ gameSpeed = 150;
44
+ isPaused = false;
45
+ isGameOver = false;
46
+
47
+ updateScore();
48
+ updateSpeed();
49
+ spawnFood();
50
+ draw();
51
+
52
+ messageDisplay.textContent = 'Press SPACE or tap Start to begin';
53
+ messageDisplay.className = 'message';
54
+ startBtn.disabled = false;
55
+ pauseBtn.disabled = true;
56
+ }
57
+
58
+ // Start game
59
+ function startGame() {
60
+ if (gameLoop || isPaused) return;
61
+
62
+ messageDisplay.textContent = '';
63
+ startBtn.disabled = true;
64
+ pauseBtn.disabled = false;
65
+
66
+ gameLoop = setInterval(() => {
67
+ update();
68
+ draw();
69
+ }, gameSpeed);
70
+ }
71
+
72
+ // Pause game
73
+ function pauseGame() {
74
+ if (isGameOver) return;
75
+
76
+ isPaused = !isPaused;
77
+
78
+ if (isPaused) {
79
+ clearInterval(gameLoop);
80
+ gameLoop = null;
81
+ messageDisplay.textContent = 'PAUSED - Press SPACE or Resume';
82
+ messageDisplay.className = 'message show';
83
+ pauseBtn.textContent = 'Resume';
84
+ startBtn.disabled = false;
85
+ } else {
86
+ startGame();
87
+ messageDisplay.textContent = '';
88
+ pauseBtn.textContent = 'Pause';
89
+ startBtn.disabled = true;
90
+ }
91
+ }
92
+
93
+ // Reset game
94
+ function resetGame() {
95
+ clearInterval(gameLoop);
96
+ gameLoop = null;
97
+ initGame();
98
+ }
99
+
100
+ // Update game state
101
+ function update() {
102
+ direction = nextDirection;
103
+
104
+ // Calculate new head position
105
+ const head = { ...snake[0] };
106
+
107
+ switch (direction) {
108
+ case 'up':
109
+ head.y--;
110
+ break;
111
+ case 'down':
112
+ head.y++;
113
+ break;
114
+ case 'left':
115
+ head.x--;
116
+ break;
117
+ case 'right':
118
+ head.x++;
119
+ break;
120
+ }
121
+
122
+ // Check collision with walls
123
+ if (head.x < 0 || head.x >= GRID_SIZE || head.y < 0 || head.y >= GRID_SIZE) {
124
+ gameOver();
125
+ return;
126
+ }
127
+
128
+ // Check collision with self
129
+ if (snake.some(segment => segment.x === head.x && segment.y === head.y)) {
130
+ gameOver();
131
+ return;
132
+ }
133
+
134
+ // Add new head
135
+ snake.unshift(head);
136
+
137
+ // Check if food eaten
138
+ if (head.x === food.x && head.y === food.y) {
139
+ score += 10;
140
+ updateScore();
141
+ spawnFood();
142
+ increaseSpeed();
143
+ } else {
144
+ snake.pop();
145
+ }
146
+ }
147
+
148
+ // Draw everything
149
+ function draw() {
150
+ // Clear canvas
151
+ ctx.fillStyle = '#1f2937';
152
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
153
+
154
+ // Draw grid
155
+ ctx.strokeStyle = '#374151';
156
+ ctx.lineWidth = 1;
157
+ for (let i = 0; i <= GRID_SIZE; i++) {
158
+ ctx.beginPath();
159
+ ctx.moveTo(i * CELL_SIZE, 0);
160
+ ctx.lineTo(i * CELL_SIZE, canvas.height);
161
+ ctx.stroke();
162
+
163
+ ctx.beginPath();
164
+ ctx.moveTo(0, i * CELL_SIZE);
165
+ ctx.lineTo(canvas.width, i * CELL_SIZE);
166
+ ctx.stroke();
167
+ }
168
+
169
+ // Draw snake
170
+ snake.forEach((segment, index) => {
171
+ if (index === 0) {
172
+ // Head
173
+ ctx.fillStyle = '#10b981';
174
+ } else {
175
+ // Body
176
+ ctx.fillStyle = '#34d399';
177
+ }
178
+ ctx.fillRect(
179
+ segment.x * CELL_SIZE + 1,
180
+ segment.y * CELL_SIZE + 1,
181
+ CELL_SIZE - 2,
182
+ CELL_SIZE - 2
183
+ );
184
+ });
185
+
186
+ // Draw food
187
+ ctx.fillStyle = '#ef4444';
188
+ ctx.beginPath();
189
+ ctx.arc(
190
+ food.x * CELL_SIZE + CELL_SIZE / 2,
191
+ food.y * CELL_SIZE + CELL_SIZE / 2,
192
+ CELL_SIZE / 2 - 2,
193
+ 0,
194
+ Math.PI * 2
195
+ );
196
+ ctx.fill();
197
+ }
198
+
199
+ // Spawn food
200
+ function spawnFood() {
201
+ do {
202
+ food = {
203
+ x: Math.floor(Math.random() * GRID_SIZE),
204
+ y: Math.floor(Math.random() * GRID_SIZE)
205
+ };
206
+ } while (snake.some(segment => segment.x === food.x && segment.y === food.y));
207
+ }
208
+
209
+ // Change direction
210
+ function changeDirection(newDirection) {
211
+ // Prevent 180 degree turns
212
+ if (
213
+ (newDirection === 'up' && direction !== 'down') ||
214
+ (newDirection === 'down' && direction !== 'up') ||
215
+ (newDirection === 'left' && direction !== 'right') ||
216
+ (newDirection === 'right' && direction !== 'left')
217
+ ) {
218
+ nextDirection = newDirection;
219
+ }
220
+ }
221
+
222
+ // Increase speed
223
+ function increaseSpeed() {
224
+ if (gameSpeed > 50) {
225
+ gameSpeed -= 5;
226
+ clearInterval(gameLoop);
227
+ if (!isPaused) {
228
+ gameLoop = setInterval(() => {
229
+ update();
230
+ draw();
231
+ }, gameSpeed);
232
+ }
233
+ updateSpeed();
234
+ }
235
+ }
236
+
237
+ // Update score
238
+ function updateScore() {
239
+ scoreDisplay.textContent = score;
240
+
241
+ if (score > highScore) {
242
+ highScore = score;
243
+ localStorage.setItem('snakeHighScore', highScore);
244
+ highScoreDisplay.textContent = highScore;
245
+ } else {
246
+ highScoreDisplay.textContent = highScore;
247
+ }
248
+ }
249
+
250
+ // Update speed display
251
+ function updateSpeed() {
252
+ if (gameSpeed > 100) {
253
+ speedDisplay.textContent = 'Normal';
254
+ } else if (gameSpeed > 60) {
255
+ speedDisplay.textContent = 'Fast';
256
+ } else {
257
+ speedDisplay.textContent = 'Very Fast';
258
+ }
259
+ }
260
+
261
+ // Game over
262
+ function gameOver() {
263
+ clearInterval(gameLoop);
264
+ gameLoop = null;
265
+ isGameOver = true;
266
+
267
+ messageDisplay.textContent = `Game Over! Final Score: ${score}`;
268
+ messageDisplay.className = 'message show game-over';
269
+
270
+ startBtn.disabled = false;
271
+ pauseBtn.disabled = true;
272
+ pauseBtn.textContent = 'Pause';
273
+ }
274
+
275
+ // Keyboard controls
276
+ document.addEventListener('keydown', (e) => {
277
+ switch (e.key) {
278
+ case 'ArrowUp':
279
+ case 'w':
280
+ case 'W':
281
+ e.preventDefault();
282
+ changeDirection('up');
283
+ break;
284
+ case 'ArrowDown':
285
+ case 's':
286
+ case 'S':
287
+ e.preventDefault();
288
+ changeDirection('down');
289
+ break;
290
+ case 'ArrowLeft':
291
+ case 'a':
292
+ case 'A':
293
+ e.preventDefault();
294
+ changeDirection('left');
295
+ break;
296
+ case 'ArrowRight':
297
+ case 'd':
298
+ case 'D':
299
+ e.preventDefault();
300
+ changeDirection('right');
301
+ break;
302
+ case ' ':
303
+ e.preventDefault();
304
+ if (!gameLoop && !isPaused) {
305
+ startGame();
306
+ } else if (!isGameOver) {
307
+ pauseGame();
308
+ }
309
+ break;
310
+ }
311
+ });
312
+
313
+ // Button controls
314
+ upBtn.addEventListener('click', () => changeDirection('up'));
315
+ downBtn.addEventListener('click', () => changeDirection('down'));
316
+ leftBtn.addEventListener('click', () => changeDirection('left'));
317
+ rightBtn.addEventListener('click', () => changeDirection('right'));
318
+
319
+ startBtn.addEventListener('click', () => {
320
+ if (isGameOver) {
321
+ resetGame();
322
+ }
323
+ startGame();
324
+ });
325
+ pauseBtn.addEventListener('click', pauseGame);
326
+ resetBtn.addEventListener('click', resetGame);
327
+
328
+ // Touch swipe controls
329
+ let touchStartX = 0;
330
+ let touchStartY = 0;
331
+
332
+ canvas.addEventListener('touchstart', (e) => {
333
+ touchStartX = e.touches[0].clientX;
334
+ touchStartY = e.touches[0].clientY;
335
+ });
336
+
337
+ canvas.addEventListener('touchend', (e) => {
338
+ const touchEndX = e.changedTouches[0].clientX;
339
+ const touchEndY = e.changedTouches[0].clientY;
340
+
341
+ const deltaX = touchEndX - touchStartX;
342
+ const deltaY = touchEndY - touchStartY;
343
+
344
+ if (Math.abs(deltaX) > Math.abs(deltaY)) {
345
+ if (deltaX > 0) {
346
+ changeDirection('right');
347
+ } else {
348
+ changeDirection('left');
349
+ }
350
+ } else {
351
+ if (deltaY > 0) {
352
+ changeDirection('down');
353
+ } else {
354
+ changeDirection('up');
355
+ }
356
+ }
357
+ });
358
+
359
+ // Initialize on load
360
+ initGame();
@@ -0,0 +1,246 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ body {
8
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
9
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
10
+ min-height: 100vh;
11
+ display: flex;
12
+ justify-content: center;
13
+ align-items: center;
14
+ padding: 20px;
15
+ }
16
+
17
+ .container {
18
+ width: 100%;
19
+ max-width: 500px;
20
+ }
21
+
22
+ .game-card {
23
+ background: white;
24
+ border-radius: 16px;
25
+ padding: 30px;
26
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
27
+ }
28
+
29
+ .game-card h1 {
30
+ text-align: center;
31
+ color: #333;
32
+ margin-bottom: 20px;
33
+ font-size: 2.5rem;
34
+ }
35
+
36
+ .game-info {
37
+ display: flex;
38
+ justify-content: space-between;
39
+ padding: 15px;
40
+ background: #f3f4f6;
41
+ border-radius: 12px;
42
+ margin-bottom: 20px;
43
+ }
44
+
45
+ .info-item {
46
+ display: flex;
47
+ flex-direction: column;
48
+ align-items: center;
49
+ }
50
+
51
+ .label {
52
+ font-size: 0.9rem;
53
+ color: #6b7280;
54
+ margin-bottom: 5px;
55
+ }
56
+
57
+ .value {
58
+ font-size: 1.3rem;
59
+ font-weight: bold;
60
+ color: #333;
61
+ }
62
+
63
+ #gameCanvas {
64
+ width: 100%;
65
+ max-width: 400px;
66
+ height: auto;
67
+ display: block;
68
+ margin: 0 auto 20px;
69
+ border-radius: 8px;
70
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
71
+ }
72
+
73
+ .message {
74
+ text-align: center;
75
+ font-size: 1.1rem;
76
+ font-weight: 600;
77
+ height: 35px;
78
+ display: flex;
79
+ justify-content: center;
80
+ align-items: center;
81
+ margin-bottom: 20px;
82
+ color: #6b7280;
83
+ opacity: 0;
84
+ transition: opacity 0.3s ease;
85
+ }
86
+
87
+ .message.show {
88
+ opacity: 1;
89
+ animation: pulse 1.5s ease-in-out infinite;
90
+ }
91
+
92
+ .message.game-over {
93
+ color: #ef4444;
94
+ font-size: 1.2rem;
95
+ }
96
+
97
+ @keyframes pulse {
98
+ 0%, 100% {
99
+ opacity: 1;
100
+ }
101
+ 50% {
102
+ opacity: 0.6;
103
+ }
104
+ }
105
+
106
+ .controls {
107
+ margin-bottom: 20px;
108
+ }
109
+
110
+ .arrow-buttons {
111
+ display: flex;
112
+ flex-direction: column;
113
+ align-items: center;
114
+ gap: 5px;
115
+ }
116
+
117
+ .arrow-row {
118
+ display: flex;
119
+ gap: 5px;
120
+ }
121
+
122
+ .arrow-btn {
123
+ width: 60px;
124
+ height: 60px;
125
+ border: 2px solid #e5e7eb;
126
+ border-radius: 8px;
127
+ background: white;
128
+ font-size: 1.5rem;
129
+ cursor: pointer;
130
+ transition: all 0.2s ease;
131
+ color: #333;
132
+ }
133
+
134
+ .arrow-btn:hover {
135
+ background: #f3f4f6;
136
+ border-color: #9ca3af;
137
+ transform: scale(1.05);
138
+ }
139
+
140
+ .arrow-btn:active {
141
+ transform: scale(0.95);
142
+ background: #e5e7eb;
143
+ }
144
+
145
+ .button-group {
146
+ display: flex;
147
+ gap: 10px;
148
+ margin-bottom: 20px;
149
+ }
150
+
151
+ .btn {
152
+ flex: 1;
153
+ padding: 12px 20px;
154
+ border: none;
155
+ border-radius: 8px;
156
+ font-size: 1rem;
157
+ font-weight: 600;
158
+ cursor: pointer;
159
+ transition: all 0.3s ease;
160
+ }
161
+
162
+ .btn:disabled {
163
+ opacity: 0.5;
164
+ cursor: not-allowed;
165
+ }
166
+
167
+ .btn-success {
168
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
169
+ color: white;
170
+ }
171
+
172
+ .btn-success:hover:not(:disabled) {
173
+ transform: translateY(-2px);
174
+ box-shadow: 0 5px 15px rgba(16, 185, 129, 0.4);
175
+ }
176
+
177
+ .btn-warning {
178
+ background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
179
+ color: white;
180
+ }
181
+
182
+ .btn-warning:hover:not(:disabled) {
183
+ transform: translateY(-2px);
184
+ box-shadow: 0 5px 15px rgba(245, 158, 11, 0.4);
185
+ }
186
+
187
+ .btn-danger {
188
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
189
+ color: white;
190
+ }
191
+
192
+ .btn-danger:hover:not(:disabled) {
193
+ transform: translateY(-2px);
194
+ box-shadow: 0 5px 15px rgba(239, 68, 68, 0.4);
195
+ }
196
+
197
+ .instructions {
198
+ background: #f9fafb;
199
+ border-radius: 8px;
200
+ padding: 15px;
201
+ font-size: 0.9rem;
202
+ color: #6b7280;
203
+ }
204
+
205
+ .instructions p {
206
+ margin-bottom: 8px;
207
+ }
208
+
209
+ .instructions p:last-child {
210
+ margin-bottom: 0;
211
+ }
212
+
213
+ @media (max-width: 480px) {
214
+ .game-card {
215
+ padding: 20px;
216
+ }
217
+
218
+ .game-card h1 {
219
+ font-size: 2rem;
220
+ }
221
+
222
+ .game-info {
223
+ flex-direction: column;
224
+ gap: 10px;
225
+ }
226
+
227
+ .info-item {
228
+ flex-direction: row;
229
+ justify-content: space-between;
230
+ width: 100%;
231
+ }
232
+
233
+ .arrow-btn {
234
+ width: 50px;
235
+ height: 50px;
236
+ font-size: 1.2rem;
237
+ }
238
+
239
+ .button-group {
240
+ flex-direction: column;
241
+ }
242
+
243
+ .instructions {
244
+ font-size: 0.85rem;
245
+ }
246
+ }