4096game/src/game.rs

207 lines
5.9 KiB
Rust
Raw Normal View History

use crate::prelude::*;
#[derive(Component)]
pub struct FieldView;
pub fn enter (
mut commands: Commands,
asset_server: Res<AssetServer>,
mut field: ResMut<Field>,
) {
let font = asset_server.load("proxima_thin.ttf");
let thread = &mut thread_rng();
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);
commands.spawn((
ScoreboardUi,
TextBundle::from_sections([
TextSection::new(
"score: ",
TextStyle {
font: font.clone(),
font_size: SCOREBOARD_FONT_SIZE,
color: TEXT_COLOR,
},
),
TextSection::from_style(TextStyle {
font,
font_size: SCOREBOARD_FONT_SIZE,
color: SCORE_COLOR,
}),
])
.with_style(Style {
position_type: PositionType::Absolute,
top: SCOREBOARD_TEXT_PADDING,
left: SCOREBOARD_TEXT_PADDING,
..default()
}),
));
//
// bg
commands.spawn(SpriteBundle {
sprite: Sprite { color: bg_color, ..Default::default() },
transform: Transform {
scale: Vec3::new(length, length, 1.0),
..Default::default()
},
..Default::default()
});
let line = |color: Color, translation: Vec3, scale: Vec3| SpriteBundle {
sprite: Sprite { color, ..Default::default() },
transform: Transform { translation, scale, ..Default::default() },
..Default::default()
};
// @TODO variable grid size
for border in 0..2 {
commands.spawn(line(border_color, Vec3::new(borders[border], 0.0, 0.0), Vec3::new(border_width, length, 1.0)));
commands.spawn(line(border_color, Vec3::new(0.0, borders[border], 0.0), Vec3::new(length, border_width, 1.0)));
}
for mesh in 0..3 {
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<Score>, mut query: Query<&mut Text, With<ScoreboardUi>>) {
let mut text = query.single_mut();
text.sections[1].value = score.to_string();
}
pub fn render_field (
mut commands: Commands,
asset_server: Res<AssetServer>,
field: Res<Field>,
) {
for (idx, &val) in field.iter().enumerate() {
if val > 0 {
spawn_square_at(&mut commands, val, idx, asset_server.clone());
}
}
}
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<ButtonInput<KeyCode>>,
gamepads: Res<Gamepads>,
button_inputs: Res<ButtonInput<GamepadButton>>,
_axes: Res<Axis<GamepadAxis>>,
field: ResMut<Field>,
score: ResMut<Score>,
) {
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<Field>,
score: ResMut<Score>
) {
println!("{:?} {:?}", direction, score);
}
pub fn redraw_field () {
}