From 0c6a2cbb24decf581bced251973b098dc45d0fba Mon Sep 17 00:00:00 2001 From: Rich Churcher Date: Fri, 3 Jan 2025 12:30:56 +1300 Subject: [PATCH] Basic movement of yups, collision detection --- src/game.rs | 5 ++- src/game/movement.rs | 14 ++++++++ src/game/yup.rs | 29 +++++++++++++++++ src/lib.rs | 4 +-- src/screens.rs | 2 +- src/screens/ingame.rs | 4 +-- src/screens/ingame/playing.rs | 60 +++++++++++++++++++++++++++++++---- 7 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 src/game/movement.rs create mode 100644 src/game/yup.rs diff --git a/src/game.rs b/src/game.rs index 138a419..cb9adee 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,3 +1,6 @@ +pub mod movement; +pub mod yup; + use bevy::prelude::*; use crate::screens::Screen; @@ -21,7 +24,7 @@ pub enum Game { pub fn plugin(app: &mut App) { app.init_state::(); app.enable_state_scoped_entities::(); - + app.add_plugins((movement::plugin, yup::plugin)); app.add_systems(OnEnter(Game::Intro), init); } diff --git a/src/game/movement.rs b/src/game/movement.rs new file mode 100644 index 0000000..ea33945 --- /dev/null +++ b/src/game/movement.rs @@ -0,0 +1,14 @@ +use avian2d::prelude::*; +use bevy::prelude::*; + +use crate::screens::ingame::playing::MovementSpeed; + +pub fn plugin(app: &mut App) { + app.add_systems(FixedUpdate, movement); +} + +fn movement(mut moving_objects: Query<(&mut LinearVelocity, &MovementSpeed)>) { + for (mut lv, speed) in &mut moving_objects { + lv.x = speed.0; + } +} diff --git a/src/game/yup.rs b/src/game/yup.rs new file mode 100644 index 0000000..ef2ce16 --- /dev/null +++ b/src/game/yup.rs @@ -0,0 +1,29 @@ +use avian2d::prelude::*; +use bevy::prelude::*; + +use crate::screens::ingame::playing::{MovementSpeed, Obstacle}; + +#[derive(Component, Debug)] +pub struct Yup; + +pub fn plugin(app: &mut App) { + app.add_systems(PostProcessCollisions, collision_handler); +} + +fn collision_handler( + mut collisions: ResMut, + obstacles: Query>, + mut yups: Query<(Entity, &mut MovementSpeed), With>, +) { + // For now, we'll ignore all collisions between yups. + // TODO: sometimes blockers will need to be collided with! + collisions.retain(|c| yups.get(c.entity1).is_err() || yups.get(c.entity2).is_err()); + + for (yup, mut speed) in &mut yups { + for obstacle in &obstacles { + if collisions.contains(yup, obstacle) { + *speed = MovementSpeed(-speed.0); + } + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 44be4cc..916bb75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,8 @@ mod assets; #[cfg(feature = "dev")] mod dev_tools; -mod game; -mod screens; +pub mod game; +pub mod screens; mod ui; use avian2d::PhysicsPlugins; diff --git a/src/screens.rs b/src/screens.rs index 3b801b3..9fd8abe 100644 --- a/src/screens.rs +++ b/src/screens.rs @@ -1,4 +1,4 @@ -mod ingame; +pub mod ingame; mod loading; mod splash; mod title; diff --git a/src/screens/ingame.rs b/src/screens/ingame.rs index e490d4b..16e2342 100644 --- a/src/screens/ingame.rs +++ b/src/screens/ingame.rs @@ -1,5 +1,5 @@ -mod pause; -mod playing; +pub mod pause; +pub mod playing; use crate::game::Game; use bevy::prelude::*; diff --git a/src/screens/ingame/playing.rs b/src/screens/ingame/playing.rs index 4b673a8..20dbbb8 100644 --- a/src/screens/ingame/playing.rs +++ b/src/screens/ingame/playing.rs @@ -4,7 +4,7 @@ use avian2d::{ }; use bevy::prelude::*; -use crate::screens::Screen; +use crate::{game::yup::Yup, screens::Screen}; pub fn plugin(app: &mut App) { app.add_systems(OnEnter(Screen::InGame), init); @@ -12,10 +12,13 @@ pub fn plugin(app: &mut App) { } #[derive(Component, Debug)] -struct Player; +pub struct Platform; + +#[derive(Component, Debug)] +pub struct Obstacle; #[derive(Component)] -struct MovementSpeed(Scalar); +pub struct MovementSpeed(pub Scalar); fn init( mut commands: Commands, @@ -30,6 +33,7 @@ fn init( }; commands.spawn(( Name::new("Platform"), + Platform, platform.clone(), Collider::rectangle(50., 50.), RigidBody::Static, @@ -38,17 +42,61 @@ fn init( )); commands.spawn(( - Name::new("Player"), - Player, + Name::new("Platform"), + Platform, + platform.clone(), + Collider::rectangle(50., 50.), + RigidBody::Static, + StateScoped(Screen::InGame), + Transform::from_xyz(400., -150., 0.).with_scale(Vec3::new(10., 0.5, 10.)), + )); + + commands.spawn(( + Name::new("Obstacle"), + Obstacle, + platform.clone(), + Collider::rectangle(50., 50.), + RigidBody::Static, + StateScoped(Screen::InGame), + Transform::from_xyz(500., -112., 0.), + )); + + commands.spawn(( + Name::new("Obstacle"), + Obstacle, + platform.clone(), + Collider::rectangle(50., 50.), + RigidBody::Static, + StateScoped(Screen::InGame), + Transform::from_xyz(200., -112., 0.), + )); + + commands.spawn(( + Name::new("Yup"), + Yup, Collider::circle(20.), LockedAxes::ROTATION_LOCKED, Mesh2d(meshes.add(Circle::new(20.))), MeshMaterial2d(materials.add(Color::srgb(0.2, 0.7, 0.9))), - MovementSpeed(250.), + MovementSpeed(100.), Restitution::ZERO.with_combine_rule(CoefficientCombine::Min), RigidBody::Dynamic, StateScoped(Screen::InGame), Transform::from_xyz(0., 200., 0.), )); + + commands.spawn(( + Name::new("Yup"), + Yup, + Collider::circle(20.), + LockedAxes::ROTATION_LOCKED, + Mesh2d(meshes.add(Circle::new(20.))), + MeshMaterial2d(materials.add(Color::srgb(0.1, 0.6, 0.9))), + MovementSpeed(100.), + Restitution::ZERO.with_combine_rule(CoefficientCombine::Min), + RigidBody::Dynamic, + StateScoped(Screen::InGame), + Transform::from_xyz(-100., 500., 0.), + )); time.unpause(); }