Skip to content
Snippets Groups Projects
Verified Commit 1b574c12 authored by Louis's avatar Louis :fire:
Browse files

Press space to shoot, despawn shots at the edge of the screen

parent ba10525e
No related branches found
No related tags found
No related merge requests found
......@@ -524,6 +524,18 @@ dependencies = [
"radsort",
]
[[package]]
name = "bevy_prototype_lyon"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "799f9bc78cdef67d8dbecd06d2147d30732cdc74eb5e15edacf76ff2069b3d9f"
dependencies = [
"bevy",
"lyon_algorithms",
"lyon_tessellation",
"svgtypes",
]
[[package]]
name = "bevy_ptr"
version = "0.10.1"
......@@ -1148,6 +1160,15 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "float_next_after"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fc612c5837986b7104a87a0df74a5460931f1c5274be12f8d0f40aa2f30d632"
dependencies = [
"num-traits",
]
[[package]]
name = "foreign-types"
version = "0.3.2"
......@@ -1511,6 +1532,12 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "libm"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
[[package]]
name = "lock_api"
version = "0.4.10"
......@@ -1527,6 +1554,48 @@ version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
[[package]]
name = "lyon_algorithms"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00a0349cd8f0270781bb93a824b63df6178e3b4a27794e7be3ce3763f5a44d6e"
dependencies = [
"lyon_path",
"num-traits",
]
[[package]]
name = "lyon_geom"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74df1ff0a0147282eb10699537a03baa7d31972b58984a1d44ce0624043fe8ad"
dependencies = [
"arrayvec",
"euclid",
"num-traits",
]
[[package]]
name = "lyon_path"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8358c012e5651e4619cfd0b5b75c0f77866181a01b0909aab4bae14adf660"
dependencies = [
"lyon_geom",
"num-traits",
]
[[package]]
name = "lyon_tessellation"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d2124218d5428149f9e09520b9acc024334a607e671f032d06567b61008977c"
dependencies = [
"float_next_after",
"lyon_path",
"thiserror",
]
[[package]]
name = "malloc_buf"
version = "0.0.6"
......@@ -1762,6 +1831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
"libm",
]
[[package]]
......@@ -2158,6 +2228,7 @@ name = "shoot-the-revival"
version = "0.1.0"
dependencies = [
"bevy",
"bevy_prototype_lyon",
"log",
]
......@@ -2167,6 +2238,12 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f"
[[package]]
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]]
name = "slab"
version = "0.4.8"
......@@ -2235,6 +2312,15 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2"
[[package]]
name = "svgtypes"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22975e8a2bac6a76bb54f898a6b18764633b00e780330f0b689f65afb3975564"
dependencies = [
"siphasher",
]
[[package]]
name = "syn"
version = "1.0.109"
......
......@@ -7,6 +7,7 @@ edition = "2021"
[dependencies]
log = "0.4.19"
bevy_prototype_lyon = "0.8.0"
[dependencies.bevy]
version = "0.10.1"
......
......@@ -18,6 +18,7 @@ mod _plugin {
.add_systems((
super::player::process_player_input,
super::motion::apply_velocity,
super::spawning::apply_despawn_boundaries,
));
}
}
......@@ -25,6 +26,6 @@ mod _plugin {
pub use _plugin::EntityPlugin;
pub use collision::{check_box_collisions, BoxSize, CollisionGroup};
pub use motion::Velocity;
pub use motion::{Velocity, DIR_LEFT, DIR_RIGHT};
pub use player::Player;
pub use spawning::EntitySpawner;
pub use spawning::{DespawnOffScreen, EntitySpawner};
......@@ -3,6 +3,9 @@ use bevy::math::Vec2;
use bevy::prelude::{Component, Query, Res, Time, Transform};
use std::ops::Mul;
pub const DIR_LEFT: Vec2 = Vec2::new(-1.0, 0.0);
pub const DIR_RIGHT: Vec2 = Vec2::new(1.0, 0.0);
#[derive(Clone, Copy, Debug, Component)]
pub struct Velocity(Vec2);
deref_as!(mut Velocity => Vec2);
......
use crate::entities::spawning::EntitySpawner;
use crate::entities::Velocity;
use crate::entities::{CollisionGroup, DespawnOffScreen, EntitySpawner, Velocity, DIR_RIGHT};
use crate::system::window_bounds;
use bevy::math::Vec2;
use bevy::prelude::{Component, DetectChangesMut, Input, KeyCode, Query, Res, With};
use bevy::math::{Vec2, Vec3Swizzles};
use bevy::prelude::{Component, DetectChangesMut, Input, KeyCode, Query, Res, Transform, With};
#[derive(Component)]
pub struct Player;
......@@ -17,7 +16,9 @@ macro_rules! any_pressed {
}
pub fn process_player_input(
mut player_query: Query<&mut Velocity, With<Player>>,
mut spawner: EntitySpawner,
mut player_velocity_query: Query<&mut Velocity, With<Player>>,
player_position_query: Query<&Transform, With<Player>>,
input: Res<Input<KeyCode>>,
) {
let mut delta = Vec2::default();
......@@ -35,7 +36,17 @@ pub fn process_player_input(
delta.y += 1.0;
}
for mut velocity in &mut player_query {
if input.just_pressed(KeyCode::Space) {
for position in &player_position_query {
spawner.spawn_projectile(
position.translation.xy() + Vec2::new(15.0, 0.0),
DIR_RIGHT,
(CollisionGroup::FriendlyProjectile, DespawnOffScreen::all()),
);
}
}
for mut velocity in &mut player_velocity_query {
if delta != Vec2::ZERO {
*velocity = Velocity::default() * delta;
} else if **(velocity.bypass_change_detection()) != Vec2::ZERO {
......
use crate::entities::motion::Velocity;
use crate::entities::{BoxSize, CollisionGroup, Player};
use crate::system::{Background, BACKGROUND_HEIGHT, BACKGROUND_WIDTH};
use crate::system::{Background, DawnBringerPalette, BACKGROUND_HEIGHT, BACKGROUND_WIDTH};
use crate::utilities::translate_rect;
use bevy::ecs::system::SystemParam;
use bevy::prelude::{AssetServer, Commands, Entity, Res, Sprite, SpriteBundle, Transform, Vec2};
use bevy::math::Vec3Swizzles;
use bevy::prelude::{
AssetServer, Bundle, Changed, Commands, Component, DespawnRecursiveExt, Entity,
OrthographicProjection, Query, Rect, Res, Sprite, SpriteBundle, Transform, Vec2,
};
use bevy_prototype_lyon::draw::Stroke;
use bevy_prototype_lyon::prelude::{Fill, GeometryBuilder, ShapeBundle};
use bevy_prototype_lyon::shapes;
static Z_PLAYER: f32 = 300.0;
static Z_ITEMS: f32 = 200.0;
static Z_ENEMY: f32 = 250.0;
static Z_BACKGROUND: f32 = 50.0;
#[derive(Copy, Clone, Debug, Component)]
pub struct DespawnOffScreen {
left: bool,
right: bool,
top: bool,
bottom: bool,
}
impl Default for DespawnOffScreen {
fn default() -> Self {
Self {
left: true,
right: true,
top: true,
bottom: true,
}
}
}
impl DespawnOffScreen {
pub fn all() -> Self {
Self::default()
}
pub fn right() -> Self {
Self {
left: false,
right: true,
top: false,
bottom: false,
}
}
pub fn left() -> Self {
Self {
left: true,
right: false,
top: false,
bottom: false,
}
}
pub fn entity_should_despawn(&self, entity_pos: Vec2, camera_bounds: Rect) -> bool {
self.left && entity_pos.x < camera_bounds.min.x
|| self.top && entity_pos.y > camera_bounds.max.y
|| self.right && entity_pos.x > camera_bounds.max.x
|| self.bottom && entity_pos.y < camera_bounds.min.y
}
}
#[derive(SystemParam)]
pub struct EntitySpawner<'w, 's> {
commands: Commands<'w, 's>,
......@@ -62,4 +120,56 @@ impl<'w, 's> EntitySpawner<'w, 's> {
))
.id()
}
pub fn spawn_projectile(
&mut self,
position: Vec2,
velocity_direction: Vec2,
rest: impl Bundle,
) -> Entity {
let projectile_shape = shapes::RoundedPolygon {
radius: 2.0,
closed: true,
points: vec![
Vec2::new(-7.0, -2.0),
Vec2::new(-7.0, 2.0),
Vec2::new(7.0, 2.0),
Vec2::new(7.0, -2.0),
],
};
self.commands
.spawn((
ShapeBundle {
path: GeometryBuilder::build_as(&projectile_shape),
transform: Transform::from_translation(position.extend(Z_ITEMS)),
..Default::default()
},
BoxSize::from(Vec2::new(10.0, 10.0)),
Fill::color(DawnBringerPalette::MID_BLUE),
Stroke::new(DawnBringerPalette::MIDNIGHT_BLUE, 2.0),
Velocity::from(Vec2::new(100.0, 0.0) * velocity_direction),
rest,
))
.id()
}
}
pub fn apply_despawn_boundaries(
mut commands: Commands,
camera_query: Query<(&OrthographicProjection, &Transform)>,
bounds_query: Query<(Entity, &DespawnOffScreen, &Transform), Changed<Transform>>,
) {
let (camera_ortho, camera_position) = match camera_query.get_single() {
Ok(value) => value,
Err(_) => return,
};
let viewport = translate_rect(camera_ortho.area, camera_position.translation.xy());
for (entity, boundary, transform) in &bounds_query {
if boundary.entity_should_despawn(transform.translation.xy(), viewport) {
commands.entity(entity).despawn_recursive();
}
}
}
......@@ -17,5 +17,6 @@ fn main() {
}))
.add_plugin(shoot_the_revival::system::SystemPlugin)
.add_plugin(shoot_the_revival::entities::EntityPlugin)
.add_plugin(bevy_prototype_lyon::plugin::ShapePlugin)
.run();
}
use bevy::math::Vec2;
use bevy::prelude::Rect;
#[macro_export]
macro_rules! deref_as {
($outer:ty => $inner:ty) => {
......@@ -18,3 +20,7 @@ macro_rules! deref_as {
}
}
}
pub fn translate_rect(rect: Rect, translation: Vec2) -> Rect {
Rect::from_corners(rect.min + translation, rect.max + translation)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment