More snake-like movement

This commit is contained in:
Timothy Warren 2020-12-30 09:52:14 -05:00
parent 40ed85950b
commit 19aa9b8d1a

View File

@ -25,12 +25,16 @@ impl Size {
}
}
struct SnakeHead;
struct SnakeHead {
direction: Direction,
}
struct Materials {
head_material: Handle<ColorMaterial>,
food_material: Handle<ColorMaterial>,
}
struct SnakeMoveTimer(Timer);
struct Food;
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>>) {
commands.spawn(Camera2dBundle::default());
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)),
..Default::default()
})
.with(SnakeHead)
.with(SnakeHead {
direction: Direction::Up,
})
.with(Position { x: 3, y: 3 })
.with(Size::square(0.8));
}
fn snake_movement(
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 keyboard_input.pressed(KeyCode::Left) {
pos.x -= 1;
if let Some((head_entity, mut head)) = heads.iter_mut().next() {
let mut head_pos = positions.get_mut(head_entity).unwrap();
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) {
pos.x += 1;
if !snake_timer.0.finished() {
return;
}
if keyboard_input.pressed(KeyCode::Down) {
pos.y -= 1;
match &head.direction {
Direction::Left => {
head_pos.x -= 1;
}
if keyboard_input.pressed(KeyCode::Up) {
pos.y += 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() {
App::build()
.add_resource(ClearColor(Color::rgb(0.04, 0.04, 0.04)))
@ -136,12 +186,17 @@ fn main() {
height: 500.0,
..Default::default()
})
.add_resource(SnakeMoveTimer(Timer::new(
Duration::from_millis(150),
true,
)))
.add_startup_system(setup.system())
.add_startup_stage("game_setup", SystemStage::single(spawn_snake.system()))
.add_system(snake_movement.system())
.add_system(position_translation.system())
.add_system(size_scaling.system())
.add_system(food_spawner.system())
.add_system(snake_timer.system())
.add_plugins(DefaultPlugins)
.run();
}