Skip to content

Commit

Permalink
remove level loader and basic controls
Browse files Browse the repository at this point in the history
  • Loading branch information
mockersf committed Nov 8, 2024
1 parent d43e57e commit 67096df
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 299 deletions.
89 changes: 9 additions & 80 deletions src/game/mod.rs
Original file line number Diff line number Diff line change
@@ -1,98 +1,21 @@
use bevy::prelude::*;

use crate::{
level_loader::{Level, LoadedLevel, Tile},
GameAssets, GameState,
};
use crate::{GameAssets, GameState};

mod player;

const SCALE: f32 = 0.5;

pub fn game_plugin(app: &mut App) {
app.add_plugins(player::player_plugin)
.add_systems(OnEnter(GameState::Game), display_level);
}

#[derive(Component)]
#[require(IsOnGround, Velocity, AgainstWall)]
struct Player;

#[derive(Component, Default)]
struct IsOnGround(f32);

#[derive(Component, Default)]
struct AgainstWall(bool, bool);

#[derive(Component, Default)]
struct Velocity {
current: f32,
target: f32,
jumping: f32,
}

#[derive(Component)]
struct Ground;

fn ground_tile_index(line: &[Tile], i: usize) -> usize {
match (
i == 0 || !matches!(line.get(i - 1).unwrap_or(&Tile::Empty), Tile::Ground),
!matches!(line.get(i + 1).unwrap_or(&Tile::Empty), Tile::Ground),
) {
(true, true) => 8,
(true, false) => 14,
(false, true) => 0,
(false, false) => 7,
}
}

fn display_tile(
commands: &mut Commands,
tile: &Tile,
i: usize,
x: f32,
y: f32,
line: &[Tile],
assets: &GameAssets,
) {
match tile {
Tile::Ground => {
let index = ground_tile_index(line, i);
commands.spawn((
Sprite::from_atlas_image(
assets.ground_image.clone(),
TextureAtlas {
layout: assets.ground_layout.clone(),
index,
},
),
Transform::from_xyz(x, y, 0.0).with_scale(Vec3::splat(SCALE)),
Ground,
StateScoped(GameState::Game),
));
}
Tile::Empty => {}
}
}

fn display_level(
mut commands: Commands,
assets: Res<GameAssets>,
level: Res<LoadedLevel>,
levels: Res<Assets<Level>>,
) {
let level = levels.get(&level.level).unwrap();

for (j, line) in level.tiles.iter().enumerate() {
for (i, tile) in line.iter().enumerate() {
let (x, y) = (
(i as f32 - 9.0) * 128.0 * SCALE,
-(j as f32 - 5.0) * 128.0 * SCALE,
);
display_tile(&mut commands, tile, i, x, y, line, &assets);
}
}

fn display_level(mut commands: Commands, assets: Res<GameAssets>) {
commands.spawn((
Sprite::from_atlas_image(
assets.player_image.clone(),
Expand All @@ -101,8 +24,14 @@ fn display_level(
index: 0,
},
),
Transform::from_xyz(0.0, 200.0, 0.0).with_scale(Vec3::splat(0.5)),
StateScoped(GameState::Game),
Player,
));

commands.spawn((
Sprite::from_color(Color::linear_rgb(0.0, 1.0, 0.0), Vec2::new(1000.0, 80.0)),
Transform::from_xyz(0.0, -100.0, 0.0),
Ground,
StateScoped(GameState::Game),
));
}
144 changes: 17 additions & 127 deletions src/game/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,50 @@ use bevy::{

use crate::GameState;

use super::{AgainstWall, Ground, IsOnGround, Player, Velocity};
use super::{Ground, Player};

pub fn player_plugin(app: &mut App) {
app.add_systems(
FixedUpdate,
(
control_player,
on_ground,
moving,
player_animation,
death_by_fall,
gravity.after(on_ground),
// Uncommend to following line after you've done the exercises 6.4 to have srpites for the ground
// gravity
)
.run_if(in_state(GameState::Game)),
);
}

fn control_player(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut player: Query<(&mut Velocity, &IsOnGround), With<Player>>,
time: Res<Time>,
mut player: Query<&mut Transform, With<Player>>,
) {
let (mut velocity, is_on_ground) = player.single_mut();
if time.elapsed_secs() - is_on_ground.0 < 2.0 || velocity.jumping > 0.0 {
if keyboard_input.pressed(KeyCode::KeyA) {
velocity.target = -5.0;
} else if keyboard_input.pressed(KeyCode::KeyD) {
velocity.target = 5.0;
} else {
velocity.target = 0.0;
}
let mut player_transform = player.single_mut();
if keyboard_input.pressed(KeyCode::KeyA) {
player_transform.translation.x -= 5.0;
}
if time.elapsed_secs() - is_on_ground.0 < 0.5 && keyboard_input.pressed(KeyCode::Space) {
velocity.jumping = 15.0;
if keyboard_input.pressed(KeyCode::KeyD) {
player_transform.translation.x += 5.0;
}
}

fn on_ground(
mut player: Query<(&Transform, &mut IsOnGround, &mut AgainstWall), With<Player>>,
fn gravity(
mut player: Query<&mut Transform, With<Player>>,
ground: Query<&Transform, (Without<Player>, With<Ground>)>,
time: Res<Time>,
#[cfg(feature = "debug")] mut gizmos: Gizmos,
) {
let mut is_on_ground = false;
let mut is_against_wall = (false, false);
let (player_transform, mut player_on_ground, mut player_against_wall) = player.single_mut();
let mut player_transform = player.single_mut();

let player_aabb = Aabb2d::new(
Vec2::new(
player_transform.translation.x,
player_transform.translation.y - 128.0 / 4.0,
player_transform.translation.y,
),
Vec2::new(
128.0 * player_transform.scale.x,
(256.0 * 5.0 / 8.0) * player_transform.scale.y,
) / 2.0
* 0.8,
256.0 * player_transform.scale.y,
) / 2.0,
);

#[cfg(feature = "debug")]
{
use bevy::math::bounding::BoundingVolume;
gizmos.rect_2d(
player_aabb.center(),
player_aabb.half_size() * 2.,
Color::srgb(1.0, 0.0, 0.0),
);
}

for ground_transform in &ground {
let ground_aabb = Aabb2d::new(
Vec2::new(
Expand All @@ -87,95 +62,10 @@ fn on_ground(
);

if ground_aabb.intersects(&player_aabb) {
if ground_transform.translation.y
> player_transform.translation.y - 256.0 / 4.0 * player_transform.scale.y - 2.0
{
if ground_transform.translation.x < player_transform.translation.x {
is_against_wall.0 = true;
} else {
is_against_wall.1 = true;
}
} else {
is_on_ground = true;
}
is_on_ground = true;
}
}
if is_on_ground {
player_on_ground.0 = time.elapsed_secs();
}
if is_against_wall.0 != player_against_wall.0 {
player_against_wall.0 = is_against_wall.0;
}
if is_against_wall.1 != player_against_wall.1 {
player_against_wall.1 = is_against_wall.1;
}
}

fn gravity(mut player: Query<(&mut Transform, &IsOnGround), With<Player>>, time: Res<Time>) {
let (mut player_transform, player_on_ground) = player.single_mut();

if time.elapsed_secs() - player_on_ground.0 > 0.1 {
if !is_on_ground {
player_transform.translation.y -= 10.0;
}
}

fn moving(mut player: Query<(&mut Transform, &mut Velocity, &AgainstWall), With<Player>>) {
let (mut player_transform, mut velocity, against_wall) = player.single_mut();

if velocity.jumping > 0.0 {
player_transform.translation.y += velocity.jumping;
velocity.jumping -= 0.5;
}

if velocity.current != 0.0 {
if against_wall.0 && velocity.current < 0.0 {
velocity.current = 0.0;
}
if against_wall.1 && velocity.current > 0.0 {
velocity.current = 0.0;
}
player_transform.translation.x += velocity.current;
}
if velocity.current != velocity.target {
velocity.current += (velocity.target - velocity.current) / 10.0;
if velocity.current.abs() < 0.1 {
velocity.current = 0.0;
}
}
}

fn player_animation(
mut player: Query<(&mut Sprite, &Velocity), Changed<Transform>>,
mut steps: Local<u32>,
) {
if let Ok((mut sprite, velocity)) = player.get_single_mut() {
if velocity.jumping > 0.0 {
sprite.texture_atlas.as_mut().unwrap().index = 35;
} else {
*steps += 1;
if *steps % 10 == 0 {
sprite.texture_atlas.as_mut().unwrap().index =
if sprite.texture_atlas.as_ref().unwrap().index == 0 {
7
} else {
0
};
}
}
if velocity.current < 0.0 {
sprite.flip_x = true;
} else if velocity.current > 0.0 {
sprite.flip_x = false;
}
}
}

fn death_by_fall(
mut next: ResMut<NextState<GameState>>,
player_transform: Query<&Transform, With<Player>>,
) {
let player_transform = player_transform.single();
if player_transform.translation.y < -400.0 {
next.set(GameState::Menu);
}
}
71 changes: 0 additions & 71 deletions src/level_loader.rs

This file was deleted.

Loading

0 comments on commit 67096df

Please sign in to comment.