grid movement

This commit is contained in:
Christian Nieves
2024-12-08 02:24:46 -06:00
parent dd882752de
commit 9dda1a1a50

View File

@ -1,17 +1,99 @@
use bevy::prelude::*; use bevy::{prelude::*, window::PrimaryWindow};
use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_inspector_egui::quick::WorldInspectorPlugin;
const SNAKE_HEAD_COLOR: Color = Color::srgb(0.7, 1.0, 0.7);
const ARENA_WIDTH: u32 = 20;
const ARENA_HEIGHT: u32 = 15;
const WINDOW_WIDTH: f32 = 1280.0;
#[derive(Component)] #[derive(Component)]
struct SnakeHead; struct SnakeHead;
const SNAKE_HEAD_COLOR: Color = Color::srgb(0.7, 0.7, 0.7); #[derive(Component)]
struct Position {
x: i32,
y: i32,
}
#[derive(Component)]
struct Size {
width: f32,
height: f32,
}
impl Size {
pub fn square(x: f32) -> Self {
Self {
width: x,
height: x,
}
}
}
fn snake_movement_system(
input: Res<ButtonInput<KeyCode>>,
mut head_transforms: Query<(&SnakeHead, &mut Position)>,
) {
for (_, mut pos) in head_transforms.iter_mut() {
if input.pressed(KeyCode::ArrowUp) {
pos.y += 1;
} else if input.pressed(KeyCode::ArrowDown) {
pos.y -= 1;
} else if input.pressed(KeyCode::ArrowLeft) {
pos.x -= 1;
} else if input.pressed(KeyCode::ArrowRight) {
pos.x += 1;
}
}
}
fn scale_translation(
mut windows: Query<&mut Window, With<PrimaryWindow>>,
mut q: Query<(&Size, &mut Transform)>,
) {
let window = windows.single_mut();
for (sprite_size, mut transform) in q.iter_mut() {
transform.scale = Vec3::new(
sprite_size.width / ARENA_WIDTH as f32 * window.width(),
sprite_size.height / ARENA_HEIGHT as f32 * window.height(),
1.0,
);
}
}
fn position_translation(
mut windows: Query<&mut Window, With<PrimaryWindow>>,
mut q: Query<(&Position, &mut Transform)>,
) {
// We subtract half the window width because our coordinate system starts at the bottom left, and
// Translation starts from the center. We then add half the size of a single tile, because we want
// our sprites bottom left corner to be at the bottom left of a tile, not the center.
fn convert(pos: f32, bound_window: f32, bound_game: f32) -> f32 {
let tile_size = bound_window / bound_game;
pos / bound_game * bound_window - (bound_window / 2.) + (tile_size / 2.)
}
let window = windows.single_mut();
for (pos, mut transform) in q.iter_mut() {
transform.translation = Vec3::new(
convert(pos.x as f32, window.width(), ARENA_WIDTH as f32),
convert(pos.y as f32, window.height(), ARENA_HEIGHT as f32),
0.0,
);
}
}
fn setup_player(mut commands: Commands) { fn setup_player(mut commands: Commands) {
commands.spawn(Sprite { commands
color: SNAKE_HEAD_COLOR, .spawn(Sprite {
custom_size: Some(Vec2::new(10.0, 10.0)), color: SNAKE_HEAD_COLOR,
..default() custom_size: Some(Vec2::new(10.0, 10.0)),
}); ..default()
})
.insert(SnakeHead)
.insert(Position { x: 0, y: 0 })
.insert(Size::square(1.0));
} }
fn setup_camera(mut commands: Commands) { fn setup_camera(mut commands: Commands) {
@ -19,9 +101,25 @@ fn setup_camera(mut commands: Commands) {
} }
fn main() { fn main() {
let systems = snake_movement_system;
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
title: "Snake".to_string(),
resolution: (
WINDOW_WIDTH,
WINDOW_WIDTH * (ARENA_HEIGHT as f32 / ARENA_WIDTH as f32),
)
.into(),
..default()
}),
..default()
}),
)
.add_plugins(WorldInspectorPlugin::new()) .add_plugins(WorldInspectorPlugin::new())
.add_systems(Startup, (setup_camera, setup_player)) .add_systems(Startup, (setup_camera, setup_player))
.add_systems(Update, systems)
.add_systems(PostUpdate, (scale_translation, position_translation))
.run(); .run();
} }