More snake-like movement

This commit is contained in:
Timothy Warren 2020-12-30 09:52:14 -05:00
parent 40ed85950b
commit 19aa9b8d1a
1 changed files with 69 additions and 14 deletions

View File

@ -25,12 +25,16 @@ impl Size {
} }
} }
struct SnakeHead; struct SnakeHead {
direction: Direction,
}
struct Materials { struct Materials {
head_material: Handle<ColorMaterial>, head_material: Handle<ColorMaterial>,
food_material: Handle<ColorMaterial>, food_material: Handle<ColorMaterial>,
} }
struct SnakeMoveTimer(Timer);
struct Food; struct Food;
struct FoodSpawnTimer(Timer); struct FoodSpawnTimer(Timer);
@ -40,6 +44,24 @@ impl Default for FoodSpawnTimer {
} }
} }
#[derive(PartialEq, Copy, Clone)]
enum Direction {
Left,
Up,
Right,
Down,
}
impl Direction {
fn opposite(self) -> Self {
match self {
Self::Left => Self::Right,
Self::Right => Self::Left,
Self::Up => Self::Down,
Self::Down => Self::Up,
}
}
}
fn setup(commands: &mut Commands, mut materials: ResMut<Assets<ColorMaterial>>) { fn setup(commands: &mut Commands, mut materials: ResMut<Assets<ColorMaterial>>) {
commands.spawn(Camera2dBundle::default()); commands.spawn(Camera2dBundle::default());
commands.insert_resource(Materials { commands.insert_resource(Materials {
@ -55,28 +77,52 @@ fn spawn_snake(commands: &mut Commands, materials: Res<Materials>) {
sprite: Sprite::new(Vec2::new(10.0, 10.0)), sprite: Sprite::new(Vec2::new(10.0, 10.0)),
..Default::default() ..Default::default()
}) })
.with(SnakeHead) .with(SnakeHead {
direction: Direction::Up,
})
.with(Position { x: 3, y: 3 }) .with(Position { x: 3, y: 3 })
.with(Size::square(0.8)); .with(Size::square(0.8));
} }
fn snake_movement( fn snake_movement(
keyboard_input: Res<Input<KeyCode>>, keyboard_input: Res<Input<KeyCode>>,
mut head_positions: Query<&mut Position, With<SnakeHead>>, snake_timer: ResMut<SnakeMoveTimer>,
mut heads: Query<(Entity, &mut SnakeHead)>,
mut positions: Query<&mut Position>,
) { ) {
for mut pos in head_positions.iter_mut() { if let Some((head_entity, mut head)) = heads.iter_mut().next() {
if keyboard_input.pressed(KeyCode::Left) { let mut head_pos = positions.get_mut(head_entity).unwrap();
pos.x -= 1; let dir: Direction = if keyboard_input.pressed(KeyCode::Left) {
Direction::Left
} else if keyboard_input.pressed(KeyCode::Down) {
Direction::Down
} else if keyboard_input.pressed(KeyCode::Up) {
Direction::Up
} else if keyboard_input.pressed(KeyCode::Right) {
Direction::Right
} else {
head.direction
};
if dir != head.direction.opposite() {
head.direction = dir;
} }
if keyboard_input.pressed(KeyCode::Right) { if !snake_timer.0.finished() {
pos.x += 1; return;
}
if keyboard_input.pressed(KeyCode::Down) {
pos.y -= 1;
}
if keyboard_input.pressed(KeyCode::Up) {
pos.y += 1;
} }
match &head.direction {
Direction::Left => {
head_pos.x -= 1;
}
Direction::Right => {
head_pos.x += 1;
}
Direction::Up => {
head_pos.y += 1;
}
Direction::Down => {
head_pos.y -= 1;
}
};
} }
} }
@ -127,6 +173,10 @@ fn food_spawner(
} }
} }
fn snake_timer(time: Res<Time>, mut snake_timer: ResMut<SnakeMoveTimer>) {
snake_timer.0.tick(time.delta_seconds());
}
fn main() { fn main() {
App::build() App::build()
.add_resource(ClearColor(Color::rgb(0.04, 0.04, 0.04))) .add_resource(ClearColor(Color::rgb(0.04, 0.04, 0.04)))
@ -136,12 +186,17 @@ fn main() {
height: 500.0, height: 500.0,
..Default::default() ..Default::default()
}) })
.add_resource(SnakeMoveTimer(Timer::new(
Duration::from_millis(150),
true,
)))
.add_startup_system(setup.system()) .add_startup_system(setup.system())
.add_startup_stage("game_setup", SystemStage::single(spawn_snake.system())) .add_startup_stage("game_setup", SystemStage::single(spawn_snake.system()))
.add_system(snake_movement.system()) .add_system(snake_movement.system())
.add_system(position_translation.system()) .add_system(position_translation.system())
.add_system(size_scaling.system()) .add_system(size_scaling.system())
.add_system(food_spawner.system()) .add_system(food_spawner.system())
.add_system(snake_timer.system())
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.run(); .run();
} }