Skip to content

Commit dfa0163

Browse files
committed
fix block shaking hard while falling, and some refactor
1 parent 2dd9990 commit dfa0163

File tree

3 files changed

+52
-84
lines changed

3 files changed

+52
-84
lines changed

src/constants.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,14 @@ export enum Inputs {
2828
Up = 2,
2929
Ctrl = 3,
3030
}
31+
32+
export const BlockDefinitionMap = new Map<string, Block | null>([
33+
[".", null],
34+
["b", Block.block],
35+
["m", Block.movable],
36+
["f", Block.fallable],
37+
["s", Block.switch],
38+
["S", Block.switchBase],
39+
["w", Block.switchingBlockOFF],
40+
["g", Block.goal],
41+
]);

src/grid.ts

Lines changed: 38 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { type Container, Sprite, type Ticker } from "pixi.js";
22
import { type Writable, get } from "svelte/store";
3-
import { Block } from "./constants.ts";
3+
import { Block, BlockDefinitionMap } from "./constants.ts";
44
import * as consts from "./constants.ts";
55
import { assert, warnIf } from "./lib.ts";
66
import type { Context, GameConfig, GameState, MovableObject } from "./public-types.ts";
@@ -41,7 +41,7 @@ export type GridCell =
4141
switchId: string | undefined; // switchの上に置かれている場合
4242
}
4343
| {
44-
block: null;
44+
block: null; // air
4545
objectId?: unknown;
4646
}
4747
| {
@@ -558,7 +558,7 @@ export class Grid {
558558
const vcell = this.__vsom[y][x];
559559
const ccell = cells[y][x];
560560
if (ccell.block !== Block.fallable) continue;
561-
assert(vcell !== null && vcell.block === ccell.block, "[Grid.tick] vcell is out of sync with ccell");
561+
assert(vcell?.block === ccell.block, "[Grid.tick] vcell is out of sync with ccell");
562562

563563
vcell.dy = (vcell.dy ?? 0) + (vcell.vy ?? 0) * ticker.deltaTime;
564564
vcell.vy = (vcell.vy ?? 0) + consts.gravity * blockSize * ticker.deltaTime;
@@ -567,34 +567,36 @@ export class Grid {
567567
vcell.vy = maxSpeed;
568568
}
569569

570-
let swapTargetY = y;
571-
// 下にブロックがあるなどの要因で止まる
572-
if (!isAvail(cells, x, swapTargetY + 1)) {
570+
let swapDiff = 0;
571+
while (swapDiff * blockSize <= vcell.dy) {
572+
// 下にブロックがあるなどの要因で止まる
573+
if (!isAvail(cells, x, y + swapDiff + 1)) break;
574+
vcell.dy -= blockSize;
575+
swapDiff++;
576+
}
577+
// これ以上下に行けない
578+
if (!isAvail(cells, x, y + swapDiff)) {
579+
// 着地 (dy はたいてい 0 未満なので、別で判定が必要)
573580
if (vcell.dy >= 0) {
574-
// 着地 (dy はたいてい 0 未満なので、別で判定が必要)
575581
vcell.dy = 0;
576582
vcell.vy = 0;
577583
}
578-
} else {
579-
// 落下する
580-
while ((swapTargetY - y) * blockSize <= vcell.dy) {
581-
vcell.dy -= blockSize;
582-
swapTargetY++;
583-
}
584584
}
585-
if (y !== swapTargetY) {
585+
586+
vcell.sprite.y = y * blockSize + marginY + vcell.dy;
587+
if (swapDiff > 0) {
586588
this.setBlock(cx, x, y, { block: null });
587-
this.setBlock(cx, x, swapTargetY, ccell);
588-
const vSwapCell = this.__vsom[swapTargetY][x];
589-
assert(vSwapCell !== null, "it should not happen");
589+
this.setBlock(cx, x, y + swapDiff, ccell);
590+
const vSwapCell = this.__vsom[y + swapDiff][x];
591+
assert(vSwapCell != null, "it should not happen");
590592
vSwapCell.dy = vcell.dy;
591593
vSwapCell.vy = vcell.vy;
592594
vcell.dy = 0;
593595
vcell.vy = 0;
594596
// また抽象化失敗してる...
595-
vSwapCell.sprite.y = y * blockSize + marginY + vSwapCell.dy;
597+
vSwapCell.sprite.y = (y + swapDiff) * blockSize + marginY + vSwapCell.dy;
598+
console.log("dy", vSwapCell.dy, "vy", vSwapCell.vy);
596599
}
597-
vcell.sprite.y = y * blockSize + marginY + vcell.dy;
598600
}
599601
}
600602
}
@@ -611,7 +613,6 @@ function isAvail(cells: GridCell[][], x: number, y: number) {
611613
// 下にブロックがない
612614
return true;
613615
default:
614-
// console.log("ブロックあり");
615616
// 下にブロックがある
616617
return false;
617618
}
@@ -626,18 +627,19 @@ export function createCellsFromStageDefinition(stageDefinition: StageDefinition)
626627
const cellDef = rowDefinition[x];
627628
const block = blockFromDefinition(cellDef);
628629
switch (block) {
629-
case Block.movable: {
630-
const group = stageDefinition.blockGroups.find((b) => b.x === x && b.y === y);
631-
const objectId = group ? group.objectId : Math.random().toString();
630+
// blocks that don't need additional initialization
631+
case Block.block:
632+
case null:
633+
case Block.switchBase:
634+
case Block.goal: {
632635
const cell: GridCell = {
633636
block,
634-
objectId,
635-
switchId: undefined,
636637
};
637638
row.push(cell);
638-
639639
break;
640640
}
641+
// movable blocks
642+
case Block.movable:
641643
case Block.fallable: {
642644
const group = stageDefinition.blockGroups.find((b) => b.x === x && b.y === y);
643645
const objectId = group ? group.objectId : Math.random().toString();
@@ -647,40 +649,16 @@ export function createCellsFromStageDefinition(stageDefinition: StageDefinition)
647649
switchId: undefined,
648650
};
649651
row.push(cell);
652+
650653
break;
651654
}
652-
case Block.block:
653-
case null: {
654-
const cell: GridCell = {
655-
block,
656-
};
657-
row.push(cell);
658-
break;
659-
}
660-
case Block.switch: {
661-
const group = stageDefinition.switchGroups.find((b) => b.x === x && b.y === y);
662-
if (!group) {
663-
throw new Error("switch must have switchGroup");
664-
}
665-
const switchId = group.switchId;
666-
const cell: GridCell = {
667-
block,
668-
switchId,
669-
};
670-
row.push(cell);
671-
break;
672-
}
673-
case Block.switchBase: {
674-
const cell: GridCell = {
675-
block,
676-
};
677-
row.push(cell);
678-
break;
679-
}
655+
// switches
656+
case Block.switch:
657+
case Block.switchingBlockON:
680658
case Block.switchingBlockOFF: {
681659
const group = stageDefinition.switchGroups.find((b) => b.x === x && b.y === y);
682660
if (!group) {
683-
throw new Error("switchingBlock must have switchGroup");
661+
throw new Error("switch must have matching switchGroup");
684662
}
685663
const switchId = group.switchId;
686664
const cell: GridCell = {
@@ -690,14 +668,6 @@ export function createCellsFromStageDefinition(stageDefinition: StageDefinition)
690668
row.push(cell);
691669
break;
692670
}
693-
case Block.goal: {
694-
const cell: GridCell = {
695-
block,
696-
};
697-
row.push(cell);
698-
break;
699-
}
700-
case Block.switchingBlockON:
701671
case Block.switchPressed: {
702672
throw new Error(`createCellsFromStageDefinition: block is not supported: ${block}`);
703673
}
@@ -711,27 +681,13 @@ export function createCellsFromStageDefinition(stageDefinition: StageDefinition)
711681
}
712682

713683
export function blockFromDefinition(d: string): Block | null {
714-
switch (d) {
715-
case ".":
716-
return null;
717-
case "b":
718-
return Block.block;
719-
case "m":
720-
return Block.movable;
721-
case "f":
722-
return Block.fallable;
723-
case "s":
724-
return Block.switch;
725-
case "S":
726-
return Block.switchBase;
727-
case "w":
728-
return Block.switchingBlockOFF;
729-
case "g":
730-
return Block.goal;
731-
default:
732-
throw new Error(`[blockFromDefinition] no proper block: ${d}`);
684+
const block = BlockDefinitionMap.get(d);
685+
if (block === undefined) {
686+
throw new Error(`[blockFromDefinition] no proper block: ${d}`);
733687
}
688+
return block;
734689
}
690+
735691
function createSprite(
736692
blockSize: number,
737693
block: Block,

src/stages.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export type StageDefinition = {
1616
isTutorial?: boolean;
1717
initialPlayerX: number; // 左端から0-indexed
1818
initialPlayerY: number; // 上端から0-indexed +1すると浮かずに地面に立つ
19+
// ブロックと fallable のグループ
1920
blockGroups: {
2021
// 複数ブロックからなるオブジェクトについては明示的に指定
2122
x: number;
@@ -431,11 +432,11 @@ export const stages = new Map<string, StageDefinition>([
431432
".......b.....bbbbb",
432433
"......b......bbbbb",
433434
".....b.......bbbbb",
434-
"...fb........bbbbb",
435+
"....b........bbbbb",
435436
"bbbbbbbbbb.bbbbbbb",
436437
],
437438
initialPlayerX: 1,
438-
initialPlayerY: 7,
439+
initialPlayerY: 2,
439440
blockGroups: [],
440441
switchGroups: [],
441442
},

0 commit comments

Comments
 (0)