Skip to content

Commit

Permalink
Merge pull request #6 from Abstractolotl/scene-refactor
Browse files Browse the repository at this point in the history
Add base classes for scenes & wrap game objects
  • Loading branch information
NouCake authored Jan 16, 2024
2 parents 04adbef + 7ea3b79 commit 772aa88
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 200 deletions.
20 changes: 11 additions & 9 deletions src/board/board.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,30 @@ export interface BoardPacket extends PlayerPacket {

const PLAYER_SIZE = 16;
const BOARD_SIDE_LENGTH = 12;
export default class GameBoard {
export default class GameBoard extends Phaser.GameObjects.Container {

static preload(scene: Scene) {
scene.load.image("board_bg", "assets/title_background.png")
}

private TILE_SIZE: number;

private scene: Scene;
private aznopoly: AzNopolyGame;

private players: Map<string, BoardPlayer>;
private bounds: { x: number, y: number, size: number };
private size: number;

constructor(aznopoly: AzNopolyGame, scene: Scene, { x, y, size }: { x: number, y: number, size: number }) {
constructor(aznopoly: AzNopolyGame, scene: Scene, x: number, y: number, size: number) {
super(scene, x, y);
this.size = size;
this.aznopoly = aznopoly;
this.scene = scene;
this.players = new Map();
this.bounds = { x, y, size };

this.TILE_SIZE = size / BOARD_SIDE_LENGTH;

const background = this.scene.add.image(x, y, "board_bg")
const background = new Phaser.GameObjects.Image(scene, 0, 0, "board_bg");
this.add(background);

const targetScale = size / background.width;
background.setScale(targetScale);
background.setOrigin(0, 0);
Expand Down Expand Up @@ -82,9 +83,10 @@ export default class GameBoard {
const coords = GameBoard.getCoordForPos(startPos);
const color = getColorFromUUID(this.aznopoly.room.getPlayerName(uuid));
const player = {
gameObject: this.scene.add.rectangle(coords.x, coords.y, PLAYER_SIZE, PLAYER_SIZE, color),
gameObject: new Phaser.GameObjects.Rectangle(this.scene, coords.x * this.TILE_SIZE, coords.y * this.TILE_SIZE, PLAYER_SIZE, PLAYER_SIZE, color),
position: startPos,
};
this.add(player.gameObject);
this.players.set(uuid, player)
this.movePlayer(uuid, 0);
return player;
Expand Down Expand Up @@ -113,7 +115,7 @@ export default class GameBoard {
player.position += distance;
const coords = GameBoard.getCoordForPos(player.position);

player.gameObject.setPosition(this.bounds.x + coords.x * this.TILE_SIZE, this.bounds.y + coords.y * this.TILE_SIZE)
player.gameObject.setPosition(coords.x * this.TILE_SIZE, coords.y * this.TILE_SIZE)
this.checkPlayerColisions();
}

Expand Down
30 changes: 20 additions & 10 deletions src/game.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import AzNopolyClient from "./client";
import Room from "./room";
import { Player } from "./types";
import { PacketType, RoomInitPacket, RoomNamePacket } from "./types/client";

export default class AzNopolyGame {

private _room: Room;
private _client: AzNopolyClient;
private _name: string;
private _room!: Room;
private _client!: AzNopolyClient;
private _name!: string;

constructor(room: string, name: string) {
constructor() {
(window as any)["aznopoly"] = this;
}

public init(roomId: string) {
this._client = new AzNopolyClient();
this._room = new Room(room, this, this.client)
this._name = name;
this._room = new Room(roomId, this, this.client);
this._name = this.getPlayerName();

this._client.connect(room);

(window as any)["game"] = this;
this._client.connect(roomId);
}

public get player(): Player {
Expand All @@ -42,4 +43,13 @@ export default class AzNopolyGame {
return this.room.host == uuid;
}

public updatePlayerName(name: string) {
this._name = name;
}

private getPlayerName() {
const names = ["Bob", "Bebb", "Steve", "Michael", "John", "Doe", "Wurstbrigand"];
return names[Math.floor(Math.random() * names.length)];
}

}
10 changes: 6 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Phaser from 'phaser';
import TitleScene from './scene/title-scene';
import GameScene from './scene/game-scene';
import LobbyScene from './scene/lobby-scene';
import AzNopolyGame from './game';

export const WIDTH = 1280;
export const HEIGHT = 720;
Expand All @@ -21,11 +22,12 @@ window.onload = () => {
}
});

game.scene.add('title', TitleScene);
game.scene.add('lobby', LobbyScene);
game.scene.add('game', GameScene);
const aznopoly = new AzNopolyGame();

game.scene.start('title');
game.scene.add('title', new TitleScene(aznopoly));
game.scene.add('lobby', new LobbyScene(aznopoly));
game.scene.add('game', new GameScene(aznopoly));

game.scene.start('title');
Object.assign(window, { game });
};
15 changes: 6 additions & 9 deletions src/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,19 @@ export default class Room extends EventTarget {
this._connectedIds.add(client);
});

this._playerNames.set(this.aznopoly.player.uuid, this.aznopoly.player.name);
this.broadcastName(this.aznopoly.player.uuid, this.aznopoly.player.name);
this._playerNames.set(this.aznopoly.client.id, this.aznopoly.player.name);
this.broadcastName(this.aznopoly.client.id, this.aznopoly.player.name);

this.dispatchEvent(new Event(RoomEvent.READY));
}

private broadcastName(id: string, name: string) {
// if (this.client.debugMode) {
// console.log("Broadcasting name", id, name)
// }

const namePacket: RoomNamePacket = {
type: PacketType.ROOM_NAME,
sender: id,
sender: this.client.id,
data: {
name
name,
uuid: id,
}
}
this.client.sendPacket(namePacket)
Expand Down Expand Up @@ -102,7 +99,7 @@ export default class Room extends EventTarget {
console.warn("Player " + packet.sender + " tried to change their name, but the room is locked!");
}

this._playerNames.set(packet.sender, packet.data.name);
this._playerNames.set(packet.data.uuid, packet.data.name);
this.dispatchEvent(new Event(RoomEvent.UPDATE));
}

Expand Down
18 changes: 15 additions & 3 deletions src/scene-network-util.ts → src/scene-switcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@ import AzNopolyClient from "./client";
import AzNopolyGame from "./game";
import { PacketType, SceneChangePacket, SceneReadyPacket } from "./types/client";

export const SceneSwitcher = {
waitForPlayers: (aznopoly: AzNopolyGame, sceneKey: string) => {
sendSceneChangePacket(aznopoly, sceneKey);
return new Promise<void>((resolve) => {
new SceneReadyListener(aznopoly, sceneKey, () => {
resolve();
});
});
},
updateScene: sendSceneReadyPacket
}

/**
* Waits for every player to send a "Ready" packet
*/
export class SceneReadyListener {
class SceneReadyListener {

private aznopoly: AzNopolyGame;

Expand Down Expand Up @@ -39,7 +51,7 @@ export class SceneReadyListener {

}

export function sendSceneReadyPacket(aznopoly: AzNopolyGame, sceneName: string) {
function sendSceneReadyPacket(aznopoly: AzNopolyGame, sceneName: string) {
const packet: SceneReadyPacket = {
type: PacketType.SCEEN_READY,
sender: aznopoly.client.id,
Expand All @@ -50,7 +62,7 @@ export function sendSceneReadyPacket(aznopoly: AzNopolyGame, sceneName: string)
aznopoly.client.sendPacket(packet);
}

export function sendSceneChangePacket(aznopoly: AzNopolyGame, sceneName: string) {
function sendSceneChangePacket(aznopoly: AzNopolyGame, sceneName: string) {
const packet: SceneChangePacket = {
type: PacketType.SCENE_CHANGE,
sender: aznopoly.client.id,
Expand Down
58 changes: 58 additions & 0 deletions src/scene/base-scene.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Scene } from "phaser";
import AzNopolyGame from "../game";
import { SceneSwitcher } from "../scene-switcher";
import { PacketType, PlayerPacket, SceneChangePacket } from "../types/client";


export class BaseScene extends Phaser.Scene {

protected aznopoly: AzNopolyGame;
private packetListener: [string, EventListener][] = [];
private sync: boolean;

constructor(aznopoly: AzNopolyGame, synced: boolean = true) {
super();
this.aznopoly = aznopoly;
this.sync = synced;
}

init() {
if(!this.aznopoly.client) return;

if (this.sync) {
if (!this.aznopoly.isHost) {
SceneSwitcher.updateScene(this.aznopoly, this.scene.key);
} else {
SceneSwitcher.waitForPlayers(this.aznopoly, this.scene.key).then(() => {
this.onAllPlayerReady();
});
}
}
this.addPacketListener(PacketType.SCENE_CHANGE, this.onChangeScene.bind(this));
}

protected onAllPlayerReady() {

}

protected addPacketListener<T extends PlayerPacket>(type: string, callback: (packet: T) => void) {
const listener: EventListener = (event: Event) => {
const packet = (event as CustomEvent<T>).detail;
callback(packet);
};
this.packetListener.push([type, listener]);
this.aznopoly.client.addEventListener(type, listener);
}

protected cleanPacketListeners() {
this.packetListener.forEach(([type, listener]) => {
this.aznopoly.client.removeEventListener(type, listener);
});
}

private onChangeScene(packet: SceneChangePacket) {
if (!this.aznopoly.isPlayerHost(packet.sender)) return;
this.scene.start(packet.data.scene);
}

}
55 changes: 18 additions & 37 deletions src/scene/game-scene.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,58 @@
import GameBoard from "../board/board";
import AzNopolyGame from "../game";
import { HEIGHT, WIDTH } from "../main";
import { SceneReadyListener, sendSceneChangePacket, sendSceneReadyPacket } from "../scene-network-util";
import { SceneSwitcher } from "../scene-switcher";
import { FONT_STYLE_BODY, FONT_STYLE_HEADLINE } from "../style";
import { GameTurnRollPacket, GameTurnStartPacket, PacketType } from "../types/client";
import { AzNopolyButton } from "../ui/button";
import PlayerList from "../ui/player-list";
import { BaseScene } from "./base-scene";


const SCENE_NAME = "GAME";
export default class GameScene extends Phaser.Scene {
export default class GameScene extends BaseScene {

private board!: GameBoard;
private aznopoly!: AzNopolyGame;
private rollButton!: AzNopolyButton;

private turnNumber: number = 0;
private currentPlayerIndex: number = 0;

private currentTurnText!: Phaser.GameObjects.Text;
private currentTurnValue!: Phaser.GameObjects.Text;

preload() {
GameBoard.preload(this);
}

init(data: any) {
this.aznopoly = data.aznopoly;
}

private networkInit() {
if (this.aznopoly.isHost) {
new SceneReadyListener(this.aznopoly, SCENE_NAME, () => {
this.hostSceneInit();
});
sendSceneChangePacket(this.aznopoly, SCENE_NAME);

this.aznopoly.client.addEventListener(PacketType.GAME_TURN_ROLL, this.onTurnRoll.bind(this) as EventListener);
}
onAllPlayerReady() {
this.aznopoly.room.connectedPlayerIds.forEach(uuid => {
this.board.addPlayer(uuid);
});

this.aznopoly.client.addEventListener(PacketType.GAME_TURN_START, this.onTurnStart.bind(this) as EventListener);
this.startTurn();
}

create() {
const boardSize = HEIGHT * 0.8;
this.board = new GameBoard(this.aznopoly, this, {x: (WIDTH - boardSize) * 0.5 - 200, y: (HEIGHT - boardSize) * 0.5, size: boardSize});
this.board = this.add.existing(new GameBoard(this.aznopoly, this, (WIDTH - boardSize) * 0.5 - 200, (HEIGHT - boardSize) * 0.5, boardSize));

const playerList = new PlayerList(this, false, WIDTH - 300, 0, 250);
const playerList = this.add.existing(new PlayerList(this, false, WIDTH - 300, 0, 250));
playerList.updatePlayerList(this.aznopoly.room.connectedPlayerIds.map(e => ({name: this.aznopoly.room.getPlayerName(e), host: false})))
playerList.updateTitle("");

this.rollButton = new AzNopolyButton(this, "Roll Dice", WIDTH - 150, HEIGHT - 100, this.onRollClick.bind(this));
this.rollButton = this.add.existing(new AzNopolyButton(this, "Roll Dice", WIDTH - 150, HEIGHT - 100, this.onRollClick.bind(this)));
this.rollButton.disable();

this.currentTurnText = this.add.text(WIDTH - 300, 300, "Current Turn:", FONT_STYLE_BODY);
this.add.text(WIDTH - 300, 300, "Current Turn:", FONT_STYLE_BODY);
this.currentTurnValue = this.add.text(WIDTH - 300, 350, "", FONT_STYLE_BODY);

this.networkInit();
if (!this.aznopoly.isHost) {
sendSceneReadyPacket(this.aznopoly, SCENE_NAME);
}
}

update(time: number, delta: number) {
this.rollButton.update(time, delta);
private networkInit() {
if (this.aznopoly.isHost) {
this.aznopoly.client.addEventListener(PacketType.GAME_TURN_ROLL, this.onTurnRoll.bind(this) as EventListener);
}

this.aznopoly.client.addEventListener(PacketType.GAME_TURN_START, this.onTurnStart.bind(this) as EventListener);
}

private onRollClick() {
Expand Down Expand Up @@ -102,14 +91,6 @@ export default class GameScene extends Phaser.Scene {
}
}

private hostSceneInit() {
this.aznopoly.room.connectedPlayerIds.forEach(uuid => {
this.board.addPlayer(uuid);
});

this.startTurn();
}

private rollDice() {
const roll = Math.floor(Math.random() * 6) + 1;

Expand Down
Loading

0 comments on commit 772aa88

Please sign in to comment.