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