Add score indicator

This commit is contained in:
2023-03-17 17:54:51 +01:00
parent 3724db44b3
commit 09125bcd2f
7 changed files with 252 additions and 105 deletions

View File

@@ -3,6 +3,7 @@ use crate::{
fruit::FruitPlugin,
grid::{SEGMENT_SIZE, SIZE},
snake::SnakePlugin,
ui::UiPlugin,
};
use bevy::{prelude::*, render::camera::ScalingMode, window::WindowResolution};
use bevy_tweening::TweeningPlugin;
@@ -15,6 +16,7 @@ mod canvas;
mod fruit;
mod grid;
mod snake;
mod ui;
const ASPECT_RATIO: f32 = 16. / 9.;
const WINDOW_WIDTH: f32 = WINDOW_HEIGHT * ASPECT_RATIO;
@@ -27,15 +29,18 @@ enum GameState {
#[default]
Begin,
InGame,
Paused,
End,
}
#[derive(Resource)]
struct Score(u32);
fn main() {
let mut app = App::new();
app.insert_resource(ClearColor(CLEAR_COLOR))
.insert_resource(FixedTime::new(TICK_PERIOD))
.insert_resource(Score(0))
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
title: "Bevy-Snake".into(),
@@ -50,8 +55,9 @@ fn main() {
.add_plugin(SnakePlugin)
.add_plugin(FruitPlugin)
.add_plugin(CanvasPlugin)
.add_plugin(UiPlugin)
.add_startup_system(setup_system)
.add_system(camera_move_system);
.add_system(update_score_system);
#[cfg(debug_assertions)]
{
@@ -84,50 +90,16 @@ fn setup_system(mut commands: Commands) {
.insert(Name::new("Orthographic Camera"));
}
fn camera_move_system(
keypress: Res<Input<KeyCode>>,
mut query: Query<&mut Transform, With<Camera>>,
) {
if !keypress.pressed(KeyCode::LControl) {
return;
}
let delta = {
let mut delta = Vec3::ZERO;
if keypress.pressed(KeyCode::Up) {
delta += Vec3::new(0., 10., 0.);
}
if keypress.pressed(KeyCode::Down) {
delta += Vec3::new(0., -10., 0.);
}
if keypress.pressed(KeyCode::Left) {
delta += Vec3::new(-10., 0., 0.);
}
if keypress.pressed(KeyCode::Right) {
delta += Vec3::new(10., 0., 0.);
}
delta
};
query.for_each_mut(|mut transform| {
transform.translation += delta * 0.1;
});
fn update_score_system(mut score: ResMut<Score>, mut eaten_event: EventReader<fruit::EatenEvent>) {
score.0 += eaten_event.iter().count() as u32;
}
fn pause_system(
keypress: Res<Input<KeyCode>>,
current_state: Res<State<GameState>>,
mut next_state: ResMut<NextState<GameState>>,
) {
fn pause_system(keypress: Res<Input<KeyCode>>, mut time: ResMut<Time>) {
if keypress.just_pressed(KeyCode::P) {
let state = match current_state.0 {
GameState::InGame => GameState::Paused,
GameState::Paused => GameState::InGame,
_ => return,
};
next_state.set(state);
if time.is_paused() {
time.unpause()
} else {
time.pause()
}
}
}

14
src/ui.rs Normal file
View File

@@ -0,0 +1,14 @@
use bevy::prelude::*;
mod score;
pub struct UiPlugin;
impl Plugin for UiPlugin {
fn build(&self, app: &mut App) {
app.add_systems((
score::spawn_score_text.on_startup(),
score::update_score_text,
));
}
}

45
src/ui/score.rs Normal file
View File

@@ -0,0 +1,45 @@
use crate::Score;
use bevy::prelude::*;
#[derive(Component)]
pub(super) struct ScoreText;
pub(super) fn spawn_score_text(mut commands: Commands, asset_server: Res<AssetServer>) {
let font = asset_server.load("fonts/Audiowide-Regular.ttf");
commands.spawn((
ScoreText,
TextBundle::from_sections([
TextSection::new(
"Score: ",
TextStyle {
font: font.clone(),
font_size: 32.0,
color: Color::WHITE,
},
),
TextSection::from_style(TextStyle {
font: font,
font_size: 32.0,
color: Color::WHITE,
}),
])
.with_style(Style {
position_type: PositionType::Absolute,
position: UiRect {
left: Val::Px(10.0),
bottom: Val::Px(10.0),
..Default::default()
},
..Default::default()
}),
));
}
pub(super) fn update_score_text(mut query: Query<&mut Text, With<ScoreText>>, score: Res<Score>) {
let score = score.0;
for mut text in query.iter_mut() {
text.sections[1].value = format!("{score}");
}
}