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