Skip to content

Commit 7e46429

Browse files
committed
grid.tick()とfallableの落下処理を実装
1 parent 6101831 commit 7e46429

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

routes/+page.svelte

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@
1111
<a href="/game?stage=6">Stage 6</a>
1212
<a href="/game?stage=7">Stage 7</a>
1313
<a href="/game?stage=8">Stage 8</a>
14+
15+
<p>
16+
<a href="/game?stage=3-1">Stage 3-1</a>
17+
<a href="/game?stage=3-2">Stage 3-2</a>
18+
</p>

src/ability.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ export function placeMovableObject(
184184
grid.setBlock(cx, positionX, positionY, {
185185
block: object.block,
186186
objectId: object.objectId,
187-
dy: 0,
188187
});
189188
}
190189
}

src/grid.ts

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { type Container, Sprite } from "pixi.js";
1+
import { type Container, Sprite, type Ticker } from "pixi.js";
22
import { type Writable, get } from "svelte/store";
33
import { Block } from "./constants.ts";
4+
import * as consts from "./constants.ts";
45
import { assert } from "./lib.ts";
56
import type {
67
Context,
@@ -21,6 +22,8 @@ import type { StageDefinition } from "./stages.ts";
2122
type VirtualSpriteCell = {
2223
sprite: Sprite | null;
2324
block: Block;
25+
dy?: number; // in pixels
26+
dvy?: number;
2427
};
2528
export type GridCell =
2629
| {
@@ -34,7 +37,6 @@ export type GridCell =
3437
| {
3538
block: Block.fallable;
3639
objectId: string;
37-
dy: number; // in pixels
3840
}
3941
| {
4042
block: Block.air;
@@ -646,7 +648,6 @@ export class Grid {
646648
cells[y][x] = {
647649
block: cell.block,
648650
objectId: cell.objectId,
649-
dy: 0,
650651
};
651652
prev.sprite = movableSprite;
652653
prev.block = cell.block;
@@ -661,6 +662,48 @@ export class Grid {
661662
cells: cells,
662663
}));
663664
}
665+
tick(cx: Context, ticker: Ticker) {
666+
const { blockSize, gridX, gridY, marginY } = get(cx.config);
667+
const cells = get(cx.state).cells;
668+
for (let y = gridY - 1; y >= 0; y--) {
669+
for (let x = 0; x < gridX; x++) {
670+
let cellY = y;
671+
const vsom = this.vsom[cellY][x];
672+
const cell = cells[cellY][x];
673+
if (cell.block === Block.fallable) {
674+
vsom.dy = (vsom.dy ?? 0) + (vsom.dvy ?? 0) * ticker.deltaTime;
675+
vsom.dvy =
676+
(vsom.dvy ?? 0) + consts.gravity * blockSize * ticker.deltaTime;
677+
while (vsom.dy > 0 && cellY <= gridY - 2) {
678+
// 下のブロックと接触判定を行う
679+
const vsomBelow = this.vsom[cellY + 1][x];
680+
const cellBelow = cells[cellY + 1][x];
681+
if (cellBelow.block === Block.air) {
682+
assert(vsomBelow.sprite === null, "air sprite is not null");
683+
// fallableを1ブロック下に動かしdyを1blockSize分上げる
684+
vsom.dy -= blockSize;
685+
this.vsom[cellY + 1][x] = vsom;
686+
this.vsom[cellY][x] = vsomBelow;
687+
cells[cellY + 1][x] = cell;
688+
cells[cellY][x] = cellBelow;
689+
cellY += 1;
690+
cx.state.update((prev) => ({
691+
...prev,
692+
cells: cells,
693+
}));
694+
} else {
695+
// 衝突したので止める
696+
vsom.dy = 0;
697+
vsom.dvy = 0;
698+
break;
699+
}
700+
}
701+
assert(!!vsom.sprite, "falling sprite is null");
702+
vsom.sprite.y = cellY * blockSize + marginY + vsom.dy;
703+
}
704+
}
705+
}
706+
}
664707
}
665708

666709
export function createCellsFromStageDefinition(
@@ -695,7 +738,6 @@ export function createCellsFromStageDefinition(
695738
const cell: GridCell = {
696739
block,
697740
objectId,
698-
dy: 0,
699741
};
700742
row.push(cell);
701743
break;

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ export async function setup(
149149
}),
150150
);
151151

152+
app.ticker.add(unlessPaused((ticker) => grid.tick(cx, ticker)));
153+
152154
// Append the application canvas to the document body
153155
el.appendChild(app.canvas);
154156
const onresize = useOnResize(cx, app, grid, gridX, gridY);

0 commit comments

Comments
 (0)