Skip to content

Commit e389f5f

Browse files
committed
スイッチとオブジェクトの重複
1 parent a2085ef commit e389f5f

File tree

4 files changed

+151
-47
lines changed

4 files changed

+151
-47
lines changed

src/ability.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export function copy(cx: Context) {
6969
const movableObject = cx.grid.getMovableObject(cx, x, y);
7070
if (!movableObject) return;
7171

72+
movableObject.objectId = Math.random().toString();
73+
7274
History.record(cx);
7375

7476
cx.state.update((prev) => {
@@ -100,7 +102,7 @@ export function paste(cx: Context) {
100102
const positionX = x + i.x;
101103
const positionY = y + i.y;
102104
const target = cx.grid.getBlock(cx, positionX, positionY);
103-
if (target !== Block.air) {
105+
if (target !== Block.air && target !== Block.switch) {
104106
// すでに何かある場合は、ペーストできない
105107
return;
106108
}
@@ -126,7 +128,11 @@ export function cut(cx: Context) {
126128
const y = focus.y;
127129
const target = cx.grid.getBlock(cx, x, y);
128130
// removable 以外はカットできない
129-
if (!target || target !== Block.movable) return;
131+
if (
132+
!target ||
133+
(target !== Block.movable && target !== Block.switchWithObject)
134+
)
135+
return;
130136
const movableObject = cx.grid.getMovableObject(cx, x, y);
131137
if (!movableObject) return;
132138

@@ -136,9 +142,19 @@ export function cut(cx: Context) {
136142
prev.inventory = movableObject;
137143
return prev;
138144
});
139-
cx.grid.update(cx, (prev) =>
140-
prev.objectId === movableObject.objectId ? { block: Block.air } : prev,
141-
);
145+
if (target === Block.movable) {
146+
cx.grid.update(cx, (prev) =>
147+
prev.objectId === movableObject.objectId ? { block: Block.air } : prev,
148+
);
149+
}
150+
if (target === Block.switchWithObject) {
151+
cx.grid.update(cx, (prev) => {
152+
if (prev.objectId !== movableObject.objectId) return prev;
153+
if (prev.block === Block.switchWithObject)
154+
return { block: Block.switch, switchId: prev.switchId };
155+
return { block: Block.air };
156+
});
157+
}
142158

143159
printCells(createSnapshot(cx).game.cells, "cut");
144160
History.record(cx);
@@ -156,7 +172,7 @@ export function placeMovableObject(
156172
const positionX = x + i.x;
157173
const positionY = y + i.y;
158174
const target = grid.getBlock(cx, positionX, positionY);
159-
if (target !== Block.air) {
175+
if (target !== Block.air && target !== Block.switch) {
160176
// すでに何かある場合は、ペーストできない
161177
return;
162178
}

src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export enum Block {
1212
movable = "movable",
1313
switch = "switch",
1414
switchBase = "switch-base",
15+
switchWithObject = "switch-with-object",
1516
}
1617
export enum Facing {
1718
left = "left",

src/grid.ts

Lines changed: 117 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,17 @@ export type GridCell =
3131
}
3232
| {
3333
block: Block.switch;
34+
switchId?: string;
3435
objectId?: unknown;
3536
}
3637
| {
3738
block: Block.switchBase;
3839
objectId?: unknown;
40+
}
41+
| {
42+
block: Block.switchWithObject;
43+
switchId?: string;
44+
objectId: string; // Block.movableのID
3945
};
4046

4147
export class Grid {
@@ -207,7 +213,8 @@ export class Grid {
207213
const cells = get(cx.state).cells;
208214
const cell = cells[y]?.[x];
209215
if (!cell) return undefined;
210-
if (cell.block !== Block.movable) return undefined;
216+
if (cell.block !== Block.movable && cell.block !== Block.switchWithObject)
217+
return undefined;
211218
const objectId = cell.objectId;
212219
const retrievedBlocks: { x: number; y: number }[] = [];
213220
for (let y = 0; y < cells.length; y++) {
@@ -225,7 +232,7 @@ export class Grid {
225232
.reduce((a, b) => Math.max(a, b), 0);
226233

227234
const retrievedObject: MovableObject = {
228-
block: cell.block,
235+
block: Block.movable,
229236
objectId,
230237
relativePositions: retrievedBlocks.map((block) => ({
231238
x: block.x - minX,
@@ -257,56 +264,116 @@ export class Grid {
257264
"sprites is out of sync with cells: expected null, got sprite",
258265
);
259266
}
260-
if (prev.block !== Block.air && prev.sprite === null) {
267+
if (
268+
prev.block !== Block.air &&
269+
prev.block !== Block.switch &&
270+
prev.sprite === null
271+
) {
261272
console.warn(
262273
"sprites is out of sync with cells: expected sprite, got null",
263274
);
264275
}
265276

266-
if (cell.block !== Block.movable && cell.objectId) {
277+
if (
278+
cell.block !== Block.movable &&
279+
cell.block !== Block.switchWithObject &&
280+
cell.objectId
281+
) {
267282
console.warn("Cell is not movable but has an objectId");
268283
}
269284

270-
switch (cell.block) {
271-
case Block.air:
272-
cells[y][x] = {
273-
block: cell.block,
274-
objectId: undefined,
275-
};
276-
prev.sprite = null;
277-
prev.block = cell.block;
278-
break;
279-
case Block.block: {
280-
const blockSprite = createSprite(blockSize, cell.block, x, y, marginY);
281-
stage.addChild(blockSprite);
282-
cells[y][x] = {
283-
block: cell.block,
284-
objectId: undefined,
285-
};
286-
prev.sprite = blockSprite;
287-
prev.block = cell.block;
288-
break;
285+
if (prev.block === Block.switch) {
286+
if (cell.block !== Block.movable) {
287+
console.warn(
288+
"No block other than movable cannot be placed on the switch",
289+
);
290+
return;
289291
}
290-
case Block.movable: {
291-
const movableSprite = createSprite(
292-
blockSize,
293-
cell.block,
294-
x,
295-
y,
296-
marginY,
292+
const movableSprite = createSprite(
293+
blockSize,
294+
Block.switchWithObject,
295+
x,
296+
y,
297+
marginY,
298+
);
299+
stage.addChild(movableSprite);
300+
assert(cell.objectId !== undefined, "movable block must have objectId");
301+
if (cells[y][x].block !== Block.switch) return;
302+
cells[y][x] = {
303+
block: Block.switchWithObject,
304+
switchId: cells[y][x].switchId,
305+
objectId: cell.objectId,
306+
};
307+
prev.sprite = movableSprite;
308+
prev.block = Block.switchWithObject;
309+
} else if (prev.block === Block.switchWithObject) {
310+
if (cell.block !== Block.switch) {
311+
console.warn(
312+
"No block other than switch cannot replace the switch with object",
297313
);
298-
stage.addChild(movableSprite);
299-
assert(cell.objectId !== undefined, "movable block must have objectId");
300-
cells[y][x] = {
301-
block: cell.block,
302-
objectId: cell.objectId,
303-
};
304-
prev.sprite = movableSprite;
305-
prev.block = cell.block;
306-
break;
314+
return;
315+
}
316+
const blockSprite = createSprite(blockSize, Block.switch, x, y, marginY);
317+
stage.addChild(blockSprite);
318+
if (cells[y][x].block !== Block.switchWithObject) return;
319+
cells[y][x] = {
320+
block: Block.switch,
321+
switchId: cells[y][x].switchId,
322+
objectId: undefined,
323+
};
324+
prev.sprite = blockSprite;
325+
prev.block = Block.switch;
326+
} else {
327+
switch (cell.block) {
328+
case Block.air:
329+
cells[y][x] = {
330+
block: cell.block,
331+
objectId: undefined,
332+
};
333+
prev.sprite = null;
334+
prev.block = cell.block;
335+
break;
336+
case Block.block: {
337+
const blockSprite = createSprite(
338+
blockSize,
339+
cell.block,
340+
x,
341+
y,
342+
marginY,
343+
);
344+
stage.addChild(blockSprite);
345+
cells[y][x] = {
346+
block: cell.block,
347+
objectId: undefined,
348+
};
349+
prev.sprite = blockSprite;
350+
prev.block = cell.block;
351+
break;
352+
}
353+
case Block.movable: {
354+
const movableSprite = createSprite(
355+
blockSize,
356+
cell.block,
357+
x,
358+
y,
359+
marginY,
360+
);
361+
stage.addChild(movableSprite);
362+
assert(
363+
cell.objectId !== undefined,
364+
"movable block must have objectId",
365+
);
366+
cells[y][x] = {
367+
block: cell.block,
368+
objectId: cell.objectId,
369+
};
370+
prev.sprite = movableSprite;
371+
prev.block = cell.block;
372+
break;
373+
}
374+
default:
375+
// cell satisfies never;
307376
}
308-
default:
309-
// cell satisfies never;
310377
}
311378
cx.state.update((prev) => ({
312379
...prev,
@@ -350,6 +417,7 @@ export function createCellsFromStageDefinition(
350417
case Block.switch: {
351418
const cell: GridCell = {
352419
block,
420+
switchId: Math.random().toString(),
353421
};
354422
row.push(cell);
355423
break;
@@ -416,6 +484,12 @@ function createSprite(
416484
updateSprite(switchBaseSprite, blockSize, x, y, marginY);
417485
return switchBaseSprite;
418486
}
487+
case Block.switchWithObject: {
488+
const movableSprite = new Sprite(rockTexture);
489+
movableSprite.tint = 0xff0000;
490+
updateSprite(movableSprite, blockSize, x, y, marginY);
491+
return movableSprite;
492+
}
419493
default:
420494
throw new Error("no proper block");
421495
}
@@ -451,6 +525,8 @@ export function printCells(cells: GridCell[][], context?: string) {
451525
return "s";
452526
case Block.switchBase:
453527
return "S";
528+
case Block.switchWithObject:
529+
return "M";
454530
default:
455531
cell satisfies never;
456532
}

src/player.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,10 @@ export function tick(cx: Context, ticker: Ticker) {
159159

160160
const isBlock = (x: number, y: number) =>
161161
cx.grid.getBlock(cx, Math.floor(x), Math.floor(y)) !== Block.air &&
162+
cx.grid.getBlock(cx, Math.floor(x), Math.floor(y)) !== Block.switch &&
162163
cx.grid.getBlock(cx, Math.floor(x), Math.floor(y)) !== undefined;
164+
const isSwitchBase = (x: number, y: number) =>
165+
cx.grid.getBlock(cx, Math.floor(x), Math.floor(y)) === Block.switchBase;
163166
const isOutOfWorldLeft = (x: number) => x < 0;
164167
const isOutOfWorldRight = (x: number) => x >= gridX;
165168
const isOutOfWorldBottom = (y: number) => y >= gridY + marginY / blockSize;
@@ -230,6 +233,14 @@ export function tick(cx: Context, ticker: Ticker) {
230233
player.vy = 0;
231234
}
232235

236+
if (isSwitchBase(nextX, nextBottomY)) {
237+
const switchBlock = cx.grid.getBlock(cx, nextX, nextTopY);
238+
if (switchBlock !== Block.switchWithObject) {
239+
// if (switchBlock !== Block.switch) throw new Error("Invalid switch block");
240+
cx.state.set;
241+
}
242+
}
243+
233244
// 当たり判定結果を反映する
234245
player.x += player.vx * ticker.deltaTime;
235246
player.y += player.vy * ticker.deltaTime;

0 commit comments

Comments
 (0)