Skip to content

Commit

Permalink
Add target arrows
Browse files Browse the repository at this point in the history
  • Loading branch information
guimcaballero committed Jan 20, 2021
1 parent 59a4125 commit 9a7e904
Showing 1 changed file with 73 additions and 19 deletions.
92 changes: 73 additions & 19 deletions src/arrows.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::consts::*;
use crate::types::*;
use bevy::prelude::*;

/// Keeps the textures and materials for Arrows
Expand Down Expand Up @@ -26,46 +27,99 @@ impl FromResources for ArrowMaterialResource {
}
}

/// Actual component that goes on the sprites
struct Arrow;
struct TargetArrow;
fn setup_target_arrows(commands: &mut Commands, materials: Res<ArrowMaterialResource>) {
use Directions::*;
let directions = [Up, Down, Left, Right];

for direction in directions.iter() {
let mut transform =
Transform::from_translation(Vec3::new(TARGET_POSITION, direction.y(), 1.));
transform.rotate(Quat::from_rotation_z(direction.rotation()));
commands
.spawn(SpriteBundle {
material: materials.border_texture.clone(),
sprite: Sprite::new(Vec2::new(140., 140.)),
transform,
..Default::default()
})
.with(TargetArrow);
}
}

/// Keeps track of when to Spawn a new arrow
struct SpawnTimer(Timer);
/// Actual component that goes on the sprites
struct Arrow {
speed: Speed,
direction: Directions,
}

/// Spawns arrows
fn spawn_arrows(
commands: &mut Commands,
mut song_config: ResMut<SongConfig>,
materials: Res<ArrowMaterialResource>,
time: Res<Time>,
mut timer: ResMut<SpawnTimer>,
) {
if !timer.0.tick(time.delta_seconds()).just_finished() {
return;
// We get the current time since startup (secs) and the time since the last iteration (secs_last),
// this way we check if any arrows should spawn in this window

// Song starts 3 seconds after start, so we subtract 3 seconds
let secs = time.seconds_since_startup() - 3.;
let secs_last = secs - time.delta_seconds_f64();

// Counter of how many arrows we need to spawn and remove from the list
let mut remove_counter = 0;
for arrow in &song_config.arrows {
// List is ordered, so we can just check until an item fails
// Check if arrow should be spawned at any point between last frame and this frame
if secs_last < arrow.spawn_time && arrow.spawn_time < secs {
remove_counter += 1;

// Get the correct material according to speed
let material = match arrow.speed {
Speed::Slow => materials.red_texture.clone(),
Speed::Medium => materials.blue_texture.clone(),
Speed::Fast => materials.green_texture.clone(),
};

let mut transform =
Transform::from_translation(Vec3::new(SPAWN_POSITION, arrow.direction.y(), 1.));
// Rotate the arrow acording to direction
transform.rotate(Quat::from_rotation_z(arrow.direction.rotation()));
commands
.spawn(SpriteBundle {
material,
sprite: Sprite::new(Vec2::new(140., 140.)),
transform,
..Default::default()
})
.with(Arrow {
speed: arrow.speed,
direction: arrow.direction,
});
} else {
break;
}
}

let transform = Transform::from_translation(Vec3::new(SPAWN_POSITION, 0., 1.));
commands
.spawn(SpriteBundle {
material: materials.red_texture.clone(),
sprite: Sprite::new(Vec2::new(140., 140.)),
transform,
..Default::default()
})
.with(Arrow);
// Remove the arrows we have spawned from the list
for _ in 0..remove_counter {
song_config.arrows.remove(0);
}
}

/// Moves the arrows forward
fn move_arrows(time: Res<Time>, mut query: Query<(&mut Transform, &Arrow)>) {
for (mut transform, _arrow) in query.iter_mut() {
transform.translation.x += time.delta_seconds() * BASE_SPEED;
for (mut transform, arrow) in query.iter_mut() {
transform.translation.x += time.delta_seconds() * arrow.speed.value();
}
}

pub struct ArrowsPlugin;
impl Plugin for ArrowsPlugin {
fn build(&self, app: &mut AppBuilder) {
app.init_resource::<ArrowMaterialResource>()
.add_resource(SpawnTimer(Timer::from_seconds(1.0, true)))
.add_startup_system(setup_target_arrows.system())
.add_system(spawn_arrows.system())
.add_system(move_arrows.system());
}
Expand Down

0 comments on commit 9a7e904

Please sign in to comment.