diff --git a/src/game.rs b/src/game.rs index 736355b..9df12da 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,80 +1,29 @@ use crate::prelude::*; -fn spawn_square_at (commands: &mut Commands, level: u32, position: usize, asset_server: AssetServer) { - let font = asset_server.load("proxima_thin.ttf"); - let Some(&(x, y)) = sq_origins.get(position) else { - return; - }; +#[derive(Component)] +pub struct FieldView; - let text = 2i32.pow(level); - let label = Text2dBundle { - text: Text::from_section(text.to_string(), TextStyle { - font, - font_size: 44., - color: Color::WHITE, - }), - transform: Transform { - translation: Vec3::new(x, y, 0.0), - ..Default::default() - }, - ..Default::default() - }; - commands.spawn(SpriteBundle { - sprite: Sprite { - color: sq_colors[level as usize % sq_colors.len()], - ..Default::default() - }, - transform: Transform { - translation: Vec3::new(x, y, 0.0), - scale: Vec3::new(148.0, 148.0, 1.0), - ..Default::default() - }, - ..Default::default() - }); - commands.spawn(label); -} - -pub fn update_scoreboard (score: Res, mut query: Query<&mut Text, With>) { - let mut text = query.single_mut(); - text.sections[1].value = score.to_string(); -} - -pub fn render_field ( - mut commands: Commands, - asset_server: Res, - field: Res, -) { - for (idx, &val) in field.iter().enumerate() { - if val > 0 { - spawn_square_at(&mut commands, val, idx, asset_server.clone()); - } - } -} pub fn enter ( mut commands: Commands, asset_server: Res, mut field: ResMut, ) { + let font = asset_server.load("proxima_thin.ttf"); let thread = &mut thread_rng(); - let mut start = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]; + let borders = [-305., 305.]; + let lines = [-150., 0., 150.]; - start.shuffle(thread); - *field = Field(start); - - ui(commands, asset_server) - -} - -pub fn ui ( - mut commands: Commands, - asset_server: Res, -) { - let font = asset_server.load("proxima.ttf"); + let border_width = 10.; + let line_width = 1.; + let length = 620.; + let border_color = Color::BLACK; + let line_color = Color::srgba(0., 0., 0., 0.667); + let bg_color = Color::srgba(0.2, 0.01, 0.5, 0.632); commands.spawn(( ScoreboardUi, @@ -100,23 +49,7 @@ pub fn ui ( ..default() }), )); - - draw_board(&mut commands); -} - - -fn draw_board (commands: &mut Commands) { - let borders = [-305., 305.]; - let lines = [-150., 0., 150.]; - - let border_width = 10.; - let line_width = 1.; - let length = 620.; - - let border_color = Color::BLACK; - let line_color = Color::srgba(0., 0., 0., 0.667); - let bg_color = Color::srgba(0.2, 0.01, 0.5, 0.632); - + // // bg commands.spawn(SpriteBundle { sprite: Sprite { color: bg_color, ..Default::default() }, @@ -143,9 +76,131 @@ fn draw_board (commands: &mut Commands) { commands.spawn(line(line_color, Vec3::new(lines[mesh], 0.0, 0.0), Vec3::new(line_width, length, 1.0))); commands.spawn(line(line_color, Vec3::new(0.0, lines[mesh], 0.0), Vec3::new(length, line_width, 1.0))); } + + + let mut start = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]; + start.shuffle(thread); + *field = Field(start); + + + render_field(commands, asset_server, field.into()); +} + +pub fn update_scoreboard (score: Res, mut query: Query<&mut Text, With>) { + let mut text = query.single_mut(); + text.sections[1].value = score.to_string(); +} + +pub fn render_field ( + mut commands: Commands, + asset_server: Res, + field: Res, +) { + for (idx, &val) in field.iter().enumerate() { + if val > 0 { + spawn_square_at(&mut commands, val, idx, asset_server.clone()); + } + } } -pub fn run (mut commands: Commands) { +fn spawn_square_at (commands: &mut Commands, level: u32, position: usize, asset_server: AssetServer) { + let font = asset_server.load("proxima_thin.ttf"); + let Some(&(x, y)) = sq_origins.get(position) else { + return; + }; + + let text = 2i32.pow(level); + let label = Text2dBundle { + text: Text::from_section(text.to_string(), TextStyle { + font, + font_size: 44., + color: Color::WHITE, + }), + transform: Transform { + translation: Vec3::new(x, y, 0.0), + ..Default::default() + }, + ..Default::default() + }; + + commands.spawn((SpriteBundle { + sprite: Sprite { + color: sq_colors[level as usize % sq_colors.len()], + ..Default::default() + }, + transform: Transform { + translation: Vec3::new(x, y, 0.0), + scale: Vec3::new(148.0, 148.0, 1.0), + ..Default::default() + }, + ..Default::default() + }, FieldView)); + + commands.spawn((label, FieldView)); +} + + +pub fn process_inputs ( + kb: Res>, + gamepads: Res, + button_inputs: Res>, + _axes: Res>, + field: ResMut, + score: ResMut, +) { + + for key in kb.get_just_pressed() { + match key { + KeyCode::ArrowUp | KeyCode::KeyW => { + return move_field(MoveDirection::Up, field, score); + }, + KeyCode::ArrowDown | KeyCode::KeyS => { + return move_field(MoveDirection::Down, field, score); + }, + KeyCode::ArrowLeft | KeyCode::KeyA => { + return move_field(MoveDirection::Left, field, score); + }, + KeyCode::ArrowRight | KeyCode::KeyD => { + return move_field(MoveDirection::Right, field, score); + }, + _ => () + } + return; + } + + for gamepad in gamepads.iter() { + use GamepadButtonType as GBT; + + // is_current_gamepad_button_pressed (i ain't writing this) + let icgbp = |gbt: GamepadButtonType| button_inputs.just_pressed(GamepadButton::new(gamepad, gbt)); + + // @TODO: think about throttling stick inputs; if this is possible, reintroduce stick + // controls (with custom actuation point) + // https://bevy-cheatbook.github.io/input/gamepad.html#gamepad-settings + if icgbp(GBT::DPadLeft) { + return move_field(MoveDirection::Left, field, score); + } else if icgbp(GBT::DPadRight) { + return move_field(MoveDirection::Right, field, score); + } else if icgbp(GBT::DPadUp) { + return move_field(MoveDirection::Up, field, score); + } else if icgbp(GBT::DPadDown) { + return move_field(MoveDirection::Down, field, score); + } + + + } +} + +pub fn move_field ( + direction: MoveDirection, + field: ResMut, + score: ResMut +) { + + println!("{:?} {:?}", direction, score); +} + +pub fn redraw_field () { } diff --git a/src/main.rs b/src/main.rs index 715f6cd..52f72d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,12 +14,12 @@ impl Plugin for SqPlugin { // add things to your app here app .insert_resource(ClearColor(BG_COLOR)) - .insert_state(State4096::Menu) + .insert_state(State4096::Game) .insert_state(InGameState::Static) .insert_resource(Score(0)) .insert_resource(Field(vec![])) .add_systems(Startup, setup::setup) - .add_systems(Update, (game::render_field, game::update_scoreboard, game::run).run_if(in_state(State4096::Game))) + .add_systems(Update, (game::update_scoreboard, game::process_inputs).run_if(in_state(State4096::Game))) .add_systems(Update, (menu::actions, common::button_system).run_if(in_state(State4096::Menu))) .add_systems(OnEnter(State4096::Menu), menu::enter) .add_systems(OnExit(State4096::Menu), common::despawn_screen::) diff --git a/src/prelude.rs b/src/prelude.rs index 98acee7..0e82304 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,7 +1,7 @@ pub use bevy::prelude::*; pub use rand::{ seq::SliceRandom, thread_rng, Rng }; -#[derive(Resource, Deref, DerefMut)] +#[derive(Resource, Deref, DerefMut, Debug)] pub struct Score (pub usize); #[derive(Component)] @@ -11,6 +11,13 @@ pub struct ScoreboardUi; #[derive(Resource, Deref, DerefMut)] pub struct Field (pub Vec); +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum MoveDirection { + Up, + Down, + Left, + Right +} #[derive(States, Clone, Debug, Default, PartialEq, Eq, Hash)] pub enum State4096 {