-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/add box door mechanics phaser #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import type { SpriteAnimator } from "../lib/sprite-animator"; | ||
| import { Entity } from "./entity"; | ||
|
|
||
| export class Crate extends Entity { | ||
| public readonly crateId: number; | ||
|
|
||
| constructor( | ||
| scene: Phaser.Scene, | ||
| x: number, | ||
| y: number, | ||
| crateId: number, | ||
| textureKey = "crate", | ||
| animator: SpriteAnimator | null = null, | ||
| ) { | ||
| super(scene, x, y, textureKey, animator); | ||
| this.crateId = crateId; | ||
| } | ||
|
|
||
| public get id(): number { | ||
| return this.crateId; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,43 @@ | ||||||||
| import { Mechanic } from "./mechanic"; | ||||||||
|
|
||||||||
| export class Button extends Mechanic { | ||||||||
| public readonly buttonId: string; | ||||||||
| public readonly color: string; | ||||||||
| private pressed: boolean; | ||||||||
| private pressedTextureKey: string; | ||||||||
| private releasedTextureKey: string; | ||||||||
|
|
||||||||
| constructor( | ||||||||
| scene: Phaser.Scene, | ||||||||
| x: number, | ||||||||
| y: number, | ||||||||
| buttonId: string, | ||||||||
| color: string, | ||||||||
| pressed = false, | ||||||||
| pressedTextureKey = "button-pressed", | ||||||||
| releasedTextureKey = "button-released", | ||||||||
| ) { | ||||||||
| super(scene, x, y, pressed ? pressedTextureKey : releasedTextureKey); | ||||||||
| this.buttonId = buttonId; | ||||||||
| this.color = color; | ||||||||
| this.pressed = pressed; | ||||||||
| this.pressedTextureKey = pressedTextureKey; | ||||||||
| this.releasedTextureKey = releasedTextureKey; | ||||||||
| } | ||||||||
|
|
||||||||
| public get id(): string { | ||||||||
| return this.buttonId; | ||||||||
| } | ||||||||
|
|
||||||||
|
Comment on lines
+28
to
+31
|
||||||||
| public get id(): string { | |
| return this.buttonId; | |
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import { Mechanic } from "./mechanic"; | ||
|
|
||
| export class Door extends Mechanic { | ||
| public readonly doorId: string; | ||
| public readonly color: string; | ||
|
||
| private openTextureKey: string; | ||
| private closedTextureKey: string; | ||
| private open: boolean; | ||
|
|
||
| constructor( | ||
| scene: Phaser.Scene, | ||
| x: number, | ||
| y: number, | ||
| doorId: string, | ||
| color: string, | ||
| open = false, | ||
| openTextureKey = "door-open", | ||
| closedTextureKey = "door-closed", | ||
| ) { | ||
| super(scene, x, y, open ? openTextureKey : closedTextureKey); | ||
| this.doorId = doorId; | ||
| this.color = color; | ||
| this.open = open; | ||
| this.openTextureKey = openTextureKey; | ||
| this.closedTextureKey = closedTextureKey; | ||
| } | ||
|
|
||
| public get id(): string { | ||
| return this.doorId; | ||
| } | ||
|
Comment on lines
+28
to
+30
|
||
|
|
||
| public get isOpen(): boolean { | ||
| return this.open; | ||
| } | ||
|
|
||
| public set isOpen(value: boolean) { | ||
| this.open = value; | ||
| const textureKey = this.open ? this.openTextureKey : this.closedTextureKey; | ||
| this.changeTexture(textureKey); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { TILE_SIZE } from "../lib/const"; | ||
|
|
||
| export class Mechanic extends Phaser.GameObjects.Container { | ||
| protected sprite: Phaser.GameObjects.Sprite; | ||
| protected gridX: number; | ||
| protected gridY: number; | ||
|
|
||
| constructor( | ||
| scene: Phaser.Scene, | ||
| gridX: number, | ||
| gridY: number, | ||
| textureKey = "door", | ||
| ) { | ||
| super(scene); | ||
|
|
||
| this.gridX = gridX; | ||
| this.gridY = gridY; | ||
|
|
||
| this.sprite = this.scene.add.sprite(0, 0, textureKey); | ||
| this.add(this.sprite); | ||
|
|
||
| this.setPosition( | ||
| this.gridX * TILE_SIZE + TILE_SIZE / 2, | ||
| this.gridY * TILE_SIZE + TILE_SIZE / 2, | ||
| ); | ||
| } | ||
|
|
||
| public changeTexture(textureKey: string) { | ||
| this.sprite.setTexture(textureKey); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,13 +1,19 @@ | ||||||||||||||||||||||||||||||||||||||
| import type { Room } from "colyseus.js"; | ||||||||||||||||||||||||||||||||||||||
| import * as Phaser from "phaser"; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| import type { Button as ButtonType } from "../../types/button"; | ||||||||||||||||||||||||||||||||||||||
| import type { Crate as CrateType } from "../../types/crate"; | ||||||||||||||||||||||||||||||||||||||
| import type { Door as DoorType } from "../../types/door"; | ||||||||||||||||||||||||||||||||||||||
| import type { | ||||||||||||||||||||||||||||||||||||||
| MessageCratesUpdate, | ||||||||||||||||||||||||||||||||||||||
| MessageDoorsAndButtonsUpdate, | ||||||||||||||||||||||||||||||||||||||
| MessageMapInfo, | ||||||||||||||||||||||||||||||||||||||
| MessageOnAddPlayer, | ||||||||||||||||||||||||||||||||||||||
| MessageOnRemovePlayer, | ||||||||||||||||||||||||||||||||||||||
| MessagePositionUpdate, | ||||||||||||||||||||||||||||||||||||||
| } from "../../types/messages"; | ||||||||||||||||||||||||||||||||||||||
| import type { Player as PlayerType } from "../../types/player"; | ||||||||||||||||||||||||||||||||||||||
| import { Crate } from "../entities/crate"; | ||||||||||||||||||||||||||||||||||||||
| import { Player } from "../entities/player"; | ||||||||||||||||||||||||||||||||||||||
| import { TILE_SIZE } from "../lib/const"; | ||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -18,10 +24,15 @@ import { | |||||||||||||||||||||||||||||||||||||
| } from "../lib/player-animators"; | ||||||||||||||||||||||||||||||||||||||
| import type { SpriteAnimator } from "../lib/sprite-animator"; | ||||||||||||||||||||||||||||||||||||||
| import { getTileName } from "../lib/utils"; | ||||||||||||||||||||||||||||||||||||||
| import { Button } from "../mechanics/button"; | ||||||||||||||||||||||||||||||||||||||
| import { Door } from "../mechanics/door"; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| export class Main extends Phaser.Scene { | ||||||||||||||||||||||||||||||||||||||
| private room!: Room; | ||||||||||||||||||||||||||||||||||||||
| private players = new Map<string, Player>(); | ||||||||||||||||||||||||||||||||||||||
| private crates = new Map<number, Crate>(); | ||||||||||||||||||||||||||||||||||||||
| private buttons = new Map<string, Button>(); | ||||||||||||||||||||||||||||||||||||||
| private doors = new Map<string, Door>(); | ||||||||||||||||||||||||||||||||||||||
| private cursors!: Phaser.Types.Input.Keyboard.CursorKeys; | ||||||||||||||||||||||||||||||||||||||
| private wasd!: { | ||||||||||||||||||||||||||||||||||||||
| W: Phaser.Input.Keyboard.Key; | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -49,6 +60,10 @@ export class Main extends Phaser.Scene { | |||||||||||||||||||||||||||||||||||||
| this.load.image("wall", "images/wall.png"); | ||||||||||||||||||||||||||||||||||||||
| this.load.image("crate", "images/crate.png"); | ||||||||||||||||||||||||||||||||||||||
| this.load.image("ground", "images/ground.png"); | ||||||||||||||||||||||||||||||||||||||
| this.load.image("button-released", "images/buttons/button-green.png"); | ||||||||||||||||||||||||||||||||||||||
| this.load.image("button-pressed", "images/buttons/button-red.png"); | ||||||||||||||||||||||||||||||||||||||
| this.load.image("door-open", "images/doors/door-green-open.png"); | ||||||||||||||||||||||||||||||||||||||
| this.load.image("door-closed", "images/doors/door-green-closed.png"); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| for (const [index, textureKey] of PLAYER_TEXTURE_KEYS.entries()) { | ||||||||||||||||||||||||||||||||||||||
| this.load.spritesheet( | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -89,6 +104,18 @@ export class Main extends Phaser.Scene { | |||||||||||||||||||||||||||||||||||||
| for (const player of message.players) { | ||||||||||||||||||||||||||||||||||||||
| this.addPlayer(player); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| for (const crate of message.crates) { | ||||||||||||||||||||||||||||||||||||||
| this.addCrate(crate); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| for (const button of message.buttons) { | ||||||||||||||||||||||||||||||||||||||
| this.addButton(button); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| for (const door of message.doors) { | ||||||||||||||||||||||||||||||||||||||
| this.addDoor(door); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| room.onMessage("onAddPlayer", (message: MessageOnAddPlayer) => { | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -117,6 +144,33 @@ export class Main extends Phaser.Scene { | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| room.onMessage("cratesUpdate", (message: MessageCratesUpdate) => { | ||||||||||||||||||||||||||||||||||||||
| for (const crateUpdate of message.crates) { | ||||||||||||||||||||||||||||||||||||||
| const crate = this.crates.get(crateUpdate.crateId); | ||||||||||||||||||||||||||||||||||||||
| if (crate !== undefined) { | ||||||||||||||||||||||||||||||||||||||
| crate.move(crateUpdate.direction); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| room.onMessage( | ||||||||||||||||||||||||||||||||||||||
| "doorsAndButtonsUpdate", | ||||||||||||||||||||||||||||||||||||||
| (message: MessageDoorsAndButtonsUpdate) => { | ||||||||||||||||||||||||||||||||||||||
| for (const element of message.doorsAndButtons) { | ||||||||||||||||||||||||||||||||||||||
| const door = this.doors.get(element.doorId); | ||||||||||||||||||||||||||||||||||||||
| const button = this.buttons.get(element.buttonId); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (door !== undefined) { | ||||||||||||||||||||||||||||||||||||||
| door.isOpen = element.open; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (button !== undefined) { | ||||||||||||||||||||||||||||||||||||||
| button.isPressed = element.open; | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+164
to
+168
|
||||||||||||||||||||||||||||||||||||||
| door.isOpen = element.open; | |
| } | |
| if (button !== undefined) { | |
| button.isPressed = element.open; | |
| door.isOpen = element.open; | |
| } else { | |
| console.warn( | |
| `doorsAndButtonsUpdate: door with id "${element.doorId}" not found when setting open=${element.open}`, | |
| ); | |
| } | |
| if (button !== undefined) { | |
| button.isPressed = element.open; | |
| } else { | |
| console.warn( | |
| `doorsAndButtonsUpdate: button with id "${element.buttonId}" not found when setting pressed=${element.open}`, | |
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| export interface Button { | ||
| x: number; | ||
| y: number; | ||
| buttonId: string; | ||
| color: string; | ||
| pressed: boolean; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| export interface Crate { | ||
| x: number; | ||
| y: number; | ||
| crateId: number; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| export interface Door { | ||
| doorId: string; | ||
| color: string; | ||
| x: number; | ||
| y: number; | ||
| open: boolean; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,10 +1,24 @@ | ||||||
| import type { Button } from "../types/button"; | ||||||
| import type { Crate } from "../types/crate"; | ||||||
| import type { Door } from "../types/door"; | ||||||
| import type { Player } from "../types/player"; | ||||||
|
|
||||||
| export interface MessageMapInfo { | ||||||
| grid: number[][]; | ||||||
| width: number; | ||||||
| height: number; | ||||||
| players: Player[]; | ||||||
| crates: Crate[]; | ||||||
| doors: Door[]; | ||||||
| buttons: Button[]; | ||||||
| } | ||||||
|
|
||||||
| export interface MessageCratesUpdate { | ||||||
| crates: { crateId: number; direction: "left" | "right" | "up" | "down" }[]; | ||||||
| } | ||||||
|
|
||||||
| export interface MessageDoorsAndButtonsUpdate { | ||||||
| doorsAndButtons: { doorId: string; buttonId: string; open: boolean }[]; | ||||||
|
||||||
| doorsAndButtons: { doorId: string; buttonId: string; open: boolean }[]; | |
| doorButtonPairs: { doorId: string; buttonId: string; open: boolean }[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
colorfield in Button is stored but never used. The code always loads hardcoded green/red button textures regardless of the color value passed from the backend. Either implement color-based texture loading (e.g., 'button-{color}.png') or remove the unused color field from the interface and constructor.