Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Add collisions #20

Merged
merged 6 commits into from
Mar 16, 2022
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
18 changes: 12 additions & 6 deletions protobufs/atc/v1/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import "atc/v1/airplane.proto";
import "atc/v1/location.proto";
import "atc/v1/node.proto";

message AirplaneCollided {
string id1 = 1;
string id2 = 2;
}

message AirplaneDetected {
Airplane airplane = 1;
}
Expand All @@ -32,12 +37,13 @@ message StreamRequest {}

message StreamResponse {
oneof event {
AirplaneDetected airplane_detected = 1;
AirplaneLanded airplane_landed = 2;
AirplaneMoved airplane_moved = 3;
FlightPlanUpdated flight_plan_updated = 4;
GameStarted game_started = 5;
GameStopped game_stopped = 6;
AirplaneCollided airplane_collided = 1;
AirplaneDetected airplane_detected = 2;
AirplaneLanded airplane_landed = 3;
AirplaneMoved airplane_moved = 4;
FlightPlanUpdated flight_plan_updated = 5;
GameStarted game_started = 6;
GameStopped game_stopped = 7;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/atc-game/src/components/airplane.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use bevy::prelude::*;

pub const AIRPLANE_SIZE: f32 = 24.0;

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Component)]
pub struct Airplane;

Expand Down
21 changes: 21 additions & 0 deletions src/atc-game/src/components/collider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use bevy::prelude::*;

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Component)]
pub struct Collider;

#[cfg(test)]
mod tests {
use super::Collider;

#[test]
fn trait_send() {
fn assert_send<T: Send>() {}
assert_send::<Collider>();
}

#[test]
fn trait_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<Collider>();
}
}
2 changes: 2 additions & 0 deletions src/atc-game/src/components/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
pub use self::airplane::*;
pub use self::airplane_id::*;
pub use self::collider::*;
pub use self::flight_plan::*;
pub use self::location::*;
pub use self::speed::*;

mod airplane;
mod airplane_id;
mod collider;
mod flight_plan;
mod location;
mod speed;
11 changes: 9 additions & 2 deletions src/atc-game/src/event/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use atc::v1::stream_response::Event as ApiEvent;
use atc::v1::{
Airplane, AirplaneDetected, AirplaneLanded, AirplaneMoved, FlightPlanUpdated, GameStarted,
GameStopped,
Airplane, AirplaneCollided, AirplaneDetected, AirplaneLanded, AirplaneMoved, FlightPlanUpdated,
GameStarted, GameStopped,
};

use crate::api::IntoApi;
Expand All @@ -13,6 +13,7 @@ mod bus;

#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub enum Event {
AirplaneCollided(AirplaneId, AirplaneId),
AirplaneDetected(AirplaneId, Location, FlightPlan),
AirplaneLanded(AirplaneId),
AirplaneMoved(AirplaneId, Location),
Expand All @@ -26,6 +27,12 @@ impl IntoApi for Event {

fn into_api(self) -> Self::ApiType {
match self {
Event::AirplaneCollided(airplane_id1, airplane_id2) => {
ApiEvent::AirplaneCollided(AirplaneCollided {
id1: airplane_id1.into_api(),
id2: airplane_id2.into_api(),
})
}
Event::AirplaneDetected(id, location, flight_plan) => {
ApiEvent::AirplaneDetected(AirplaneDetected {
airplane: Some(Airplane {
Expand Down
17 changes: 12 additions & 5 deletions src/atc-game/src/state/running.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use atc::v1::get_game_state_response::GameState;

use crate::event::{Event, EventBus};
use crate::systems::{
despawn_airplane, follow_flight_plan, setup_airport, setup_grid, spawn_airplane,
update_flight_plan, SpawnTimer,
despawn_airplane, detect_collision, follow_flight_plan, setup_airport, setup_grid,
spawn_airplane, update_flight_plan, SpawnTimer,
};

pub struct GameStateRunningPlugin;
Expand All @@ -22,11 +22,12 @@ impl Plugin for GameStateRunningPlugin {
.add_system_set(
SystemSet::on_update(GameState::Running)
.with_system(despawn_airplane)
.with_system(follow_flight_plan)
.with_system(follow_flight_plan.label("movement"))
.with_system(spawn_airplane)
.with_system(update_flight_plan),
.with_system(update_flight_plan)
.with_system(detect_collision.after("movement")),
)
.add_system_set(SystemSet::on_exit(GameState::Running));
.add_system_set(SystemSet::on_exit(GameState::Running).with_system(despawn_entities));
}
}

Expand All @@ -36,3 +37,9 @@ fn send_event(event_bus: Local<EventBus>) {
.send(Event::GameStarted)
.expect("failed to send event"); // TODO: Handle error
}

fn despawn_entities(mut commands: Commands, query: Query<Entity, Without<Camera>>) {
for entity in query.iter() {
commands.entity(entity).despawn_recursive();
}
}
5 changes: 5 additions & 0 deletions src/atc-game/src/store/watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ impl StoreWatcher {
Event::FlightPlanUpdated(id, flight_plan) => {
self.update_flight_plan(id, flight_plan);
}
Event::GameStopped => self.reset(),
_ => {}
}
}
Expand Down Expand Up @@ -60,4 +61,8 @@ impl StoreWatcher {
airplane.flight_plan = flight_plan.into_api();
}
}

fn reset(&self) {
self.store.clear();
}
}
55 changes: 55 additions & 0 deletions src/atc-game/src/systems/detect_collisions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use bevy::prelude::*;
use bevy::sprite::collide_aabb::collide;

use atc::v1::get_game_state_response::GameState;

use crate::components::{AirplaneId, Collider, AIRPLANE_SIZE};
use crate::event::{Event, EventBus};

pub struct Size {
airplane: Vec2,
}

impl Default for Size {
fn default() -> Self {
Self {
airplane: Vec2::new(AIRPLANE_SIZE, AIRPLANE_SIZE),
}
}
}

pub fn detect_collision(
mut app_state: ResMut<State<GameState>>,
query: Query<(Entity, &AirplaneId, &Collider, &Transform)>,
event_bus: Local<EventBus>,
size: Local<Size>,
) {
'outer: for (entity1, airplane_id1, _, transform1) in query.iter() {
for (entity2, airplane_id2, _, transform2) in query.iter() {
if entity1 == entity2 {
continue;
}

if collide(
transform1.translation,
size.airplane,
transform2.translation,
size.airplane,
)
.is_some()
{
event_bus
.sender()
.send(Event::AirplaneCollided(
airplane_id1.clone(),
airplane_id2.clone(),
))
.expect("failed to send event"); // TODO: Handle error

app_state.set(GameState::Ready).unwrap();

break 'outer;
}
}
}
}
2 changes: 2 additions & 0 deletions src/atc-game/src/systems/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub use self::change_app_state::*;
pub use self::despawn_airplane::*;
pub use self::detect_collisions::*;
pub use self::follow_flight_plan::*;
pub use self::setup_airport::*;
pub use self::setup_cameras::*;
Expand All @@ -9,6 +10,7 @@ pub use self::update_flight_plan::*;

mod change_app_state;
mod despawn_airplane;
mod detect_collisions;
mod follow_flight_plan;
mod setup_airport;
mod setup_cameras;
Expand Down
7 changes: 5 additions & 2 deletions src/atc-game/src/systems/spawn_airplane.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use bevy::prelude::*;
use rand::Rng;

use crate::components::{Airplane, AirplaneIdGenerator, FlightPlan, Location, Speed};
use crate::components::{
Airplane, AirplaneIdGenerator, Collider, FlightPlan, Location, Speed, AIRPLANE_SIZE,
};
use crate::map::{route_between, Tile, MAP_HEIGHT_RANGE, MAP_WIDTH_RANGE};
use crate::{Event, EventBus};

Expand Down Expand Up @@ -32,7 +34,7 @@ pub fn spawn_airplane(
.spawn_bundle(SpriteBundle {
transform: Transform {
translation: Vec3::new(spawn_point.x(), spawn_point.y(), 2.0),
scale: Vec3::new(8.0, 8.0, 0.0),
scale: Vec3::new(AIRPLANE_SIZE, AIRPLANE_SIZE, 0.0),
..Default::default()
},
sprite: Sprite {
Expand All @@ -43,6 +45,7 @@ pub fn spawn_airplane(
})
.insert(Airplane)
.insert(airplane_id.clone())
.insert(Collider)
.insert(flight_plan.clone())
.insert(Speed::new(32.0));

Expand Down
7 changes: 7 additions & 0 deletions src/print-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use atc::v1::StreamRequest;

fn should_print(event: &Event) -> bool {
match event {
Event::AirplaneCollided(_) => true,
Event::AirplaneDetected(_) => true,
Event::AirplaneLanded(_) => true,
Event::AirplaneMoved(_) => false,
Expand All @@ -29,6 +30,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}

match event {
Event::AirplaneCollided(collision) => {
println!(
"Airplane {} collided with airplane {}",
collision.id1, collision.id2
);
}
Event::AirplaneDetected(airplane_detected) => {
let airplane = airplane_detected.airplane.unwrap();
let location = airplane.location.unwrap();
Expand Down