Can't move babylon.js
-
Hi!
I've been experimenting with the babylon.js boilerplate (thanks @endel for the update!)
I'm trying to have the playing move locally, send their position to the server, which sends it out to the other clients. But for some reason, I can't move with the current code. wasd to move and mouse locks to look. you control the free camera.
It comes down to this error:
Here is my code:
index.ts:import "./index.css"; import * as BABYLON from "babylonjs"; import Keycode from "keycode.js"; import { client } from "./game/network"; // Re-using server-side types for networking // This is optional, but highly recommended import { StateHandler } from "../../server/src/rooms/StateHandler"; import { PressedKeys } from "../../server/src/entities/Player"; import { CamPos } from "../../server/src/entities/Player"; const canvas = document.getElementById('game') as HTMLCanvasElement; const engine = new BABYLON.Engine(canvas, true); // This creates a basic Babylon Scene object (non-mesh) var scene = new BABYLON.Scene(engine); // This creates and positions a free camera (non-mesh) var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene); camera.keysUp = [87]; camera.keysDown = [83]; camera.keysLeft = [65]; camera.keysRight = [68]; // This targets the camera to scene origin camera.setTarget(BABYLON.Vector3.Zero()); // This attaches the camera to the canvas camera.attachControl(canvas, true); // This creates a light, aiming 0,1,0 - to the sky (non-mesh) var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); // Default intensity is 1. Let's dim the light a small amount light.intensity = 0.7; // Our built-in 'ground' shape. Params: name, width, depth, subdivs, scene var ground = BABYLON.Mesh.CreateGround("ground1", 6, 6, 2, scene); // Attach default camera mouse navigation // camera.attachControl(canvas); // Colyseus / Join Room const room = client.join<StateHandler>("game"); room.onJoin.add(() => { const playerViews: {[id: string]: BABYLON.Mesh} = {}; room.state.players.onAdd = function(player, key) { if (key != room.sessionId) { playerViews[key] = BABYLON.Mesh.CreateSphere("sphere1", 16, 2, scene); playerViews[key].position.set(player.position.x, player.position.y, player.position.z); } }; room.state.players.onChange = function(player, key) { if (key != room.sessionId) { playerViews[key].position.set(player.position.x, player.position.y, player.position.z); } }; room.state.players.onRemove = function(player, key) { if (key != room.sessionId) { scene.removeMesh(playerViews[key]); delete playerViews[key]; } }; }) room.onStateChange.add((state) => { console.log("New room state:", state.toJSON()); }) const camposition: CamPos = { x: 0, y: 1, z:0 }; scene.registerAfterRender(function() { camposition.x = camera.position.x; camposition.y = camera.position.y; camposition.z = camera.position.z; room.send(['pos', camposition]); }); // Scene render loop engine.runRenderLoop(function() { scene.render(); }); // Keyboard listeners const keyboard: PressedKeys = { x: 0, y: 0 }; window.addEventListener("keydown", function(e) { if (e.which === Keycode.LEFT) { keyboard.x = -1; } else if (e.which === Keycode.RIGHT) { keyboard.x = 1; } else if (e.which === Keycode.UP) { keyboard.y = -1; } else if (e.which === Keycode.DOWN) { keyboard.y = 1; } //room.send(['key', keyboard]); }); window.addEventListener("keyup", function(e) { if (e.which === Keycode.LEFT) { keyboard.x = 0; } else if (e.which === Keycode.RIGHT) { keyboard.x = 0; } else if (e.which === Keycode.UP) { keyboard.y = 0; } else if (e.which === Keycode.DOWN) { keyboard.y = 0; } //room.send(['key', keyboard]); }); // Resize the engine on window resize window.addEventListener('resize', function() { engine.resize(); });
gameroom.ts
import { Room, Client } from "colyseus"; import { StateHandler } from "./StateHandler"; import { Player } from "../entities/Player"; export class GameRoom extends Room<StateHandler> { maxClients = 8; onInit (options) { this.setSimulationInterval(() => this.onUpdate()); this.setState(new StateHandler()); } requestJoin (options) { return true; } onJoin (client) { const player = new Player(); player.name = `Player ${ this.clients.length }`; this.state.players[client.sessionId] = player; } onMessage (client: Client, message: any) { const [event, data] = message; const player: Player = this.state.players[client.sessionId]; if (event === "pos") { player.camPos = data; } } onUpdate () { for (const sessionId in this.state.players) { const player: Player = this.state.players[sessionId]; player.position.x = player.camPos.x; player.position.y = player.camPos.y; player.position.z = player.camPos.z; console.log(player.camPos.x + " " + player.camPos.y + " " + player.camPos.z); } } onLeave (client: Client) { delete this.state.players[client.sessionId]; } onDispose () { } }
player.ts
import { Schema, type } from "@colyseus/schema"; export interface PressedKeys { x: number; y: number; } export interface CamPos { x: number; y: number; z: number; } export class Position extends Schema { @type("number") x: number = 0; @type("number") y: number = 0; @type("number") z: number = 0; } export class Player extends Schema { @type("string") name: string; @type(Position) position = new Position(); pressedKeys: PressedKeys = { x: 0, y: 0 }; camPos: CamPos = { x: 0, y: 1, z: 0 }; constructor () { super(); } }
thanks for any help, Givo.
Or, if it helps, here is a zip file of the whole project: https://drive.google.com/file/d/1pKI-eLp6JQhMwCfH6Qb1XWlnK-2EsKbU/view?usp=sharing
-
I was able to fix it! Babylon.js was loading a lot faster than colyseus, so using the
scene.registerAfterRender(function() {}
was calling room.send before the client had even connected. I now use the pointer lockcanvas.click
function to start the position updates!demo at https://boilerplate-fps-works.herokuapp.com/
WASD moving, mouse look