Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"crates/games/breakpoint-golf",
"crates/games/breakpoint-platformer",
"crates/games/breakpoint-lasertag",
"crates/games/breakpoint-tron",
"crates/adapters/breakpoint-github",
]

Expand Down
4 changes: 3 additions & 1 deletion crates/breakpoint-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ authors.workspace = true
crate-type = ["cdylib", "rlib"]

[features]
default = ["golf", "platformer", "lasertag"]
default = ["golf", "platformer", "lasertag", "tron"]
golf = ["dep:breakpoint-golf"]
platformer = ["dep:breakpoint-platformer"]
lasertag = ["dep:breakpoint-lasertag"]
tron = ["dep:breakpoint-tron"]

[dependencies]
breakpoint-core = { path = "../breakpoint-core" }
breakpoint-golf = { path = "../games/breakpoint-golf", optional = true }
breakpoint-platformer = { path = "../games/breakpoint-platformer", optional = true }
breakpoint-lasertag = { path = "../games/breakpoint-lasertag", optional = true }
breakpoint-tron = { path = "../games/breakpoint-tron", optional = true }
serde.workspace = true
serde_json.workspace = true
rmp-serde.workspace = true
Expand Down
27 changes: 27 additions & 0 deletions crates/breakpoint-client/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,25 @@ impl App {
GameId::LaserTag => {
self.camera.set_mode(CameraMode::LaserTagFixed);
},
#[cfg(feature = "tron")]
GameId::Tron => {
if let Some(ref role) = self.network_role
&& let Some(s) = read_game_state::<breakpoint_tron::TronState>(active)
&& let Some(c) = s.players.get(&role.local_player_id)
&& c.alive
{
let dir = match c.direction {
breakpoint_tron::Direction::North => [0.0, -1.0],
breakpoint_tron::Direction::South => [0.0, 1.0],
breakpoint_tron::Direction::East => [1.0, 0.0],
breakpoint_tron::Direction::West => [-1.0, 0.0],
};
self.camera.set_mode(CameraMode::TronFollow {
cycle_pos: glam::Vec3::new(c.x, 0.0, c.z),
direction: dir,
});
}
},
#[allow(unreachable_patterns)]
_ => {},
}
Expand Down Expand Up @@ -590,6 +609,10 @@ impl App {
&self.ws,
);
},
#[cfg(feature = "tron")]
GameId::Tron => {
crate::game::tron_input::process_tron_input(&self.input, active, role, &self.ws);
},
#[allow(unreachable_patterns)]
_ => {},
}
Expand Down Expand Up @@ -632,6 +655,10 @@ impl App {
dt,
);
},
#[cfg(feature = "tron")]
GameId::Tron => {
crate::game::tron_render::sync_tron_scene(&mut self.scene, active, &self.theme, dt);
},
#[allow(unreachable_patterns)]
_ => {},
}
Expand Down
35 changes: 35 additions & 0 deletions crates/breakpoint-client/src/camera_gl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ pub enum CameraMode {
PlatformerFollow { player_pos: Vec2 },
/// Laser tag: fixed top-down view.
LaserTagFixed,
/// Tron: third-person chase camera behind the player's cycle.
TronFollow {
cycle_pos: Vec3,
direction: [f32; 2],
},
/// Overview of the course (golf fallback).
GolfOverview {
center_x: f32,
Expand Down Expand Up @@ -106,6 +111,36 @@ impl Camera {
self.target = Vec3::new(25.0, 0.0, 25.0);
self.up = Vec3::Z;
},
CameraMode::TronFollow {
cycle_pos,
direction,
} => {
// Chase camera behind the cycle
let cam_height = 18.0;
let cam_behind = 25.0;
let look_ahead = 15.0;

let dir_x = direction[0];
let dir_z = direction[1];

// Camera behind the cycle
let target_pos = Vec3::new(
cycle_pos.x - dir_x * cam_behind,
cam_height,
cycle_pos.z - dir_z * cam_behind,
);
// Look ahead of the cycle
let look_at = Vec3::new(
cycle_pos.x + dir_x * look_ahead,
0.0,
cycle_pos.z + dir_z * look_ahead,
);

self.position = self.position.lerp(target_pos, lerp_factor);
self.target = self.target.lerp(look_at, lerp_factor);
self.up = Vec3::Y;
self.far = 600.0;
},
CameraMode::None => {},
}
}
Expand Down
9 changes: 9 additions & 0 deletions crates/breakpoint-client/src/game/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ pub mod lasertag_render;
pub mod platformer_input;
#[cfg(feature = "platformer")]
pub mod platformer_render;
#[cfg(feature = "tron")]
pub mod tron_input;
#[cfg(feature = "tron")]
pub mod tron_render;

use std::collections::HashMap;

Expand Down Expand Up @@ -53,6 +57,11 @@ pub fn create_registry() -> GameRegistry {
registry.register(GameId::LaserTag, || {
Box::new(breakpoint_lasertag::LaserTagArena::new())
});
#[cfg(feature = "tron")]
registry.register(
GameId::Tron,
|| Box::new(breakpoint_tron::TronCycles::new()),
);
registry
}

Expand Down
28 changes: 28 additions & 0 deletions crates/breakpoint-client/src/game/tron_input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use breakpoint_tron::{TronInput, TurnDirection};

use crate::app::{ActiveGame, NetworkRole};
use crate::game::send_player_input;
use crate::input::InputState;
use crate::net_client::WsClient;

/// Process tron input: A/D or Left/Right for turning, Space for brake.
pub fn process_tron_input(
input: &InputState,
active: &mut ActiveGame,
role: &NetworkRole,
ws: &WsClient,
) {
let turn = if input.is_key_just_pressed("KeyA") || input.is_key_just_pressed("ArrowLeft") {
TurnDirection::Left
} else if input.is_key_just_pressed("KeyD") || input.is_key_just_pressed("ArrowRight") {
TurnDirection::Right
} else {
TurnDirection::None
};

let brake =
input.is_key_down("Space") || input.is_key_down("KeyS") || input.is_key_down("ArrowDown");

let tron_input = TronInput { turn, brake };
send_player_input(&tron_input, active, role, ws);
}
Loading