UNPKG

colyseus.js

Version:

Colyseus Multiplayer SDK for JavaScript/TypeScript

207 lines (161 loc) 7.26 kB
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <style> body { font-family: Tahoma, Geneva, sans-serif; } </style> <script src="colyseus.js"></script> <script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.min.js"></script> </head> <body> <script type="text/javascript"> class Part4Scene extends Phaser.Scene { constructor() { super({ key: "part4" }); this.playerEntities = {}; this.inputPayload = { left: false, right: false, up: false, down: false, tick: undefined, }; this.elapsedTime = 0; this.fixedTimeStep = 1000 / 60; this.currentTick = 0; } preload() { // update menu background color this.cameras.main.setBackgroundColor(0x000000); // preload demo assets // this.load.image('ship_0001', 'assets/ship_0001.png'); this.load.image('ship_0001', 'https://cdn.glitch.global/3e033dcd-d5be-4db4-99e8-086ae90969ec/ship_0001.png?v=1649945243288'); } async create() { this.cursorKeys = this.input.keyboard.createCursorKeys(); this.debugFPS = this.add.text(4, 4, "", { color: "#ff0000", }); // connect with the room await this.connect(); this.room.state.players.onAdd((player, sessionId) => { const entity = this.physics.add.image(player.x, player.y, 'ship_0001'); this.playerEntities[sessionId] = entity; // is current player if (sessionId === this.room.sessionId) { this.currentPlayer = entity; this.localRef = this.add.rectangle(0, 0, entity.width, entity.height); this.localRef.setStrokeStyle(1, 0x00ff00); this.remoteRef = this.add.rectangle(0, 0, entity.width, entity.height); this.remoteRef.setStrokeStyle(1, 0xff0000); player.onChange(() => { this.remoteRef.x = player.x; this.remoteRef.y = player.y; }); } else { // listening for server updates player.onChange(() => { // // we're going to LERP the positions during the render loop. // entity.setData('serverX', player.x); entity.setData('serverY', player.y); }); } }); // remove local reference when entity is removed from the server this.room.state.players.onRemove((player, sessionId) => { const entity = this.playerEntities[sessionId]; if (entity) { entity.destroy(); delete this.playerEntities[sessionId] } }); // this.cameras.main.startFollow(this.ship, true, 0.2, 0.2); // this.cameras.main.setZoom(1); this.cameras.main.setBounds(0, 0, 800, 600); } async connect() { // add connection status text const connectionStatusText = this.add .text(0, 0, "Trying to connect with the server...") .setStyle({ color: "#ff0000" }) .setPadding(4) const client = new Colyseus.Client("ws://localhost:2567"); try { this.room = await client.joinOrCreate("my_room", {}); // connection successful! connectionStatusText.destroy(); } catch (e) { // couldn't connect connectionStatusText.text = "Could not connect with the server."; } } update(time, delta) { // skip loop if not connected yet. if (!this.currentPlayer) { return; } this.elapsedTime += delta; while (this.elapsedTime >= this.fixedTimeStep) { this.elapsedTime -= this.fixedTimeStep; this.fixedTick(time, this.fixedTimeStep); } this.debugFPS.text = `Frame rate: ${this.game.loop.actualFps}`; } fixedTick(time, delta) { this.currentTick++; // const currentPlayerRemote = this.room.state.players.get(this.room.sessionId); // const ticksBehind = this.currentTick - currentPlayerRemote.tick; // console.log({ ticksBehind }); const velocity = 2; this.inputPayload.left = this.cursorKeys.left.isDown; this.inputPayload.right = this.cursorKeys.right.isDown; this.inputPayload.up = this.cursorKeys.up.isDown; this.inputPayload.down = this.cursorKeys.down.isDown; this.inputPayload.tick = this.currentTick; this.room.send(0, this.inputPayload); if (this.inputPayload.left) { this.currentPlayer.x -= velocity; } else if (this.inputPayload.right) { this.currentPlayer.x += velocity; } if (this.inputPayload.up) { this.currentPlayer.y -= velocity; } else if (this.inputPayload.down) { this.currentPlayer.y += velocity; } this.localRef.x = this.currentPlayer.x; this.localRef.y = this.currentPlayer.y; for (let sessionId in this.playerEntities) { // interpolate all player entities // (except the current player) if (sessionId === this.room.sessionId) { continue; } const entity = this.playerEntities[sessionId]; const { serverX, serverY } = entity.data.values; entity.x = Phaser.Math.Linear(entity.x, serverX, 0.2); entity.y = Phaser.Math.Linear(entity.y, serverY, 0.2); } } } const config = { type: Phaser.AUTO, fps: { target: 60, forceSetTimeOut: true, smoothStep: false, }, width: 800, height: 600, // height: 200, backgroundColor: '#b6d53c', parent: 'phaser-example', physics: { default: "arcade" }, pixelArt: true, scene: [Part4Scene], }; const game = new Phaser.Game(config); </script> </body> </html>