From 207bef297c4ea3d965890dab68f79f4d4267a9d4 Mon Sep 17 00:00:00 2001 From: nabijaczleweli Date: Mon, 25 Apr 2016 18:47:54 +0200 Subject: [PATCH 1/4] Use per-second instead of per-tick times --- client/src/game.ts | 9 +++++---- server/src/server/gamestate.rs | 13 +++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/client/src/game.ts b/client/src/game.ts index 89ac659..5f731c8 100644 --- a/client/src/game.ts +++ b/client/src/game.ts @@ -6,7 +6,8 @@ import {GameScreen} from './gamescreen'; import {GameSocket, MessageData, Entity} from './protocol'; class Game { - static tickPeriod: number = 1.0 / 60; + static TPS: number = 60; + static tickPeriod: number = 1.0 / Game.TPS; transport: GameWSTransport = null; socket: GameSocket = null; @@ -66,7 +67,7 @@ class Game { var maxDistanceY = this.canvas.height - this.welcomeMessage.size; this.game.state.alivePlayers.forEach((player: Entity): void => { if (player.direction != null) { - var move = player.direction.clone().multiplyScalar(this.welcomeMessage.speed); + var move = player.direction.clone().multiplyScalar(this.welcomeMessage.speed / Game.TPS); var newpos = player.position.clone().add(move); if (!this.game.state.alivePlayers.some((cmpPlayer: Entity) => { return cmpPlayer.id != player.id && cmpPlayer.distanceSq(newpos) <= minPlayerDistanceSq; @@ -81,8 +82,8 @@ class Game { updateBulletStates(): void { this.game.state.aliveBullets.forEach((bullet: Entity): void => { if (bullet.direction != null) { - bullet.position.x += bullet.direction.x * this.welcomeMessage.bulletSpeed; - bullet.position.y += bullet.direction.y * this.welcomeMessage.bulletSpeed; + bullet.position.x += bullet.direction.x * this.welcomeMessage.bulletSpeed / Game.TPS; + bullet.position.y += bullet.direction.y * this.welcomeMessage.bulletSpeed / Game.TPS; } }); } diff --git a/server/src/server/gamestate.rs b/server/src/server/gamestate.rs index 5d10998..ffa003e 100644 --- a/server/src/server/gamestate.rs +++ b/server/src/server/gamestate.rs @@ -11,13 +11,14 @@ use rand::{thread_rng, Rng}; use self::super::Client; use self::super::WebSocketEvent; +const TPS: u32 = 60; static BULLET_RADIUS: f32 = 5.0; static PLAYER_RADIUS: f32 = 10.0; -static BULLET_SPEED: f32 = 3.0; -static PLAYER_SPEED: f32 = 2.0; +static BULLET_SPEED: f32 = 3.0 * TPS as f32; +static PLAYER_SPEED: f32 = 2.0 * TPS as f32; static MAP_HEIGHT: f32 = 500.0; static MAP_WIDTH: f32 = 500.0; -static TICKS_BETWEEN_FULL_UPDATES: u32 = 600; // 10s @ 60FPS +static TICKS_BETWEEN_FULL_UPDATES: u32 = 10 * TPS; /// The `GameState` contains the whole state of the game. /// @@ -116,8 +117,8 @@ impl GameState { let mut destroyed_players = Vec::new(); for (_, bullet) in &mut self.bullets { - bullet.bullet.x += bullet.bullet.move_x.unwrap_or(0.0) * BULLET_SPEED; - bullet.bullet.y += bullet.bullet.move_y.unwrap_or(0.0) * BULLET_SPEED; + bullet.bullet.x += bullet.bullet.move_x.unwrap_or(0.0) * BULLET_SPEED / TPS as f32; + bullet.bullet.y += bullet.bullet.move_y.unwrap_or(0.0) * BULLET_SPEED / TPS as f32; if bullet.bullet.x < 0.0 || bullet.bullet.x > MAP_WIDTH || bullet.bullet.y < 0.0 || bullet.bullet.y > MAP_HEIGHT { @@ -364,7 +365,7 @@ impl GameState { /// /// Returns whether the player crashed into a wall during movement. fn move_player(pos: &mut f32, mov: Option) -> bool { - let new_pos = *pos + mov.unwrap_or(0.0) * PLAYER_SPEED; + let new_pos = *pos + mov.unwrap_or(0.0) * PLAYER_SPEED / TPS as f32; *pos = new_pos.max(PLAYER_RADIUS) .min(MAP_WIDTH - PLAYER_RADIUS); From cfd0295ef2255f59e24cdcc995def8976790b4cd Mon Sep 17 00:00:00 2001 From: nabijaczleweli Date: Mon, 25 Apr 2016 21:20:50 +0200 Subject: [PATCH 2/4] Also use TPS const in server --- server/src/server/gamestate.rs | 1 + server/src/server/mod.rs | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/server/gamestate.rs b/server/src/server/gamestate.rs index ffa003e..1a09af0 100644 --- a/server/src/server/gamestate.rs +++ b/server/src/server/gamestate.rs @@ -11,6 +11,7 @@ use rand::{thread_rng, Rng}; use self::super::Client; use self::super::WebSocketEvent; +// TODO: substitute when doing config, see `mod.rs` const TPS: u32 = 60; static BULLET_RADIUS: f32 = 5.0; static PLAYER_RADIUS: f32 = 10.0; diff --git a/server/src/server/mod.rs b/server/src/server/mod.rs index 68368b8..66f6860 100644 --- a/server/src/server/mod.rs +++ b/server/src/server/mod.rs @@ -27,6 +27,9 @@ use std::time::Duration; pub use self::events::*; pub use self::gamestate::GameState; +// TODO: substitute when doing config, see `mod.rs` +const TPS: f32 = 60.0; + /// The main listening loop for the server. pub fn listen(host: &str, port: u16, @@ -61,11 +64,11 @@ pub fn listen(host: &str, /// Spawns the main game loop in a separate thread and returns the handle therefor. Non-blocking. /// -/// The general idea for the game loop is to update the game state every 16 milliseconds (60 FPS), processing messages along the way. +/// The general idea for the game loop is to update the game state every 1/TPS milliseconds, processing messages along the way. pub fn start_game_loop(game_messages: mpsc::Receiver, cont: &Arc>) -> thread::JoinHandle<()> { - static ITER_LENGTH: u64 = 16 * 1000000; // 16 milliseconds + static ITER_LENGTH: u64 = (1.0 / TPS * 1000.0) as u64 * 1000000; // 1/TPS milliseconds let cont = cont.clone(); thread::spawn(move || { From 25605b53d2c0a9f05fe03ba54c72135642547469 Mon Sep 17 00:00:00 2001 From: nabijaczleweli Date: Mon, 25 Apr 2016 21:35:32 +0200 Subject: [PATCH 3/4] Wait for another frame if this one was too quick, I guess --- client/src/game.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/game.ts b/client/src/game.ts index 5f731c8..2211882 100644 --- a/client/src/game.ts +++ b/client/src/game.ts @@ -259,7 +259,7 @@ class Game { context.restore(); - window.requestAnimationFrame(this.frame); + setTimeout((): void => { window.requestAnimationFrame(this.frame); }, Game.tickPeriod * 1000 - delta); } // From dc7bdf14050a99fa4dcec84b3ee9e48fee965521 Mon Sep 17 00:00:00 2001 From: nabijaczleweli Date: Mon, 2 May 2016 14:26:52 +0200 Subject: [PATCH 4/4] I cannot into copypasta --- server/src/server/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/server/mod.rs b/server/src/server/mod.rs index 66f6860..5160b7d 100644 --- a/server/src/server/mod.rs +++ b/server/src/server/mod.rs @@ -27,7 +27,7 @@ use std::time::Duration; pub use self::events::*; pub use self::gamestate::GameState; -// TODO: substitute when doing config, see `mod.rs` +// TODO: substitute when doing config, see `gamestate.rs` const TPS: f32 = 60.0; /// The main listening loop for the server.