···
const confetti = confettiPlugin(k);
k.addConfetti = confetti.addConfetti;
19
+
let gameActive = true;
21
-
const ground = k.add([
22
-
k.rect(k.width(), 48),
23
-
k.pos(0, k.height() - 48),
26
-
k.body({ isStatic: true }),
27
-
k.color(127, 200, 255),
22
+
// Define game scenes
23
+
k.scene("main", () => {
30
-
// Create walls around the edge of the map
32
-
const leftWall = k.add([
33
-
k.rect(20, k.height()),
37
-
k.body({ isStatic: true }),
38
-
k.color(127, 200, 255),
43
-
const rightWall = k.add([
44
-
k.rect(20, k.height()),
45
-
k.pos(k.width(), 0),
48
-
k.body({ isStatic: true }),
49
-
k.color(127, 200, 255),
30
+
const ground = k.add([
31
+
k.rect(k.width(), 48),
32
+
k.pos(0, k.height() - 48),
35
+
k.body({ isStatic: true }),
36
+
k.color(127, 200, 255),
54
-
const topWall = k.add([
55
-
k.rect(k.width(), 20),
59
-
k.body({ isStatic: true }),
60
-
k.color(127, 200, 255),
39
+
// Create walls around the edge of the map
41
+
const leftWall = k.add([
42
+
k.rect(20, k.height()),
46
+
k.body({ isStatic: true }),
47
+
k.color(127, 200, 255),
64
-
// Create player object with components
65
-
const playerObj = k.add([
67
-
k.sprite("glady-o"),
71
-
"player", // Add tag for collision detection
52
+
const rightWall = k.add([
53
+
k.rect(20, k.height()),
54
+
k.pos(k.width(), 0),
57
+
k.body({ isStatic: true }),
58
+
k.color(127, 200, 255),
74
-
// Enemy spawning variables
75
-
let enemies: any[] = [];
76
-
let initialMaxEnemies = 5;
77
-
let maxEnemies = initialMaxEnemies;
78
-
let initialSpawnInterval = 3; // seconds
79
-
let spawnInterval = initialSpawnInterval;
80
-
let gameTime = 0; // Track game time in seconds
81
-
let difficultyLevel = 1;
63
+
const topWall = k.add([
64
+
k.rect(k.width(), 20),
68
+
k.body({ isStatic: true }),
69
+
k.color(127, 200, 255),
84
-
const scoreText = k.add([k.text(`Score: ${score}`), k.pos(16, 16)]);
73
+
// Create player object with components
74
+
const playerObj = k.add([
76
+
k.sprite("glady-o"),
80
+
"player", // Add tag for collision detection
83
+
// Enemy spawning variables
84
+
let enemies: any[] = [];
85
+
let initialMaxEnemies = 5;
86
+
let maxEnemies = initialMaxEnemies;
87
+
let initialSpawnInterval = 3; // seconds
88
+
let spawnInterval = initialSpawnInterval;
89
+
let gameTime = 0; // Track game time in seconds
90
+
let difficultyLevel = 1;
93
+
const scoreText = k.add([k.text(`Score: ${score}`), k.pos(16, 16), "score"]);
95
+
// Difficulty scaling
96
+
function updateDifficulty() {
97
+
if (!gameActive) return;
99
+
gameTime += 1; // Increment game time by 1 second
101
+
// Every 30 seconds, increase difficulty
102
+
if (score != 0 && score % (50 + 5 * difficultyLevel) === 0) {
103
+
difficultyLevel += 1;
105
+
// Increase max enemies (cap at 15)
106
+
maxEnemies = Math.min(initialMaxEnemies + difficultyLevel * 3, 15);
108
+
// Decrease spawn interval (minimum 0.5 seconds)
109
+
spawnInterval = Math.max(
110
+
initialSpawnInterval - difficultyLevel * 0.3,
86
-
// Difficulty scaling
87
-
function updateDifficulty() {
88
-
gameTime += 1; // Increment game time by 1 second
115
+
`Difficulty increased to level ${difficultyLevel}. Max enemies: ${maxEnemies}, Spawn interval: ${spawnInterval}s`,
90
-
// Every 30 seconds, increase difficulty
91
-
if (score != 0 && score % (50 + 5 * difficultyLevel) === 0) {
92
-
difficultyLevel += 1;
118
+
// Cancel previous spawn loop and start a new one with updated interval
120
+
k.loop(spawnInterval, spawnEnemy);
122
+
// Visual feedback for difficulty increase
123
+
const screenCenter = k.vec2(k.width() / 2, k.height() / 2);
124
+
if (k.addConfetti) {
125
+
k.addConfetti(screenCenter);
128
+
// Add difficulty level text
129
+
const levelText = k.add([
130
+
k.text(`Difficulty Level ${difficultyLevel}!`, { size: 32 }),
131
+
k.pos(screenCenter),
132
+
k.anchor("center"),
133
+
k.color(255, 255, 255),
134
+
k.outline(2, k.rgb(0, 0, 0)),
139
+
// Fade out and destroy the text
145
+
levelText.opacity = v;
147
+
k.easings.easeInQuad,
151
+
levelText.destroy();
94
-
// Increase max enemies (cap at 15)
95
-
maxEnemies = Math.min(initialMaxEnemies + difficultyLevel * 3, 15);
156
+
// Start difficulty scaling
157
+
k.loop(1, updateDifficulty);
97
-
// Decrease spawn interval (minimum 0.5 seconds)
98
-
spawnInterval = Math.max(initialSpawnInterval - difficultyLevel * 0.3, 0.5);
159
+
// Spawn an enemy at a random position
160
+
function spawnEnemy() {
161
+
if (!gameActive) return;
101
-
`Difficulty increased to level ${difficultyLevel}. Max enemies: ${maxEnemies}, Spawn interval: ${spawnInterval}s`,
163
+
// Don't spawn if we already have max enemies
164
+
if (enemies.length >= maxEnemies) return;
104
-
// Cancel previous spawn loop and start a new one with updated interval
106
-
k.loop(spawnInterval, spawnEnemy);
166
+
// Random position at the edges of the screen
167
+
const side = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
108
-
// Visual feedback for difficulty increase
109
-
const screenCenter = k.vec2(k.width() / 2, k.height() / 2);
110
-
if (k.addConfetti) {
111
-
k.addConfetti(screenCenter);
173
+
x = Math.random() * (k.width() - 40) + 20; // Avoid spawning behind side walls
174
+
y = 10; // Just inside the top wall
177
+
x = k.width() - 10; // Just inside the right wall
178
+
y = Math.random() * (k.height() - 48 - 20) + 20; // Avoid spawning behind top wall or inside ground
181
+
x = Math.random() * (k.width() - 40) + 20; // Avoid spawning behind side walls
182
+
y = k.height() - 58; // Just above the ground (ground is at height-48 with height 48)
185
+
x = 10; // Just inside the left wall
186
+
y = Math.random() * (k.height() - 48 - 20) + 20; // Avoid spawning behind top wall or inside ground
114
-
// Add difficulty level text
115
-
const levelText = k.add([
116
-
k.text(`Difficulty Level ${difficultyLevel}!`, { size: 32 }),
117
-
k.pos(screenCenter),
118
-
k.anchor("center"),
119
-
k.color(255, 255, 255),
120
-
k.outline(2, k.rgb(0, 0, 0)),
190
+
// Create enemy using the makeEnemy function
191
+
const newEnemy = makeEnemy(k, playerObj, x, y);
192
+
enemies.push(newEnemy);
194
+
// Remove from array when destroyed
195
+
newEnemy.on("destroy", () => {
196
+
enemies = enemies.filter((e) => e !== newEnemy);
125
-
// Fade out and destroy the text
131
-
levelText.opacity = v;
133
-
k.easings.easeInQuad,
198
+
// Increase score when enemy is destroyed
199
+
score += Math.round(10 + Math.pow(difficultyLevel, 0.75));
137
-
levelText.destroy();
201
+
// Update score display
202
+
scoreText.text = `Score: ${score}`;
204
+
if (Math.random() < 0.5) spawnEnemy();
142
-
// Start difficulty scaling
143
-
k.loop(1, updateDifficulty);
208
+
// Start spawning enemies
209
+
k.loop(spawnInterval, spawnEnemy);
145
-
// Spawn an enemy at a random position
146
-
function spawnEnemy() {
147
-
// Don't spawn if we already have max enemies
148
-
if (enemies.length >= maxEnemies) return;
213
+
// Update enemy list (remove destroyed enemies)
214
+
enemies = enemies.filter((enemy) => enemy.exists());
217
+
// Listen for game over event
218
+
playerObj.on("death", () => {
219
+
gameActive = false;
220
+
finalScore = score;
222
+
// Stop enemy spawning
223
+
k.cancel("spawnEnemy");
150
-
// Random position at the edges of the screen
151
-
const side = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
225
+
// Wait a moment before showing game over screen
227
+
k.go("gameOver", finalScore);
157
-
x = Math.random() * (k.width() - 40) + 20; // Avoid spawning behind side walls
158
-
y = 10; // Just inside the top wall
161
-
x = k.width() - 10; // Just inside the right wall
162
-
y = Math.random() * (k.height() - 48 - 20) + 20; // Avoid spawning behind top wall or inside ground
165
-
x = Math.random() * (k.width() - 40) + 20; // Avoid spawning behind side walls
166
-
y = k.height() - 58; // Just above the ground (ground is at height-48 with height 48)
169
-
x = 10; // Just inside the left wall
170
-
y = Math.random() * (k.height() - 48 - 20) + 20; // Avoid spawning behind top wall or inside ground
233
+
k.scene("gameOver", (score: number) => {
235
+
k.add([k.rect(k.width(), k.height()), k.color(0, 0, 0), k.opacity(0.7)]);
174
-
// Create enemy using the makeEnemy function
175
-
const newEnemy = makeEnemy(k, playerObj, x, y);
176
-
enemies.push(newEnemy);
239
+
k.text("GAME OVER", { size: 64 }),
240
+
k.pos(k.width() / 2, k.height() / 3),
241
+
k.anchor("center"),
242
+
k.color(255, 50, 50),
178
-
// Remove from array when destroyed
179
-
newEnemy.on("destroy", () => {
180
-
enemies = enemies.filter((e) => e !== newEnemy);
247
+
k.text(`Final Score: ${score}`, { size: 36 }),
248
+
k.pos(k.width() / 2, k.height() / 2),
249
+
k.anchor("center"),
250
+
k.color(255, 255, 255),
182
-
// Increase score when enemy is destroyed
183
-
score += Math.round(10 + Math.pow(difficultyLevel, 0.75));
254
+
const restartBtn = k.add([
256
+
k.pos(k.width() / 2, (k.height() * 2) / 3),
257
+
k.anchor("center"),
258
+
k.color(50, 150, 50),
185
-
// Update score display
186
-
scoreText.text = `Score: ${score}`;
265
+
k.text("RESTART", { size: 24 }),
266
+
k.pos(k.width() / 2, (k.height() * 2) / 3),
267
+
k.anchor("center"),
268
+
k.color(255, 255, 255),
188
-
if (Math.random() < 0.5) spawnEnemy();
271
+
// Restart on button click
272
+
restartBtn.onClick(() => {
192
-
// Start spawning enemies
193
-
k.loop(spawnInterval, spawnEnemy);
276
+
// Restart on key press
277
+
k.onKeyPress("r", () => {
197
-
// Update enemy list (remove destroyed enemies)
198
-
enemies = enemies.filter((enemy) => enemy.exists());
281
+
// Restart on enter key
282
+
k.onKeyPress("enter", () => {
201
-
console.log(typeof k);