Complete game

This commit is contained in:
2026-05-27 14:04:08 +04:00
commit 9e08f3eb98
72 changed files with 6024 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

5518
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

16
Cargo.toml Normal file
View File

@@ -0,0 +1,16 @@
[package]
name = "road_race"
version = "0.1.0"
edition = "2024"
[dependencies]
rusty_engine = "7.0.0"
rand = "0.8"
[profile.dev]
opt-level = 3
debug = false
debug-assertions = false
overflow-checks = false
incremental = false
codegen-units = 16

1
assets/audio/README.md Normal file
View File

@@ -0,0 +1 @@
You may add your own sound effects to your own local copy of this directory. Please see the `audio` module documentation for details.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
The music files "Arcade Fantasy.ogg", "Classy 8-Bit.ogg", "Mysterious Magic.ogg", and "Whimsical Popsicle.ogg" have been licensed for non-attribution use in Rusty Engine itself by a commercial license agreement between the author of Rusty Engine and the creator of the music, Eric Matyas. However, any distribution of these music files in any project created using Rusty Engine must include attribution information as per the directions at https://soundimage.org/attribution-info/ or be independently licensed.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
Assets adapted from Kenney [Audio Packs] under the [CC0 1.0 Universal] license.
[CC0 1.0 Universal]: https://creativecommons.org/publicdomain/zero/1.0/
[Audio Packs]: https://www.kenney.nl/assets?q=audio

BIN
assets/audio/sfx/click.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/audio/sfx/tones1.ogg Normal file

Binary file not shown.

BIN
assets/audio/sfx/tones2.ogg Normal file

Binary file not shown.

BIN
assets/font/FiraMono-Medium.ttf Executable file

Binary file not shown.

BIN
assets/font/FiraSans-Bold.ttf Executable file

Binary file not shown.

View File

@@ -0,0 +1,4 @@
Assets adapted from Kenney [Racing Pack] under the [CC0 1.0 Universal] license.
[CC0 1.0 Universal]: https://creativecommons.org/publicdomain/zero/1.0/
[Racing Pack]: https://kenney.nl/assets/racing-pack

View File

@@ -0,0 +1,18 @@
Poly([
(28, 0),
(25.868626, 10.715136),
(19.79899, 19.79899),
(10.715136, 25.868626),
(0, 28),
(-10.715136, 25.868626),
(-19.79899, 19.79899),
(-25.868626, 10.715136),
(-28, 0),
(-25.868626, -10.715136),
(-19.79899, -19.79899),
(-10.715136, -25.868626),
(0, -28),
(10.715136, -25.868626),
(19.79899, -19.79899),
(25.868626, -10.715136),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

View File

@@ -0,0 +1,18 @@
Poly([
(28, 0),
(25.868626, 10.715136),
(19.79899, 19.79899),
(10.715136, 25.868626),
(0, 28),
(-10.715136, 25.868626),
(-19.79899, 19.79899),
(-25.868626, 10.715136),
(-28, 0),
(-25.868626, -10.715136),
(-19.79899, -19.79899),
(-10.715136, -25.868626),
(0, -28),
(10.715136, -25.868626),
(19.79899, -19.79899),
(25.868626, -10.715136),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

View File

@@ -0,0 +1,10 @@
Poly([
(-105, -29),
(-105, 28),
(-102, 31),
(102, 31),
(105, 28),
(105, -29),
(103, -31),
(-103, -31),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

View File

@@ -0,0 +1,10 @@
Poly([
(-105, -29),
(-105, 28),
(-102, 31),
(102, 31),
(105, 28),
(105, -29),
(103, -31),
(-103, -31),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

View File

@@ -0,0 +1,19 @@
Poly([
(-45, 33.5),
(38.5, 33.5),
(50, 29.5),
(57, 22.5),
(59, 18),
(59, -13),
(57, -23),
(51, -29),
(45, -32),
(37, -34),
(-43, -34),
(-50, -32),
(-57, -26.5),
(-60, -19),
(-60, 19),
(-58, 24.5),
(-52, 30.5),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,19 @@
Poly([
(-45, 33.5),
(38.5, 33.5),
(50, 29.5),
(57, 22.5),
(59, 18),
(59, -13),
(57, -23),
(51, -29),
(45, -32),
(37, -34),
(-43, -34),
(-50, -32),
(-57, -26.5),
(-60, -19),
(-60, 19),
(-58, 24.5),
(-52, 30.5),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,19 @@
Poly([
(-45, 33.5),
(38.5, 33.5),
(50, 29.5),
(57, 22.5),
(59, 18),
(59, -13),
(57, -23),
(51, -29),
(45, -32),
(37, -34),
(-43, -34),
(-50, -32),
(-57, -26.5),
(-60, -19),
(-60, 19),
(-58, 24.5),
(-52, 30.5),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,19 @@
Poly([
(-45, 33.5),
(38.5, 33.5),
(50, 29.5),
(57, 22.5),
(59, 18),
(59, -13),
(57, -23),
(51, -29),
(45, -32),
(37, -34),
(-43, -34),
(-50, -32),
(-57, -26.5),
(-60, -19),
(-60, 19),
(-58, 24.5),
(-52, 30.5),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,19 @@
Poly([
(-45, 33.5),
(38.5, 33.5),
(50, 29.5),
(57, 22.5),
(59, 18),
(59, -13),
(57, -23),
(51, -29),
(45, -32),
(37, -34),
(-43, -34),
(-50, -32),
(-57, -26.5),
(-60, -19),
(-60, 19),
(-58, 24.5),
(-52, 30.5),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,10 @@
Poly([
(-22, 16),
(-16, 22),
(16, 22),
(22, 16),
(22, -16),
(16, -22),
(-16, -22),
(-22, -16),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,4 @@
Assets adapted from Kenney [Rolling Ball Assets] pack under the [CC0 1.0 Universal] license.
[CC0 1.0 Universal]: https://creativecommons.org/publicdomain/zero/1.0/
[Rolling Ball Assets]: https://kenney.nl/assets/rolling-ball-assets

View File

@@ -0,0 +1,18 @@
Poly([
(16.5, 0),
(15.244012, 6.3142767),
(11.667262, 11.667262),
(6.3142767, 15.244012),
(0, 16.5),
(-6.3142767, 15.244012),
(-11.667262, 11.667262),
(-15.244012, 6.3142767),
(-16.5, 0),
(-15.244012, -6.3142767),
(-11.667262, -11.667262),
(-6.3142767, -15.244012),
(0, -16.5),
(6.3142767, -15.244012),
(11.667262, -11.667262),
(15.244012, -6.3142767),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

View File

@@ -0,0 +1,18 @@
Poly([
(16.5, 0),
(15.244012, 6.3142767),
(11.667262, 11.667262),
(6.3142767, 15.244012),
(0, 16.5),
(-6.3142767, 15.244012),
(-11.667262, 11.667262),
(-15.244012, 6.3142767),
(-16.5, 0),
(-15.244012, -6.3142767),
(-11.667262, -11.667262),
(-6.3142767, -15.244012),
(0, -16.5),
(6.3142767, -15.244012),
(11.667262, -11.667262),
(15.244012, -6.3142767),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

View File

@@ -0,0 +1,18 @@
Poly([
(16.5, 0),
(15.244012, 6.3142767),
(11.667262, 11.667262),
(6.3142767, 15.244012),
(0, 16.5),
(-6.3142767, 15.244012),
(-11.667262, 11.667262),
(-15.244012, 6.3142767),
(-16.5, 0),
(-15.244012, -6.3142767),
(-11.667262, -11.667262),
(-6.3142767, -15.244012),
(0, -16.5),
(6.3142767, -15.244012),
(11.667262, -11.667262),
(15.244012, -6.3142767),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

View File

@@ -0,0 +1,18 @@
Poly([
(16.5, 0),
(15.244012, 6.3142767),
(11.667262, 11.667262),
(6.3142767, 15.244012),
(0, 16.5),
(-6.3142767, 15.244012),
(-11.667262, 11.667262),
(-15.244012, 6.3142767),
(-16.5, 0),
(-15.244012, -6.3142767),
(-11.667262, -11.667262),
(-6.3142767, -15.244012),
(0, -16.5),
(6.3142767, -15.244012),
(11.667262, -11.667262),
(15.244012, -6.3142767),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

View File

@@ -0,0 +1,10 @@
Poly([
(-64, 59),
(-59, 64),
(-49, 64),
(64, -49),
(64, -59),
(59, -64),
(-59, -64),
(-64, -59),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

View File

@@ -0,0 +1,10 @@
Poly([
(-64, 11),
(-59, 16),
(59, 16),
(64, 11),
(64, -11),
(59, -16),
(-59, -16),
(-64, -11),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,10 @@
Poly([
(-16, 11),
(-11, 16),
(11, 16),
(16, 11),
(16, -11),
(11, -16),
(-11, -16),
(-16, -11),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

View File

@@ -0,0 +1,10 @@
Poly([
(-32, 27),
(-27, 32),
(27, 32),
(32, 27),
(32, -27),
(27, -32),
(-27, -32),
(-32, -27),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

View File

@@ -0,0 +1,18 @@
Poly([
(18.5, 0),
(17.09177, 7.0796432),
(13.081475, 13.081475),
(7.0796432, 17.09177),
(0, 18.5),
(-7.0796432, 17.09177),
(-13.081475, 13.081475),
(-17.09177, 7.0796432),
(-18.5, 0),
(-17.09177, -7.0796432),
(-13.081475, -13.081475),
(-7.0796432, -17.09177),
(0, -18.5),
(7.0796432, -17.09177),
(13.081475, -13.081475),
(17.09177, -7.0796432),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B

View File

@@ -0,0 +1,18 @@
Poly([
(24.5, 0),
(22.635048, 9.375744),
(17.324116, 17.324116),
(9.375744, 22.635048),
(0, 24.5),
(-9.375744, 22.635048),
(-17.324116, 17.324116),
(-22.635048, 9.375744),
(-24.5, 0),
(-22.635048, -9.375744),
(-17.324116, -17.324116),
(-9.375744, -22.635048),
(0, -24.5),
(9.375744, -22.635048),
(17.324116, -17.324116),
(22.635048, -9.375744),
])

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 B

166
src/main.rs Normal file
View File

@@ -0,0 +1,166 @@
use rand::prelude::*;
use rusty_engine::prelude::*;
const PLAYER_SPEED: f32 = 400.0;
const ROAD_SPEED: f32 = 600.0;
#[derive(Resource)]
struct GameState {
health_amount_p1: u8,
health_amount_p2: u8,
lost: bool,
}
impl Default for GameState {
fn default() -> Self {
Self {
health_amount_p1: 5,
health_amount_p2: 5,
lost: false,
}
}
}
fn main() {
let mut game = Game::new();
game.audio_manager
.play_music(MusicPreset::WhimsicalPopsicle, 0.2);
let health_message_p1 = game.add_text("health_message_p1", "Health P1: 5");
health_message_p1.translation = Vec2::new(-550.0, 320.0);
let health_message_p2 = game.add_text("health_message_p2", "Health P2: 5");
health_message_p2.translation = Vec2::new(-550.0, 280.0);
let player1 = game.add_sprite("player1", SpritePreset::RacingCarBlue);
player1.translation.x = -500.0;
player1.translation.y = 50.0;
player1.layer = 10.0;
player1.collision = true;
let player2 = game.add_sprite("player2", SpritePreset::RacingCarRed);
player2.translation.x = -500.0;
player2.translation.y = -50.0;
player2.layer = 10.0;
player2.collision = true;
for i in 0..10 {
let roadline = game.add_sprite(format!("roadline{}", i), SpritePreset::RacingBarrierWhite);
roadline.scale = 0.1;
roadline.translation.x = -350.0 + 150.0 * i as f32;
}
let obstacle_presets = [
SpritePreset::RacingBarrelBlue,
SpritePreset::RacingBarrelRed,
SpritePreset::RacingConeStraight,
SpritePreset::RacingBarrierRed,
SpritePreset::RacingBarrierWhite,
];
for (i, preset) in obstacle_presets.into_iter().enumerate() {
let obstacle = game.add_sprite(format!("obstacle{}", i), preset);
obstacle.layer = 5.0;
obstacle.collision = true;
obstacle.translation.x = rand::thread_rng().gen_range(800.0..1600.0);
obstacle.translation.y = rand::thread_rng().gen_range(-300.0..300.0);
}
game.add_logic(game_logic);
game.run(GameState::default());
}
fn game_logic(engine: &mut Engine, game_state: &mut GameState) {
if game_state.lost {
return;
}
let mut direction_player1: f32 = 0.0;
if engine.keyboard_state.pressed_any(&[KeyCode::ArrowUp]) {
direction_player1 += 1.0
}
if engine.keyboard_state.pressed_any(&[KeyCode::ArrowDown]) {
direction_player1 -= 1.0
}
let player1 = engine.sprites.get_mut("player1").unwrap();
player1.translation.y += direction_player1 * PLAYER_SPEED * engine.delta_f32;
player1.rotation = direction_player1 * 0.15;
if player1.translation.y.abs() > 360.0 {
game_state.health_amount_p1 = 0;
}
let _ = player1;
let mut direction_player2: f32 = 0.0;
if engine.keyboard_state.pressed_any(&[KeyCode::KeyW]) {
direction_player2 += 1.0
}
if engine.keyboard_state.pressed_any(&[KeyCode::KeyS]) {
direction_player2 -= 1.0
}
let player2 = engine.sprites.get_mut("player2").unwrap();
player2.translation.y += direction_player2 * PLAYER_SPEED * engine.delta_f32;
player2.rotation = direction_player2 * 0.15;
if player2.translation.y.abs() > 360.0 {
game_state.health_amount_p2 = 0;
}
let _ = player2;
for sprite in engine.sprites.values_mut() {
if sprite.label.starts_with("roadline") {
sprite.translation.x -=
(ROAD_SPEED * engine.delta_f32) + (engine.time_since_startup_f64 as f32 / 10.0);
if sprite.translation.x < -675.0 {
sprite.translation.x += 1500.0;
}
}
if sprite.label.starts_with("obstacle") {
sprite.translation.x -=
(ROAD_SPEED * engine.delta_f32) + (engine.time_since_startup_f64 as f32 / 10.0);
if sprite.translation.x < -800.0 {
sprite.translation.x = rand::thread_rng().gen_range(800.0..1600.0);
sprite.translation.y = rand::thread_rng().gen_range(-300.0..300.0);
}
}
}
for event in engine.collision_events.drain(..) {
if event.state.is_end() {
continue;
}
if event.pair.either_contains("obstacle") {
if event.pair.either_contains("player1") {
game_state.health_amount_p1 -= 1;
let health_message_p1 = engine.texts.get_mut("health_message_p1").unwrap();
health_message_p1.value = format!("Health P1: {}", game_state.health_amount_p1);
}
if event.pair.either_contains("player2") {
game_state.health_amount_p2 -= 1;
let health_message_p2 = engine.texts.get_mut("health_message_p2").unwrap();
health_message_p2.value = format!("Health P2: {}", game_state.health_amount_p2);
}
engine.audio_manager.play_sfx(SfxPreset::Impact3, 0.5);
}
}
if game_state.health_amount_p1 == 0 || game_state.health_amount_p2 == 0 {
game_state.lost = true;
let game_over = engine.add_text("game_over", "Game Over");
game_over.font_size = 128.0;
game_over.translation.x = 0.0;
game_over.translation.y = 0.0;
engine.audio_manager.stop_music();
engine.audio_manager.play_sfx(SfxPreset::Jingle3, 0.5);
}
}