Skip to content

Commit

Permalink
Car textures
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasmerlin committed Dec 10, 2023
1 parent 411f778 commit 1862c42
Show file tree
Hide file tree
Showing 18 changed files with 194 additions and 40 deletions.
Binary file added assets/cars/beetle/off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/beetle/on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/blue/off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/blue/on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/bully_1/off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/bully_1/on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/bully_2/off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/bully_2/on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/lila/off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/lila/on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/red/off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/red/on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/cars/tow_truck.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/environment/beam.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::level::LevelLifecycle;
use crate::CAR_SCALE;
use bevy::prelude::*;
use bevy::sprite::Anchor;

Expand Down Expand Up @@ -68,7 +69,7 @@ pub fn update_beam_system(
- beam_global_transform.translation())
.length();

sprite.custom_size = Some(Vec2::new(beam_length, 0.5));
sprite.custom_size = Some(Vec2::new(beam_length, 0.5 * CAR_SCALE));
}
}
}
190 changes: 161 additions & 29 deletions src/environment/car.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
use bevy::prelude::*;
use bevy::render::render_resource::Texture;
use bevy::sprite::Anchor;
use bevy_rapier2d::prelude::*;
use rand::prelude::SliceRandom;
use rand::{random, thread_rng, Rng};

use crate::block::{Block, DestroyBlockOnContact};
use crate::consts::{BLOCK_COLLISION_GROUP, FLOOR_COLLISION_GROUP};
use crate::environment::rain::DarkenSpriteOnRain;
use crate::level::{LevelLifecycle, UpdateLevelStats};
use crate::{CAR_MAX_HEIGHT, CAR_MIN_HEIGHT, HORIZONTAL_VIEWPORT_SIZE};
use crate::{
ASSET_SCALE, CAR_MAX_HEIGHT, CAR_MIN_HEIGHT, CAR_RATE, CAR_SCALE, HORIZONTAL_VIEWPORT_SIZE,
};

pub struct CarPlugin;

Expand All @@ -24,9 +30,88 @@ impl Plugin for CarPlugin {
}
}

#[derive(Component, Debug, Default)]
#[derive(Debug, Copy, Clone)]
pub enum CarType {
Beetle,
Blue,
Bully1,
Bully2,
Lila,
Red,
}

pub const CAR_TYPES: [CarType; 6] = [
CarType::Beetle,
CarType::Blue,
CarType::Bully1,
CarType::Bully2,
CarType::Lila,
CarType::Red,
];

impl CarType {
pub fn off_texture_size(&self) -> Vec2 {
match self {
CarType::Beetle => Vec2::new(487.0, 210.0),
CarType::Blue => Vec2::new(500.0, 180.0),
CarType::Bully1 => Vec2::new(580.0, 289.0),
CarType::Bully2 => Vec2::new(570.0, 260.0),
CarType::Lila => Vec2::new(500.0, 180.0),
CarType::Red => Vec2::new(500.0, 211.0),
}
}

pub fn on_texture_height(&self) -> f32 {
match self {
CarType::Beetle => 400.0,
CarType::Blue => 357.0,
CarType::Bully1 => 459.0,
CarType::Bully2 => 417.0,
CarType::Lila => 351.0,
CarType::Red => 405.0,
}
}

pub fn off_size(&self) -> Vec2 {
self.off_texture_size() * ASSET_SCALE * CAR_SCALE
}

pub fn on_size(&self) -> Vec2 {
Vec2::new(
self.off_texture_size().x * ASSET_SCALE * CAR_SCALE,
self.on_texture_height() * ASSET_SCALE * CAR_SCALE,
)
}

pub fn name(&self) -> &str {
match self {
CarType::Beetle => "beetle",
CarType::Blue => "blue",
CarType::Bully1 => "bully_1",
CarType::Bully2 => "bully_2",
CarType::Lila => "lila",
CarType::Red => "red",
}
}

pub fn on_asset_path(&self) -> String {
format!("cars/{}/on.png", self.name())
}

pub fn off_asset_path(&self) -> String {
format!("cars/{}/off.png", self.name())
}
}

#[derive(Component, Debug)]
pub struct Car {
state: CarState,
car_type: CarType,
}

#[derive(Component, Debug)]
struct CarTexture {
on: bool,
}

#[derive(Debug, Default)]
Expand All @@ -51,7 +136,7 @@ pub struct CarSpawner {
impl Default for CarSpawner {
fn default() -> Self {
Self {
spawn_timer: Timer::from_seconds(5.0, TimerMode::Repeating),
spawn_timer: Timer::from_seconds(CAR_RATE, TimerMode::Repeating),
}
}
}
Expand All @@ -60,15 +145,17 @@ pub fn spawn_car_system(
mut commands: Commands,
mut car_spawner: ResMut<CarSpawner>,
time: Res<Time>,
assets: Res<AssetServer>,
) {
car_spawner.spawn_timer.tick(time.delta());
if car_spawner.spawn_timer.just_finished() {
let car_size = Vec2::new(
thread_rng().gen_range(3.0..5.0),
thread_rng().gen_range(1.5..2.0),
);
let car_type = CAR_TYPES.choose(&mut thread_rng()).unwrap();

let car_size = car_type.off_size();

let forward = random::<bool>();

let direction = if random() { 1.0 } else { -1.0 };
let direction = if forward { 1.0 } else { -1.0 };

let car_position = Vec2::new(
direction * HORIZONTAL_VIEWPORT_SIZE,
Expand All @@ -77,33 +164,67 @@ pub fn spawn_car_system(

let car_velocity = Vec2::new(direction * -thread_rng().gen_range(7.0..10.0), 0.0);

commands.spawn((
Car::default(),
LevelLifecycle,
DestroyBlockOnContact,
SpriteBundle {
sprite: Sprite {
custom_size: Some(car_size),
color: Color::rgb(0.3, 0.3, 0.3),
..Default::default()
commands
.spawn((
Car {
state: CarState::Driving,
car_type: *car_type,
},
transform: Transform::from_xyz(car_position.x, car_position.y, 0.0),
..Default::default()
},
RigidBody::KinematicVelocityBased,
Collider::cuboid(car_size.x / 2.0, car_size.y / 2.0),
Friction::coefficient(0.5),
Velocity::linear(car_velocity),
));
LevelLifecycle,
DestroyBlockOnContact,
SpatialBundle::from_transform(Transform::from_xyz(
car_position.x,
car_position.y,
0.0,
)),
RigidBody::KinematicVelocityBased,
Collider::cuboid(car_size.x / 2.0, car_size.y / 2.0),
Friction::coefficient(0.5),
Velocity::linear(car_velocity),
))
.with_children(|parent| {
parent.spawn((
SpriteBundle {
sprite: Sprite {
custom_size: Some(car_type.on_size()),
flip_x: !forward,
anchor: Anchor::TopCenter,
..Default::default()
},
texture: assets.load(car_type.on_asset_path()),
transform: Transform::from_xyz(0.0, car_size.y / 2.0, 0.0),
..Default::default()
},
CarTexture { on: true },
DarkenSpriteOnRain(0.8),
));
parent.spawn((
SpriteBundle {
sprite: Sprite {
custom_size: Some(car_type.off_size()),
flip_x: !forward,
anchor: Anchor::TopCenter,
..Default::default()
},
texture: assets.load(car_type.off_asset_path()),
transform: Transform::from_xyz(0.0, car_size.y / 2.0, 0.0),
visibility: Visibility::Hidden,
..Default::default()
},
CarTexture { on: false },
DarkenSpriteOnRain(0.8),
));
});
car_spawner.spawn_timer =
Timer::from_seconds(random::<f32>() * 3.0 + 3.0, TimerMode::Repeating);
Timer::from_seconds(random::<f32>() * CAR_RATE + CAR_RATE, TimerMode::Repeating);
}
}

pub fn car_collision_system(
fn car_collision_system(
mut commands: Commands,
mut collision_events: EventReader<CollisionEvent>,
mut car_query: Query<(Entity, &mut Car)>,
mut car_query: Query<(Entity, &mut Car, &Children)>,
mut car_sprite_query: Query<(&CarTexture)>,
mut block_query: Query<Entity, With<Block>>,
mut car_crashed_events: EventWriter<CarCrashedEvent>,
mut update_level_stats_events: EventWriter<UpdateLevelStats>,
Expand All @@ -117,7 +238,8 @@ pub fn car_collision_system(
if !block_query.get(*block_entity).is_ok() {
return;
}
if let Ok((car_entity, mut car)) = car_query.get_mut(*car_entity) {
if let Ok((car_entity, mut car, children)) = car_query.get_mut(*car_entity)
{
if !matches!(car.state, CarState::Driving) {
return;
}
Expand All @@ -130,6 +252,16 @@ pub fn car_collision_system(
commands.entity(car_entity).insert((RigidBody::Dynamic,));
car_crashed_events.send(CarCrashedEvent { entity: car_entity });
update_level_stats_events.send(UpdateLevelStats::CarHit);

for child in children.iter() {
if let Ok((texture)) = car_sprite_query.get_mut(*child) {
if texture.on {
commands.entity(*child).insert(Visibility::Hidden);
} else {
commands.entity(*child).insert(Visibility::Visible);
}
}
}
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/environment/rain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ pub fn darken_sprite_on_rain_system(
.iter_mut()
.for_each(|(mut sprite, DarkenSpriteOnRain(darken))| {
let color = if level.rain.is_some() {
Color::rgb(0.7 * darken, 0.7 * darken, 0.7 * darken)
Color::rgb(0.7 / darken, 0.7 / darken, 0.7 / darken)
} else {
Color::WHITE
};
Expand Down
33 changes: 24 additions & 9 deletions src/environment/tow_truck.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;
use rand::{thread_rng, Rng};

use crate::environment::beam::BeamEvent;
use crate::environment::car::{Car, CarCrashedEvent};
use crate::level::LevelLifecycle;
use crate::HORIZONTAL_VIEWPORT_SIZE;
use crate::{ASSET_SCALE, CAR_MAX_HEIGHT, CAR_MIN_HEIGHT, CAR_SCALE, HORIZONTAL_VIEWPORT_SIZE};

pub struct TowTruckPlugin;

Expand All @@ -30,17 +31,35 @@ pub enum TowTruckPhase {
pub fn spawn_tow_truck_system(
mut commands: Commands,
mut car_crashed_events: EventReader<CarCrashedEvent>,
assets: Res<AssetServer>,
) {
for event in car_crashed_events.read() {
let size = Vec2::new(8.0, 4.0);
let res_w = 581.0;
let res_h = 462.0;

let pos_y = thread_rng().gen_range(CAR_MIN_HEIGHT..CAR_MAX_HEIGHT);

let size = Vec2::new(
res_w * ASSET_SCALE * CAR_SCALE,
res_h * ASSET_SCALE * CAR_SCALE,
);

commands.spawn((
TowTruck {
target: event.entity,
phase: TowTruckPhase::MovingToTarget,
},
LevelLifecycle,
SpatialBundle::from(Transform::from_xyz(-HORIZONTAL_VIEWPORT_SIZE, 5.0, 0.0)),
SpriteBundle {
transform: Transform::from_xyz(-HORIZONTAL_VIEWPORT_SIZE, pos_y, 0.0),
texture: assets.load("cars/tow_truck.png"),
sprite: Sprite {
custom_size: Some(size),
flip_x: true,
..Default::default()
},
..Default::default()
},
RigidBody::KinematicVelocityBased,
Collider::cuboid(size.x / 2.0, size.y / 2.0),
Velocity::linear(Vec2::new(5.0, 0.0)),
Expand All @@ -63,16 +82,12 @@ pub fn tow_car_system(
{
match tow_truck.phase {
TowTruckPhase::MovingToTarget => {
let distance = tow_truck_transform
.translation
.distance(car_transform.translation);

if distance < 5.0 {
if tow_truck_transform.translation.x > car_transform.translation.x + 7.0 {
tow_truck.phase = TowTruckPhase::RaisingCar;
beam_event_writer.send(BeamEvent {
source: tow_truck_entity,
target: car_entity,
source_offset: Vec3::new(1.5, 0.0, 0.0),
source_offset: Vec3::new(-2.4, 2.3, 0.0) * CAR_SCALE,
});
commands
.entity(tow_truck_entity)
Expand Down
6 changes: 6 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,18 @@ pub const GRAVITY: f32 = -9.81 * PIXELS_PER_METER * 2.0;
pub const PHYSICS_DT: f32 = 1.0 / 60.0;

pub const HORIZONTAL_VIEWPORT_SIZE: f32 = 45.0;
pub const _4K_H_RESOLUTION: f32 = 3840.0;
pub const ASSET_SCALE: f32 = HORIZONTAL_VIEWPORT_SIZE / _4K_H_RESOLUTION;
pub const FLOOR_HEIGHT: f32 = 1.0;

pub const CAR_MIN_HEIGHT: f32 = FLOOR_HEIGHT + 2.0;

pub const CAR_MAX_HEIGHT: f32 = 7.0;

pub const CAR_SCALE: f32 = 0.5;

pub const CAR_RATE: f32 = 0.75;

fn main() {
App::new()
.insert_resource(ClearColor(Color::rgb_u8(250, 225, 124)))
Expand Down

0 comments on commit 1862c42

Please sign in to comment.