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.
- package/CHANGELOG.md +80 -0
- package/README.md +179 -2
- package/bin/cli.js +20 -2
- 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/guess-number/index.html +71 -0
- package/templates/guess-number/script.js +216 -0
- package/templates/guess-number/style.css +337 -0
- package/templates/memory-game/index.html +50 -0
- package/templates/memory-game/script.js +216 -0
- package/templates/memory-game/style.css +288 -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/snake-game/index.html +61 -0
- package/templates/snake-game/script.js +360 -0
- package/templates/snake-game/style.css +246 -0
- package/templates/tetris/index.html +84 -0
- package/templates/tetris/script.js +447 -0
- package/templates/tetris/style.css +286 -0
- package/templates/tic-tac-toe/index.html +57 -0
- package/templates/tic-tac-toe/script.js +156 -0
- package/templates/tic-tac-toe/style.css +244 -0
- package/templates/whack-a-mole/index.html +85 -0
- package/templates/whack-a-mole/script.js +172 -0
- package/templates/whack-a-mole/style.css +263 -0
- package/COMPONENTS-GALLERY.html +0 -773
- package/PUBLISH-GUIDE.md +0 -112
- package/create-template-html-css-1.8.0.tgz +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
// Memory Game Logic
|
|
2
|
+
|
|
3
|
+
const memoryBoard = document.getElementById('memoryBoard');
|
|
4
|
+
const movesDisplay = document.getElementById('moves');
|
|
5
|
+
const timerDisplay = document.getElementById('timer');
|
|
6
|
+
const matchesDisplay = document.getElementById('matches');
|
|
7
|
+
const messageDisplay = document.getElementById('message');
|
|
8
|
+
const resetBtn = document.getElementById('resetBtn');
|
|
9
|
+
const difficultyBtn = document.getElementById('difficultyBtn');
|
|
10
|
+
const difficultySelector = document.getElementById('difficultySelector');
|
|
11
|
+
const difficultyBtns = document.querySelectorAll('.difficulty-btn');
|
|
12
|
+
|
|
13
|
+
// Game symbols
|
|
14
|
+
const symbols = ['đŽ', 'đ¯', 'đ¨', 'đ', 'đĒ', 'đŦ', 'đ¸', 'đē', 'âŊ', 'đ', 'đž', 'đ'];
|
|
15
|
+
|
|
16
|
+
let difficulty = 'easy';
|
|
17
|
+
let cards = [];
|
|
18
|
+
let flippedCards = [];
|
|
19
|
+
let matchedPairs = 0;
|
|
20
|
+
let moves = 0;
|
|
21
|
+
let timer = 0;
|
|
22
|
+
let timerInterval = null;
|
|
23
|
+
let canFlip = true;
|
|
24
|
+
|
|
25
|
+
// Difficulty settings
|
|
26
|
+
const difficultySettings = {
|
|
27
|
+
easy: { pairs: 8, gridCols: 4 },
|
|
28
|
+
medium: { pairs: 10, gridCols: 5 },
|
|
29
|
+
hard: { pairs: 12, gridCols: 6 }
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Initialize game
|
|
33
|
+
function initGame() {
|
|
34
|
+
clearInterval(timerInterval);
|
|
35
|
+
const settings = difficultySettings[difficulty];
|
|
36
|
+
const pairsCount = settings.pairs;
|
|
37
|
+
|
|
38
|
+
// Reset stats
|
|
39
|
+
moves = 0;
|
|
40
|
+
matchedPairs = 0;
|
|
41
|
+
timer = 0;
|
|
42
|
+
flippedCards = [];
|
|
43
|
+
canFlip = true;
|
|
44
|
+
|
|
45
|
+
updateStats();
|
|
46
|
+
messageDisplay.textContent = '';
|
|
47
|
+
messageDisplay.className = 'message';
|
|
48
|
+
|
|
49
|
+
// Create card deck
|
|
50
|
+
const selectedSymbols = symbols.slice(0, pairsCount);
|
|
51
|
+
const cardSymbols = [...selectedSymbols, ...selectedSymbols];
|
|
52
|
+
shuffleArray(cardSymbols);
|
|
53
|
+
|
|
54
|
+
// Create board
|
|
55
|
+
memoryBoard.innerHTML = '';
|
|
56
|
+
memoryBoard.style.gridTemplateColumns = `repeat(${settings.gridCols}, 1fr)`;
|
|
57
|
+
|
|
58
|
+
cards = cardSymbols.map((symbol, index) => {
|
|
59
|
+
const card = document.createElement('div');
|
|
60
|
+
card.className = 'memory-card';
|
|
61
|
+
card.dataset.symbol = symbol;
|
|
62
|
+
card.dataset.index = index;
|
|
63
|
+
|
|
64
|
+
card.innerHTML = `
|
|
65
|
+
<div class="card-inner">
|
|
66
|
+
<div class="card-front">?</div>
|
|
67
|
+
<div class="card-back">${symbol}</div>
|
|
68
|
+
</div>
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
card.addEventListener('click', () => handleCardClick(card));
|
|
72
|
+
memoryBoard.appendChild(card);
|
|
73
|
+
|
|
74
|
+
return card;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Start timer on first click
|
|
78
|
+
let firstClick = true;
|
|
79
|
+
cards.forEach(card => {
|
|
80
|
+
card.addEventListener('click', () => {
|
|
81
|
+
if (firstClick) {
|
|
82
|
+
startTimer();
|
|
83
|
+
firstClick = false;
|
|
84
|
+
}
|
|
85
|
+
}, { once: true });
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Handle card click
|
|
90
|
+
function handleCardClick(card) {
|
|
91
|
+
if (!canFlip || card.classList.contains('flipped') || card.classList.contains('matched')) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Flip card
|
|
96
|
+
card.classList.add('flipped');
|
|
97
|
+
flippedCards.push(card);
|
|
98
|
+
|
|
99
|
+
// Check if two cards are flipped
|
|
100
|
+
if (flippedCards.length === 2) {
|
|
101
|
+
canFlip = false;
|
|
102
|
+
moves++;
|
|
103
|
+
updateStats();
|
|
104
|
+
|
|
105
|
+
setTimeout(() => checkMatch(), 800);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Check if cards match
|
|
110
|
+
function checkMatch() {
|
|
111
|
+
const [card1, card2] = flippedCards;
|
|
112
|
+
const symbol1 = card1.dataset.symbol;
|
|
113
|
+
const symbol2 = card2.dataset.symbol;
|
|
114
|
+
|
|
115
|
+
if (symbol1 === symbol2) {
|
|
116
|
+
// Match found
|
|
117
|
+
card1.classList.add('matched');
|
|
118
|
+
card2.classList.add('matched');
|
|
119
|
+
matchedPairs++;
|
|
120
|
+
updateStats();
|
|
121
|
+
|
|
122
|
+
// Check if game is won
|
|
123
|
+
if (matchedPairs === difficultySettings[difficulty].pairs) {
|
|
124
|
+
handleWin();
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
// No match - flip back
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
card1.classList.remove('flipped');
|
|
130
|
+
card2.classList.remove('flipped');
|
|
131
|
+
}, 400);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
flippedCards = [];
|
|
135
|
+
canFlip = true;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Handle win
|
|
139
|
+
function handleWin() {
|
|
140
|
+
clearInterval(timerInterval);
|
|
141
|
+
messageDisplay.textContent = `đ You Won! Time: ${formatTime(timer)}, Moves: ${moves}`;
|
|
142
|
+
messageDisplay.className = 'message show win';
|
|
143
|
+
|
|
144
|
+
// Celebration animation
|
|
145
|
+
cards.forEach((card, index) => {
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
card.style.animation = 'bounce 0.5s ease';
|
|
148
|
+
}, index * 50);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Start timer
|
|
153
|
+
function startTimer() {
|
|
154
|
+
timerInterval = setInterval(() => {
|
|
155
|
+
timer++;
|
|
156
|
+
updateStats();
|
|
157
|
+
}, 1000);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Update stats display
|
|
161
|
+
function updateStats() {
|
|
162
|
+
movesDisplay.textContent = moves;
|
|
163
|
+
timerDisplay.textContent = formatTime(timer);
|
|
164
|
+
matchesDisplay.textContent = `${matchedPairs}/${difficultySettings[difficulty].pairs}`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Format time
|
|
168
|
+
function formatTime(seconds) {
|
|
169
|
+
const mins = Math.floor(seconds / 60);
|
|
170
|
+
const secs = seconds % 60;
|
|
171
|
+
return `${mins}:${secs.toString().padStart(2, '0')}`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Shuffle array
|
|
175
|
+
function shuffleArray(array) {
|
|
176
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
177
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
178
|
+
[array[i], array[j]] = [array[j], array[i]];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Toggle difficulty selector
|
|
183
|
+
function toggleDifficultySelector() {
|
|
184
|
+
difficultySelector.classList.toggle('show');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Change difficulty
|
|
188
|
+
function changeDifficulty(newDifficulty) {
|
|
189
|
+
difficulty = newDifficulty;
|
|
190
|
+
|
|
191
|
+
// Update active button
|
|
192
|
+
difficultyBtns.forEach(btn => {
|
|
193
|
+
btn.classList.toggle('active', btn.dataset.difficulty === difficulty);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
difficultySelector.classList.remove('show');
|
|
197
|
+
initGame();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Event listeners
|
|
201
|
+
resetBtn.addEventListener('click', initGame);
|
|
202
|
+
difficultyBtn.addEventListener('click', toggleDifficultySelector);
|
|
203
|
+
|
|
204
|
+
difficultyBtns.forEach(btn => {
|
|
205
|
+
btn.addEventListener('click', () => changeDifficulty(btn.dataset.difficulty));
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// Close difficulty selector when clicking outside
|
|
209
|
+
document.addEventListener('click', (e) => {
|
|
210
|
+
if (!e.target.closest('.difficulty-selector') && !e.target.closest('#difficultyBtn')) {
|
|
211
|
+
difficultySelector.classList.remove('show');
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Initialize on load
|
|
216
|
+
initGame();
|
|
@@ -0,0 +1,288 @@
|
|
|
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, #f093fb 0%, #f5576c 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: 700px;
|
|
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
|
+
position: relative;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.game-card h1 {
|
|
31
|
+
text-align: center;
|
|
32
|
+
color: #333;
|
|
33
|
+
margin-bottom: 20px;
|
|
34
|
+
font-size: 2.5rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.game-stats {
|
|
38
|
+
display: flex;
|
|
39
|
+
justify-content: space-around;
|
|
40
|
+
padding: 15px;
|
|
41
|
+
background: #f3f4f6;
|
|
42
|
+
border-radius: 12px;
|
|
43
|
+
margin-bottom: 20px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.stat {
|
|
47
|
+
text-align: center;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.stat-label {
|
|
51
|
+
display: block;
|
|
52
|
+
font-size: 0.9rem;
|
|
53
|
+
color: #6b7280;
|
|
54
|
+
margin-bottom: 5px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.stat-value {
|
|
58
|
+
display: block;
|
|
59
|
+
font-size: 1.5rem;
|
|
60
|
+
font-weight: bold;
|
|
61
|
+
color: #333;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.memory-board {
|
|
65
|
+
display: grid;
|
|
66
|
+
gap: 10px;
|
|
67
|
+
margin: 20px 0;
|
|
68
|
+
padding: 10px;
|
|
69
|
+
background: #f9fafb;
|
|
70
|
+
border-radius: 12px;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.memory-card {
|
|
74
|
+
aspect-ratio: 1;
|
|
75
|
+
cursor: pointer;
|
|
76
|
+
perspective: 1000px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.card-inner {
|
|
80
|
+
position: relative;
|
|
81
|
+
width: 100%;
|
|
82
|
+
height: 100%;
|
|
83
|
+
transition: transform 0.6s;
|
|
84
|
+
transform-style: preserve-3d;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.memory-card.flipped .card-inner {
|
|
88
|
+
transform: rotateY(180deg);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.card-front,
|
|
92
|
+
.card-back {
|
|
93
|
+
position: absolute;
|
|
94
|
+
width: 100%;
|
|
95
|
+
height: 100%;
|
|
96
|
+
backface-visibility: hidden;
|
|
97
|
+
display: flex;
|
|
98
|
+
justify-content: center;
|
|
99
|
+
align-items: center;
|
|
100
|
+
border-radius: 12px;
|
|
101
|
+
font-size: 2.5rem;
|
|
102
|
+
font-weight: bold;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.card-front {
|
|
106
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
107
|
+
color: white;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.card-back {
|
|
111
|
+
background: white;
|
|
112
|
+
border: 3px solid #e5e7eb;
|
|
113
|
+
transform: rotateY(180deg);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.memory-card:not(.flipped):not(.matched):hover .card-inner {
|
|
117
|
+
transform: scale(1.05);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.memory-card.matched .card-back {
|
|
121
|
+
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
|
122
|
+
border-color: #10b981;
|
|
123
|
+
animation: matchPulse 0.5s ease;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@keyframes matchPulse {
|
|
127
|
+
0%, 100% {
|
|
128
|
+
transform: rotateY(180deg) scale(1);
|
|
129
|
+
}
|
|
130
|
+
50% {
|
|
131
|
+
transform: rotateY(180deg) scale(1.1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@keyframes bounce {
|
|
136
|
+
0%, 100% {
|
|
137
|
+
transform: translateY(0);
|
|
138
|
+
}
|
|
139
|
+
50% {
|
|
140
|
+
transform: translateY(-10px);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.message {
|
|
145
|
+
text-align: center;
|
|
146
|
+
font-size: 1.2rem;
|
|
147
|
+
font-weight: bold;
|
|
148
|
+
height: 40px;
|
|
149
|
+
display: flex;
|
|
150
|
+
justify-content: center;
|
|
151
|
+
align-items: center;
|
|
152
|
+
margin-bottom: 20px;
|
|
153
|
+
opacity: 0;
|
|
154
|
+
transition: opacity 0.3s ease;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.message.show {
|
|
158
|
+
opacity: 1;
|
|
159
|
+
animation: slideDown 0.4s ease;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.message.win {
|
|
163
|
+
color: #10b981;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@keyframes slideDown {
|
|
167
|
+
from {
|
|
168
|
+
transform: translateY(-20px);
|
|
169
|
+
opacity: 0;
|
|
170
|
+
}
|
|
171
|
+
to {
|
|
172
|
+
transform: translateY(0);
|
|
173
|
+
opacity: 1;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.button-group {
|
|
178
|
+
display: flex;
|
|
179
|
+
gap: 10px;
|
|
180
|
+
justify-content: center;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.btn {
|
|
184
|
+
flex: 1;
|
|
185
|
+
padding: 12px 24px;
|
|
186
|
+
border: none;
|
|
187
|
+
border-radius: 8px;
|
|
188
|
+
font-size: 1rem;
|
|
189
|
+
font-weight: 600;
|
|
190
|
+
cursor: pointer;
|
|
191
|
+
transition: all 0.3s ease;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.btn-primary {
|
|
195
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
196
|
+
color: white;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.btn-primary:hover {
|
|
200
|
+
transform: translateY(-2px);
|
|
201
|
+
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.btn-secondary {
|
|
205
|
+
background: #6b7280;
|
|
206
|
+
color: white;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.btn-secondary:hover {
|
|
210
|
+
background: #4b5563;
|
|
211
|
+
transform: translateY(-2px);
|
|
212
|
+
box-shadow: 0 5px 15px rgba(107, 114, 128, 0.4);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.difficulty-selector {
|
|
216
|
+
position: absolute;
|
|
217
|
+
top: 100%;
|
|
218
|
+
left: 50%;
|
|
219
|
+
transform: translateX(-50%);
|
|
220
|
+
background: white;
|
|
221
|
+
border-radius: 12px;
|
|
222
|
+
padding: 20px;
|
|
223
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
|
224
|
+
margin-top: 10px;
|
|
225
|
+
z-index: 10;
|
|
226
|
+
opacity: 0;
|
|
227
|
+
pointer-events: none;
|
|
228
|
+
transition: all 0.3s ease;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.difficulty-selector.show {
|
|
232
|
+
opacity: 1;
|
|
233
|
+
pointer-events: all;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.difficulty-selector h3 {
|
|
237
|
+
margin-bottom: 15px;
|
|
238
|
+
color: #333;
|
|
239
|
+
text-align: center;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.difficulty-options {
|
|
243
|
+
display: flex;
|
|
244
|
+
flex-direction: column;
|
|
245
|
+
gap: 10px;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.difficulty-btn {
|
|
249
|
+
padding: 12px 20px;
|
|
250
|
+
border: 2px solid #e5e7eb;
|
|
251
|
+
border-radius: 8px;
|
|
252
|
+
background: white;
|
|
253
|
+
font-size: 1rem;
|
|
254
|
+
font-weight: 600;
|
|
255
|
+
cursor: pointer;
|
|
256
|
+
transition: all 0.3s ease;
|
|
257
|
+
color: #333;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.difficulty-btn:hover {
|
|
261
|
+
border-color: #667eea;
|
|
262
|
+
background: #f3f4f6;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.difficulty-btn.active {
|
|
266
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
267
|
+
color: white;
|
|
268
|
+
border-color: #667eea;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
@media (max-width: 600px) {
|
|
272
|
+
.game-card {
|
|
273
|
+
padding: 20px;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.game-card h1 {
|
|
277
|
+
font-size: 2rem;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.card-front,
|
|
281
|
+
.card-back {
|
|
282
|
+
font-size: 1.5rem;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.button-group {
|
|
286
|
+
flex-direction: column;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
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>Pong</title>
|
|
7
|
+
<link rel="stylesheet" href="style.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div class="container">
|
|
11
|
+
<div class="header">
|
|
12
|
+
<h1>đšī¸ Pong</h1>
|
|
13
|
+
<p class="subtitle">The classic game!</p>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="game-mode">
|
|
17
|
+
<button class="mode-btn active" data-mode="pvc">đ¤ vs Computer</button>
|
|
18
|
+
<button class="mode-btn" data-mode="pvp">đĨ Two Players</button>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div class="difficulty-selector">
|
|
22
|
+
<label>Difficulty:</label>
|
|
23
|
+
<select id="difficulty">
|
|
24
|
+
<option value="easy">Easy</option>
|
|
25
|
+
<option value="medium" selected>Medium</option>
|
|
26
|
+
<option value="hard">Hard</option>
|
|
27
|
+
<option value="impossible">Impossible</option>
|
|
28
|
+
</select>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div class="score-board">
|
|
32
|
+
<div class="player-score">
|
|
33
|
+
<h3>đ¤ Player 1</h3>
|
|
34
|
+
<div id="player1Score" class="score">0</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="divider">:</div>
|
|
37
|
+
<div class="player-score">
|
|
38
|
+
<h3 id="player2Name">đ¤ Computer</h3>
|
|
39
|
+
<div id="player2Score" class="score">0</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<canvas id="gameCanvas"></canvas>
|
|
44
|
+
|
|
45
|
+
<div class="controls">
|
|
46
|
+
<button id="startBtn" class="btn btn-primary">Start Game</button>
|
|
47
|
+
<button id="pauseBtn" class="btn btn-secondary" disabled>Pause</button>
|
|
48
|
+
<button id="resetBtn" class="btn btn-danger">Reset</button>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div id="resultMessage" class="result-message"></div>
|
|
52
|
+
|
|
53
|
+
<div class="instructions">
|
|
54
|
+
<h3>đŽ Game Instructions:</h3>
|
|
55
|
+
<div class="controls-grid">
|
|
56
|
+
<div class="control-item">
|
|
57
|
+
<strong>Player 1:</strong>
|
|
58
|
+
<div class="keys">
|
|
59
|
+
<span class="key">W</span>
|
|
60
|
+
<span>Up</span>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="keys">
|
|
63
|
+
<span class="key">S</span>
|
|
64
|
+
<span>Down</span>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="control-item">
|
|
68
|
+
<strong>Player 2:</strong>
|
|
69
|
+
<div class="keys">
|
|
70
|
+
<span class="key">â</span>
|
|
71
|
+
<span>Up</span>
|
|
72
|
+
</div>
|
|
73
|
+
<div class="keys">
|
|
74
|
+
<span class="key">â</span>
|
|
75
|
+
<span>Down</span>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<ul class="rules">
|
|
80
|
+
<li>Goal: Return the ball and score</li>
|
|
81
|
+
<li>Each goal scored = +1 point</li>
|
|
82
|
+
<li>First to 10 points wins!</li>
|
|
83
|
+
<li>Speed increases as the ball is returned</li>
|
|
84
|
+
</ul>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<script src="script.js"></script>
|
|
89
|
+
</body>
|
|
90
|
+
</html>
|