-
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
Conversation
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.
Pull request overview
This PR implements frontend support for interactive game mechanics: crates (movable objects), doors (open/close based on button state), and buttons (pressure plates). The implementation adds type definitions, Phaser entities/mechanics classes, and integrates them into the main game scene with real-time server synchronization.
Key Changes:
- Added type definitions for
Crate,Door, andButtonwith corresponding message interfaces for server updates - Created a base
Mechanicclass for stationary game objects (doors, buttons) and integratedCrateas a movableEntity - Integrated these mechanics into the main Phaser scene with message handlers for state synchronization
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
src/types/messages.tsx |
Extended MessageMapInfo with crates, doors, and buttons arrays; added MessageCratesUpdate and MessageDoorsAndButtonsUpdate interfaces for real-time updates |
src/types/door.tsx |
New interface defining door properties including ID, color, position, and open state |
src/types/crate.tsx |
New interface defining crate properties including position and numeric ID |
src/types/button.tsx |
New interface defining button properties including ID, color, position, and pressed state |
src/phaser/mechanics/mechanic.ts |
Base class for stationary mechanics (doors, buttons) extending Phaser.GameObjects.Container with texture management |
src/phaser/mechanics/door.ts |
Door implementation with open/closed state management and texture switching |
src/phaser/mechanics/button.ts |
Button implementation with pressed/released state management and texture switching |
src/phaser/entities/crate.ts |
Crate implementation extending Entity for movable box mechanics |
src/phaser/scenes/main.ts |
Integrated crates, doors, and buttons into the scene: added entity maps, preloaded textures, registered message handlers, and created initialization methods |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| export class Button extends Mechanic { | ||
| public readonly buttonId: string; | ||
| public readonly color: string; |
Copilot
AI
Dec 21, 2025
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 color field 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.
| public get id(): string { | ||
| return this.buttonId; | ||
| } | ||
|
|
Copilot
AI
Dec 21, 2025
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 id getter is defined but never used in the codebase. The Button instances are already accessed via their buttonId property. Consider removing it or documenting why it's needed for future use.
| public get id(): string { | |
| return this.buttonId; | |
| } |
| room.onMessage("cratesUpdate", (message: MessageCratesUpdate) => { | ||
| for (const crateUpdate of message.crates) { | ||
| const crate = this.crates.get(crateUpdate.crateId.toString()); | ||
| if (crate !== undefined) { | ||
| crate.move(crateUpdate.direction); | ||
| } | ||
| } | ||
| }); |
Copilot
AI
Dec 21, 2025
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.
Inconsistent ID handling: the MessageCratesUpdate uses crateId as a number, but it's converted to a string when looking up in the crates Map (line 149). This creates a mismatch between the storage key (string from crateInfo.crateId.toString() in line 212) and potential lookup patterns. Consider standardizing on either number or string for crate IDs throughout the codebase.
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.
Same here with ids (copilot comment)
| } | ||
|
|
||
| export interface MessageDoorsAndButtonsUpdate { | ||
| doorsAndButtons: { doorId: string; buttonId: string; open: boolean }[]; |
Copilot
AI
Dec 21, 2025
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 message interface names an array field doorsAndButtons, but each element contains individual doorId and buttonId properties, suggesting a one-to-one pairing. This naming could be clearer. Consider renaming to doorButtonPairs or connections to better convey that each entry represents a door-button relationship, not separate collections.
| doorsAndButtons: { doorId: string; buttonId: string; open: boolean }[]; | |
| doorButtonPairs: { doorId: string; buttonId: string; open: boolean }[]; |
src/phaser/entities/crate.ts
Outdated
| public readonly crateId: string; | ||
|
|
||
| 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.toString(); |
Copilot
AI
Dec 21, 2025
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.
Type inconsistency: the Crate constructor accepts crateId as a number parameter but immediately converts it to a string. The internal crateId field is typed as string, and the type definition in src/types/crate.tsx defines it as number. Consider accepting number and keeping it as number throughout, or accept string directly to avoid the unnecessary conversion.
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.
Here the copilot is actually right, try to keep it consistant
src/phaser/entities/crate.ts
Outdated
|
|
||
| public get id(): string { | ||
| return this.crateId; | ||
| } |
Copilot
AI
Dec 21, 2025
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 id getter is defined but never used in the codebase. Since the crates are already accessed via their crateId property directly in main.ts, this getter adds no value. Consider removing it or ensure it's needed for future use.
| public get id(): string { | |
| return this.crateId; | |
| } |
src/phaser/entities/crate.ts
Outdated
| move(direction: Direction, ease = "Circular") { | ||
| super.move(direction, ease); | ||
| } | ||
|
|
Copilot
AI
Dec 21, 2025
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 move method override doesn't add any new functionality beyond calling super.move() with the same parameters. This wrapper method is unnecessary and can be removed. The parent class's move method can be called directly.
| move(direction: Direction, ease = "Circular") { | |
| super.move(direction, ease); | |
| } |
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.
Copilot right
| public get id(): string { | ||
| return this.doorId; | ||
| } |
Copilot
AI
Dec 21, 2025
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 id getter is defined but never used in the codebase. The Door instances are already accessed via their doorId property. Consider removing it or documenting why it's needed for future use.
| door.isOpen = element.open; | ||
| } | ||
|
|
||
| if (button !== undefined) { | ||
| button.isPressed = element.open; |
Copilot
AI
Dec 21, 2025
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 message handler processes door and button updates together, but there's no validation that ensures both the doorId and buttonId actually exist before attempting to update them. If the backend sends an update with only a doorId or only a buttonId that exists, the undefined checks will silently skip the missing entity without logging. Consider adding a warning log when an expected door or button is not found to aid debugging.
| 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}`, | |
| ); |
|
|
||
| export class Door extends Mechanic { | ||
| public readonly doorId: string; | ||
| public readonly color: string; |
Copilot
AI
Dec 21, 2025
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 color field in Door and Button types is stored but never used. The code always loads hardcoded green textures ('door-green-open.png', 'button-green.png') regardless of the color value passed from the backend. Either implement color-based texture loading (e.g., 'door-{color}-open.png') or remove the unused color field from the interfaces and constructors.
24bartixx
left a comment
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.
Grate job!
It works good
Just 3 small changes before mergin
As I think about we will have to do smoother player movement animation when the user holds an arror as it jumps unnaturally, but it's for another task
src/phaser/entities/crate.ts
Outdated
| public readonly crateId: string; | ||
|
|
||
| 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.toString(); |
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.
Here the copilot is actually right, try to keep it consistant
src/phaser/entities/crate.ts
Outdated
| move(direction: Direction, ease = "Circular") { | ||
| super.move(direction, ease); | ||
| } | ||
|
|
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.
Copilot right
| room.onMessage("cratesUpdate", (message: MessageCratesUpdate) => { | ||
| for (const crateUpdate of message.crates) { | ||
| const crate = this.crates.get(crateUpdate.crateId.toString()); | ||
| if (crate !== undefined) { | ||
| crate.move(crateUpdate.direction); | ||
| } | ||
| } | ||
| }); |
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.
Same here with ids (copilot comment)
this is frontend implementations of crates, doors and buttons