tangled
alpha
login
or
join now
flo-bit.dev
/
blento
your personal website on atproto - mirror
blento.app
20
fork
atom
overview
issues
pulls
pipelines
improve dino game card
Florian
3 weeks ago
0faab9c0
c6a7b011
+39
-13
1 changed file
expand all
collapse all
unified
split
src
lib
cards
GameCards
DinoGameCard
DinoGameCard.svelte
+39
-13
src/lib/cards/GameCards/DinoGameCard/DinoGameCard.svelte
···
58
59
let gameSpeed = 5;
60
let frameCount = 0;
0
0
0
0
0
0
0
61
62
// Sprite positions in tilemap (row, column - 1-indexed based on cells.txt)
63
const SPRITE_POSITIONS: Record<string, { row: number; col: number }> = {
···
151
frame: 0
152
};
153
obstacles = [];
154
-
gameSpeed = 3.5 * (scale / 2.5);
155
score = 0;
156
frameCount = 0;
0
0
0
0
157
initGroundTiles();
158
}
159
···
293
ctx.drawImage(sprites[spriteKey], x, y, width, height);
294
}
295
296
-
function gameLoop() {
297
if (!ctx || !canvas || !spritesLoaded) {
298
animationId = requestAnimationFrame(gameLoop);
299
return;
300
}
301
0
0
0
0
0
0
0
0
302
const canvasWidth = canvas.width;
303
const canvasHeight = canvas.height;
304
const groundY = canvasHeight - groundHeight;
···
312
}
313
314
if (gameState === 'playing') {
315
-
frameCount++;
316
317
// Update ground tiles - seamless scrolling
318
for (const tile of groundTiles) {
319
-
tile.x -= gameSpeed;
320
}
321
322
// Find the rightmost tile and reposition tiles that went off-screen
···
329
330
// Update player physics
331
if (player.isJumping) {
332
-
player.velocityY += gravity;
333
-
player.y += player.velocityY;
334
335
if (player.y >= groundY - player.height) {
336
player.y = groundY - player.height;
···
342
}
343
344
// Animate player (3 walk frames)
345
-
if (frameCount % 8 === 0) {
346
player.frame = (player.frame + 1) % 3;
0
347
}
348
349
// Animate flying obstacles
350
for (const obs of obstacles) {
351
-
if (obs.type === 'air' && frameCount % 12 === 0) {
352
obs.frame = obs.frame === 1 ? 2 : 1;
353
obs.sprite = `bat${obs.frame}`;
0
354
}
355
}
356
357
// Spawn obstacles
358
const baseSpawnRate = 120;
359
const spawnRate = Math.max(60, baseSpawnRate - Math.floor(score / 100) * 5);
360
-
if (frameCount % spawnRate === 0 || (obstacles.length === 0 && frameCount > 60)) {
0
0
0
361
spawnObstacle(canvasWidth, groundY);
0
362
}
363
364
// Update obstacles
365
obstacles = obstacles.filter((obs) => {
366
-
obs.x -= gameSpeed;
367
return obs.x > -obs.width;
368
});
369
···
407
// Update score
408
score = Math.floor(frameCount / 5);
409
410
-
// Increase speed over time (slower progression)
411
-
if (frameCount % 700 === 0) {
412
-
gameSpeed = Math.min(gameSpeed + 0.2 * (scale / 2.5), 8 * (scale / 2.5));
0
413
}
414
}
415
···
58
59
let gameSpeed = 5;
60
let frameCount = 0;
61
+
let lastFrameTimestamp = 0;
62
+
let lastSpawnFrame = 0;
63
+
let lastWalkFrame = 0;
64
+
let lastBatFrame = 0;
65
+
let lastSpeedScore = 0;
66
+
const FRAME_TIME_MS = 1000 / 60;
67
+
const MAX_SPEED_BASE = 10.5;
68
69
// Sprite positions in tilemap (row, column - 1-indexed based on cells.txt)
70
const SPRITE_POSITIONS: Record<string, { row: number; col: number }> = {
···
158
frame: 0
159
};
160
obstacles = [];
161
+
gameSpeed = 4.2 * (scale / 2.5);
162
score = 0;
163
frameCount = 0;
164
+
lastSpawnFrame = 0;
165
+
lastWalkFrame = 0;
166
+
lastBatFrame = 0;
167
+
lastSpeedScore = 0;
168
initGroundTiles();
169
}
170
···
304
ctx.drawImage(sprites[spriteKey], x, y, width, height);
305
}
306
307
+
function gameLoop(timestamp = 0) {
308
if (!ctx || !canvas || !spritesLoaded) {
309
animationId = requestAnimationFrame(gameLoop);
310
return;
311
}
312
313
+
if (!lastFrameTimestamp) {
314
+
lastFrameTimestamp = timestamp;
315
+
}
316
+
317
+
const deltaMs = timestamp - lastFrameTimestamp;
318
+
lastFrameTimestamp = timestamp;
319
+
const deltaFrames = Math.min(deltaMs / FRAME_TIME_MS, 3);
320
+
321
const canvasWidth = canvas.width;
322
const canvasHeight = canvas.height;
323
const groundY = canvasHeight - groundHeight;
···
331
}
332
333
if (gameState === 'playing') {
334
+
frameCount += deltaFrames;
335
336
// Update ground tiles - seamless scrolling
337
for (const tile of groundTiles) {
338
+
tile.x -= gameSpeed * deltaFrames;
339
}
340
341
// Find the rightmost tile and reposition tiles that went off-screen
···
348
349
// Update player physics
350
if (player.isJumping) {
351
+
player.velocityY += gravity * deltaFrames;
352
+
player.y += player.velocityY * deltaFrames;
353
354
if (player.y >= groundY - player.height) {
355
player.y = groundY - player.height;
···
361
}
362
363
// Animate player (3 walk frames)
364
+
if (frameCount - lastWalkFrame >= 8) {
365
player.frame = (player.frame + 1) % 3;
366
+
lastWalkFrame = frameCount;
367
}
368
369
// Animate flying obstacles
370
for (const obs of obstacles) {
371
+
if (obs.type === 'air' && frameCount - lastBatFrame >= 12) {
372
obs.frame = obs.frame === 1 ? 2 : 1;
373
obs.sprite = `bat${obs.frame}`;
374
+
lastBatFrame = frameCount;
375
}
376
}
377
378
// Spawn obstacles
379
const baseSpawnRate = 120;
380
const spawnRate = Math.max(60, baseSpawnRate - Math.floor(score / 100) * 5);
381
+
if (
382
+
frameCount - lastSpawnFrame >= spawnRate ||
383
+
(obstacles.length === 0 && frameCount > 60)
384
+
) {
385
spawnObstacle(canvasWidth, groundY);
386
+
lastSpawnFrame = frameCount;
387
}
388
389
// Update obstacles
390
obstacles = obstacles.filter((obs) => {
391
+
obs.x -= gameSpeed * deltaFrames;
392
return obs.x > -obs.width;
393
});
394
···
432
// Update score
433
score = Math.floor(frameCount / 5);
434
435
+
// Increase speed every 100 points up to a cap
436
+
if (score >= lastSpeedScore + 100) {
437
+
gameSpeed = Math.min(gameSpeed + 0.25 * (scale / 2.5), MAX_SPEED_BASE * (scale / 2.5));
438
+
lastSpeedScore = score - (score % 100);
439
}
440
}
441