diff --git a/gameserver/commands/OnJoinCommand.ts b/gameserver/commands/OnJoinCommand.ts index 2bf285e..c3720ce 100644 --- a/gameserver/commands/OnJoinCommand.ts +++ b/gameserver/commands/OnJoinCommand.ts @@ -1,18 +1,28 @@ // OnJoinCommand.ts import { Command } from "@colyseus/command"; import { SessionRoom } from "../SessionRoom"; -import { Client } from "colyseus"; import { nanoid } from "nanoid"; import { CommandPayload } from "./CommandPayloadType"; +import * as helper from '../helpers'; +import SAT from 'sat'; export class OnJoinCommand extends Command { execute({ client, message, gameManager }: CommandPayload) { const sessionId = client.sessionId; - console.log("Player Joined", message); + const playerPos = new SAT.Vector( + (Math.random() * gameManager?.scene.getDimension().x!), + (Math.random() * gameManager?.scene.getDimension().y!) + ); + + const clampedPos = helper.clampVector( + playerPos, + new SAT.Vector(100,100), + gameManager!.scene.getDimension()!.clone().sub(new SAT.Vector(100,100)) + ); const playerState = this.state.addPlayer( sessionId, message?.playerName || `Player_${nanoid()}`, - message?.x || 0, - message?.y || 0 + clampedPos.x, + clampedPos.y, ); if (!playerState) return; gameManager?.addPlayer(playerState); diff --git a/public/constant.ts b/public/constant.ts index b21a9cd..c1b2bbb 100644 --- a/public/constant.ts +++ b/public/constant.ts @@ -8,6 +8,7 @@ export default { SESSIONLOBBY: "SESSIONLOBBY", SPAWNSELECTSCENE: "SPAWNSELECT", HUD_SCORE: "SCOREHUD", + TUTORIAL: "TUTORIAL", }, GAMEEVENTS: { SOLDIER_CREATED: "SC", diff --git a/public/html/menu-form.html b/public/html/menu-form.html index 7b61b4b..e670f8a 100644 --- a/public/html/menu-form.html +++ b/public/html/menu-form.html @@ -3,8 +3,10 @@ /* General Styles */ body { - font-family: 'Montserrat', sans-serif; /* Default font */ - background-color: #f5f5f5; /* Example background color */ + font-family: 'Montserrat', sans-serif; + /* Default font */ + background-color: #f5f5f5; + /* Example background color */ } /* Button styles */ @@ -41,9 +43,11 @@ position: relative; padding: 1px; width: 400px; - background: rgba(255, 255, 255, 0.5); /* Corrected to use RGBA for transparency */ + background: rgba(255, 255, 255, 0.5); + /* Corrected to use RGBA for transparency */ border-radius: 10px; - font-family: 'Montserrat', sans-serif; /* Explicitly set the font */ + font-family: 'Montserrat', sans-serif; + /* Explicitly set the font */ } input[type="submit"] { @@ -54,9 +58,12 @@ font-size: 18px; font-weight: 700; cursor: pointer; - background-color: #4CAF50; /* Example background color */ - color: white; /* Text color */ - border: none; /* Remove border */ + background-color: #4CAF50; + /* Example background color */ + color: white; + /* Text color */ + border: none; + /* Remove border */ } @@ -71,4 +78,5 @@

Conquesta

- + + \ No newline at end of file diff --git a/public/scenes/GameScene.ts b/public/scenes/GameScene.ts index 36c8c6d..e893ab6 100644 --- a/public/scenes/GameScene.ts +++ b/public/scenes/GameScene.ts @@ -78,7 +78,6 @@ export class GameScene extends BaseScene { } onSoldierAdded(soldier: SoldierState, ownerPlayer: PlayerState) { - console.log("Adding a soldier ", soldier.id); const spearmen = new Spearman( this, soldier.id, @@ -89,6 +88,10 @@ export class GameScene extends BaseScene { [ownerPlayer.colorR, ownerPlayer.colorG, ownerPlayer.colorB], ownerPlayer.id ); + spearmen.setData("serverPosition", { + x: soldier.currentPositionX, + y: soldier.currentPositionY, + }); const playerSoldiersGameObject = this.data.get( "playerSoldiersGameObject" ) as Map; @@ -101,7 +104,6 @@ export class GameScene extends BaseScene { ); soldiersMap = playerSoldiersGameObject.get(soldier.playerId); } - console.log("Added soldier with id ", soldier.id, soldier); soldiersMap!.set(soldier.id, spearmen); } @@ -182,10 +184,10 @@ export class GameScene extends BaseScene { return; } - phaserSceneObject?.setPosition( - soldierState.currentPositionX, - soldierState.currentPositionY - ); + phaserSceneObject.setData("serverPosition", { + x: soldierState.currentPositionX, + y: soldierState.currentPositionY, + }); } onSoldierHealthUpdate( @@ -219,7 +221,7 @@ export class GameScene extends BaseScene { }); console.log(`map set`, map); const tileset = map.addTilesetImage("groundtiles", "img_groundtiles"); - console.log(`tileset set `, tileset) + console.log(`tileset set `, tileset); const layer = map.createLayer("groundlayer", tileset!); this.data.set("map1", map); @@ -644,5 +646,20 @@ export class GameScene extends BaseScene { update(delta: number) { this.renderDebugPath(); this.controls?.update(delta); + + const soldierPhaserObjs = >( + this.data.get("playerSoldiersGameObject") + ); + for (let [playerId, soldierMap] of soldierPhaserObjs) { + for (let [soldierId, soldierPhaserObj] of soldierMap) { + const serverPos = <{ x: number; y: number }>( + soldierPhaserObj.getData("serverPosition") + ); + soldierPhaserObj.setPosition( + Phaser.Math.Linear(soldierPhaserObj.x, serverPos.x, 0.5), + Phaser.Math.Linear(soldierPhaserObj.y, serverPos.y, 0.5) + ); + } + } } } diff --git a/public/scenes/MenuScene.ts b/public/scenes/MenuScene.ts index 4f564fb..a1c554b 100644 --- a/public/scenes/MenuScene.ts +++ b/public/scenes/MenuScene.ts @@ -34,6 +34,8 @@ export class MenuScene extends BaseScene { } let playBtn = playerForm.getChildByName("btnJoin"); let createSessionBtn = playerForm.getChildByName("btnCreate"); + const tutorialBtn = playerForm.getChildByName("btnTutorial"); + let inputField = playerForm.getChildByName("nameInput"); inputField?.addEventListener("input", (event) => { @@ -48,6 +50,11 @@ export class MenuScene extends BaseScene { } }); + tutorialBtn?.addEventListener("pointerdown", async (event) => { + event.stopPropagation(); + this.scene.start(CONSTANT.SCENES.TUTORIAL); + }); + playerForm.addListener("click"); playerForm.on("click", function (event: any) { event.stopPropagation(); diff --git a/public/scenes/TutorialScene.ts b/public/scenes/TutorialScene.ts new file mode 100644 index 0000000..0b3362e --- /dev/null +++ b/public/scenes/TutorialScene.ts @@ -0,0 +1,160 @@ +import CONSTANT from "../constant"; +import { BaseScene } from "./BaseScene"; +import { NetworkManager } from "../NetworkManager"; +import { addBackgroundImage } from "../helpers/addBackgroundImage"; +const URL = `${window.location.host}`; +export class MenuScene extends BaseScene { + constructor() { + super(CONSTANT.SCENES.TUTORIAL); + console.log(URL); + } + init() { + super.init(); + } + preload() { + this.scene.bringToTop(); + this.load.html("playerForm", "../html/menu-form.html"); + this.load.image("background", "../assets/background.png"); + } + create() { + let networkManager = this.registry.get("networkManager") as NetworkManager; + addBackgroundImage(this, "background"); + this.AddObject(this.add.text(100, 20, "War.IO"), "obj_introText"); + + this.AddObject( + this.add.dom(600, 200).createFromCache("playerForm"), + "obj_playerForm" + ); + + const playerForm = + this.GetObject("obj_playerForm"); + if (!playerForm) { + console.error("player form not found"); + return; + } + let playBtn = playerForm.getChildByName("btnJoin"); + let createSessionBtn = playerForm.getChildByName("btnCreate"); + const tutorialBtn = playerForm.getChildByName("btnTutorial"); + + let inputField = playerForm.getChildByName("nameInput"); + + inputField?.addEventListener("input", (event) => { + var inputName = playerForm.getChildByName("nameInput") as Element & { + value: string; + }; + if (!inputName) return; + if (inputName.value !== "") { + let name = inputName.value.trim().replace(" ", "-"); + networkManager.setPlayerName(name); + this.GetObject("obj_introText")?.setText( + `Welcome: ${name}` + ); + } + }); + + tutorialBtn?.addEventListener("pointerdown", async (event) => { + event.stopPropagation(); + this.scene.start(CONSTANT.SCENES.TUTORIAL); + }); + + playerForm.addListener("click"); + playerForm.on("click", function (event: any) { + event.stopPropagation(); + }); + + playBtn?.addEventListener("pointerdown", async (event) => { + event.stopPropagation(); + this.scene.start(CONSTANT.SCENES.SESSIONBROWSER); + }); + + createSessionBtn?.addEventListener("pointerdown", async (event) => { + event.stopPropagation(); + await this.onCreateSessionClick(); + }); + + this.AddSceneEvent("shutdown", (data: any) => { + console.log("shutdown ", data.config.key); + this.Destroy(); + }); + + this.AddSceneEvent("destroy", () => { + this.input.removeAllListeners(); + this.events.removeAllListeners(); + }); + } + + async onPlayButtonClick(buttonParentForm: Phaser.GameObjects.DOMElement) { + const playerForm = buttonParentForm; + const networkManager = this.registry.get( + "networkManager" + ) as NetworkManager; + var inputName = playerForm.getChildByName("nameInput") as Element & { + value: string; + }; + if (inputName?.nodeValue !== "") { + let name = inputName?.value.trim().replace(" ", "-"); + networkManager.setPlayerName(name || ""); + } + try { + let rooms = await networkManager.getAvailableSession(); + if (!rooms || rooms.length === 0) { + return; + } + let sessionId = rooms[0].roomId; + const onConnectHandler = () => { + playerForm.setVisible(false); + playerForm.destroy(); + this.scene.start(CONSTANT.SCENES.SESSIONLOBBY, { + sessionId, + }); + }; + const onDisconnectHandler = () => { + console.log("SocketDisconnect: Launching Menu Scene"); + this.scene.start(CONSTANT.SCENES.MENU); + }; + //join session + await ( + this.registry.get("networkManager") as NetworkManager + ).connectGameServer(`${URL}/${sessionId}`); + } catch (err) { + console.error(err); + } + } + + async onJoinSessionClick() { + try { + const networkManager = this.registry.get( + "networkManager" + ) as NetworkManager; + if (!networkManager) { + throw new Error("NetworkManager is not defined"); + } + + const playerName = (this.GetObject( + "obj_playerForm" + )?.getChildByName("nameInput") as Element & { value: string })!.value; + const sessions = await networkManager.getAvailableSession(); + console.log("available sessions ", sessions); + } catch (error) {} + } + async onCreateSessionClick() { + try { + const networkManager = this.registry.get( + "networkManager" + ) as NetworkManager; + if (!networkManager) { + throw new Error("NetworkManager is not defined"); + } + + const playerName = (this.GetObject( + "obj_playerForm" + )?.getChildByName("nameInput") as Element & { value: string })!.value; + await networkManager?.hostAndJoinSession(`${playerName}`); + + console.log("[client id] : ", networkManager?.getClientId()); + this.scene.start(CONSTANT.SCENES.SESSIONLOBBY); + } catch (error) { + console.log(error); + } + } +}