Skip to content

Commit

Permalink
feat: game jam version 🍓
Browse files Browse the repository at this point in the history
change: new input binding system based on events (easier to use)
chore: cleanup
  • Loading branch information
eerii committed Dec 2, 2023
1 parent d4c90ff commit 035bfbe
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 202 deletions.
47 changes: 26 additions & 21 deletions examples/dvd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ pub struct SampleGamePlugin;
impl Plugin for SampleGamePlugin {
fn build(&self, app: &mut App) {
app.add_event::<CollisionEvent>()
.add_systems(OnEnter(GameState::Play), init_sample)
.add_systems(
OnEnter(GameState::Play),
(init_sample.run_if(run_once()), resume_game),
)
.add_systems(
Update,
(update_sample, on_collision).run_if(in_state(GameState::Play)),
Expand All @@ -52,13 +55,6 @@ impl Plugin for SampleGamePlugin {
}
}

// ·········
// Resources
// ·········

#[derive(Resource)]
struct GameInfo;

// ··········
// Components
// ··········
Expand Down Expand Up @@ -87,18 +83,12 @@ fn init_sample(
mut cmd: Commands,
assets: Res<GameAssets>,
opts: Res<Persistent<GameOptions>>,
info: Option<Res<GameInfo>>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
// Camera
cmd.spawn((Camera2dBundle::default(), GameCamera));

if info.is_some() {
debug!("Game already initialized");
return;
}
cmd.insert_resource(GameInfo);

// Background
cmd.spawn(MaterialMesh2dBundle {
mesh: meshes.add(Mesh::from(shape::Quad::default())).into(),
Expand Down Expand Up @@ -152,13 +142,17 @@ fn update_sample(
let win_bound = Rect::from_center_size(Vec2::ZERO, SIZE);

for (entity, mut trans, mut vel, sprite) in objects.iter_mut() {
// Update position based on velocity
let t = &mut trans.translation;
*t += vel.0.extend(0.) * time.delta_seconds();

// Calculate the sprite bound
let obj_bound = Rect::from_center_size(
Vec2::new(t.x, t.y),
sprite.custom_size.expect("Sprite has a custom size"),
sprite.custom_size.expect("Sprite needs a custom size"),
);

// Calculate the interection with the level borders and send a collision event
let intersection = win_bound.intersect(obj_bound).size();
if intersection.x < obj_bound.width() {
vel.0.x *= -1.;
Expand All @@ -182,6 +176,7 @@ fn on_collision(
) {
let (mut text, mut counter) = counter.single_mut();

// On each collision, increase the counter, change the spirte color and play audio
for CollisionEvent(entity) in event_collision.read() {
counter.0 += 1;
text.sections[0].value = counter.0.to_string();
Expand All @@ -194,12 +189,22 @@ fn on_collision(
}
}

fn random_color() -> Color {
Color::hsl(rand::random::<f32>() * 360., 0.8, 0.8)
fn resume_game(mut cam: Query<&mut Camera, With<GameCamera>>) {
if let Ok(mut cam) = cam.get_single_mut() {
cam.is_active = true;
}
}

fn pause_game(mut cmd: Commands, query: Query<Entity, With<GameCamera>>) {
for entity in query.iter() {
cmd.entity(entity).despawn_recursive();
fn pause_game(mut cam: Query<&mut Camera, With<GameCamera>>) {
if let Ok(mut cam) = cam.get_single_mut() {
cam.is_active = false;
}
}

// ·····
// Extra
// ·····

fn random_color() -> Color {
Color::hsl(rand::random::<f32>() * 360., 0.8, 0.8)
}
53 changes: 22 additions & 31 deletions examples/jump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bevy_embedded_assets::{EmbeddedAssetPlugin, PluginMode};
use bevy_persistent::Persistent;
use hello_bevy::{
config::{GameOptions, Keybinds},
input::InputState,
input::Bind,
load::GameAssets,
GamePlugin, GameState,
};
Expand Down Expand Up @@ -52,19 +52,15 @@ pub struct SampleGamePlugin;

impl Plugin for SampleGamePlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(GameState::Play), init_sample)
.add_systems(Update, update_sample.run_if(in_state(GameState::Play)))
.add_systems(OnExit(GameState::Play), pause_game);
app.add_systems(
OnEnter(GameState::Play),
(init_sample.run_if(run_once()), resume_game),
)
.add_systems(Update, update_sample.run_if(in_state(GameState::Play)))
.add_systems(OnExit(GameState::Play), pause_game);
}
}

// ·········
// Resources
// ·········

#[derive(Resource)]
struct GameInfo;

// ··········
// Components
// ··········
Expand All @@ -88,18 +84,12 @@ fn init_sample(
mut cmd: Commands,
assets: Res<GameAssets>,
opts: Res<Persistent<GameOptions>>,
info: Option<Res<GameInfo>>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
// Camera
cmd.spawn((Camera2dBundle::default(), GameCamera));

if info.is_some() {
debug!("Game already initialized");
return;
}
cmd.insert_resource(GameInfo);

// Background
cmd.spawn(MaterialMesh2dBundle {
mesh: meshes.add(Mesh::from(shape::Quad::default())).into(),
Expand Down Expand Up @@ -145,14 +135,9 @@ fn update_sample(
time: Res<Time>,
mut objects: Query<(&mut Player, &mut Transform)>,
mut counter: Query<(&mut Text, &mut Counter)>,
keyboard: Res<Input<KeyCode>>,
mouse: Res<Input<MouseButton>>,
gamepads: Res<Gamepads>,
gamepad_buttons: Res<Input<GamepadButton>>,
input: Res<Input<Bind>>,
keybinds: Res<Persistent<Keybinds>>,
) {
let input = InputState::new(&keyboard, &mouse, &gamepads, &gamepad_buttons);

for (mut player, mut trans) in objects.iter_mut() {
let t = &mut trans.translation;

Expand All @@ -169,7 +154,7 @@ fn update_sample(
}

// Jump
if input.just_pressed(&keybinds.jump).unwrap_or(false) {
if keybinds.jump.iter().any(|bind| input.just_pressed(*bind)) {
player.velocity.y = JUMP_VEL;

let (mut text, mut counter) = counter.single_mut();
Expand All @@ -178,25 +163,31 @@ fn update_sample(
}

// Move
if input.pressed(&keybinds.left).unwrap_or(false) {
if keybinds.left.iter().any(|bind| input.pressed(*bind)) {
player.velocity.x = -MOVE_VEL;
} else if input.pressed(&keybinds.right).unwrap_or(false) {
} else if keybinds.right.iter().any(|bind| input.pressed(*bind)) {
player.velocity.x = MOVE_VEL;
} else if player.velocity.x.abs() > MOVE_CUTOFF {
player.velocity.x *= MOVE_FACTOR;
} else {
player.velocity.x = 0.;
}

// Move
// Update position based on velocity and add bounds
*t += player.velocity.extend(0.) * time.delta_seconds();
t.y = t.y.max(-SIZE.y * 0.4);
t.x = (t.x + SIZE.x * 0.5).rem_euclid(SIZE.x) - SIZE.x * 0.5;
}
}

fn pause_game(mut cmd: Commands, query: Query<Entity, With<GameCamera>>) {
for entity in query.iter() {
cmd.entity(entity).despawn_recursive();
fn resume_game(mut cam: Query<&mut Camera, With<GameCamera>>) {
if let Ok(mut cam) = cam.get_single_mut() {
cam.is_active = true;
}
}

fn pause_game(mut cam: Query<&mut Camera, With<GameCamera>>) {
if let Ok(mut cam) = cam.get_single_mut() {
cam.is_active = false;
}
}
9 changes: 9 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ pub struct Keybinds {
pub pause: Vec<Bind>,
}

impl Keybinds {
pub fn all(&self) -> Vec<&Bind> {
self.iter_fields()
.filter_map(|f| f.downcast_ref::<Vec<Bind>>())
.flatten()
.collect()
}
}

impl Default for Keybinds {
fn default() -> Self {
Self {
Expand Down
4 changes: 2 additions & 2 deletions src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,11 @@ mod only_in_debug {

let graph_dir = Path::new(".data").join("graphs");
if !graph_dir.exists() {
std::fs::create_dir(&graph_dir).expect("Failed to create graph directory");
std::fs::create_dir_all(&graph_dir).expect("Failed to create graph directory");
}

std::fs::write(graph_dir.join(format!("{}.dot", name)), dot)
.expect("Failed to write graph");
.unwrap_or_else(|e| warn!("Failed to save graph: {}", e));

if let Err(e) = std::process::Command::new("dot")
.arg("-Tsvg")
Expand Down
Loading

0 comments on commit 035bfbe

Please sign in to comment.