Skip to content

Commit

Permalink
Random Level Generation (#63)
Browse files Browse the repository at this point in the history
Issue:
==============
Closes #54
Closes #9

What was done:
==============
* Added a random level generator that uses Perlin noise.
* Constrains the camera within the level boundaries.
* Added Tile and BorderTile components.
  • Loading branch information
mnmaita authored Nov 15, 2023
1 parent ccde544 commit b25bc5f
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 18 deletions.
96 changes: 91 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ bevy = { version = "0.12.0", default-features = false, features = [
"vorbis",
"x11",
] }
noise = "0.8.2"
rand = "0.7.3"

[profile.dev.package."*"]
opt-level = 3
60 changes: 58 additions & 2 deletions src/camera.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
use bevy::prelude::*;

use crate::game::Player;
use crate::{
game::Player,
level::{GRID_SIZE, HALF_TILE_SIZE, TILE_SIZE},
};

pub struct CameraPlugin;

impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, setup_camera);

app.add_systems(Update, update_camera.run_if(any_with_component::<Player>()));
app.add_systems(
Update,
(
update_camera.run_if(any_with_component::<Player>()),
constrain_camera_position_to_level,
)
.chain(),
);
}
}

Expand All @@ -26,3 +36,49 @@ fn update_camera(
camera_transform.translation.x = player_transform.translation.x;
camera_transform.translation.y = player_transform.translation.y;
}

fn constrain_camera_position_to_level(
mut camera_query: Query<(&Camera, &mut Transform), With<Camera2d>>,
#[cfg(debug_assertions)] mut gizmos: Gizmos,
) {
let (camera, mut camera_transform) = camera_query.single_mut();

if let Some(viewport_size) = camera.logical_viewport_size() {
let level_dimensions = GRID_SIZE * TILE_SIZE;
let viewport_size_remainder = viewport_size % TILE_SIZE;
let camera_boundary_size = (level_dimensions
- (viewport_size - viewport_size_remainder)
- viewport_size_remainder)
.clamp(Vec2::ZERO, Vec2::splat(f32::MAX));
let camera_boundary = Rect::from_center_size(-HALF_TILE_SIZE, camera_boundary_size);

if camera_boundary.is_empty() {
if viewport_size.x > level_dimensions.x {
camera_transform.translation.x = 0.0;
}
if viewport_size.y > level_dimensions.y {
camera_transform.translation.y = 0.0;
}
}

if camera_boundary.size() != Vec2::ZERO
&& !camera_boundary.contains(camera_transform.translation.truncate())
{
let (min_x, max_x) = (camera_boundary.min.x, camera_boundary.max.x);
let (min_y, max_y) = (camera_boundary.min.y, camera_boundary.max.y);
camera_transform.translation.x = camera_transform.translation.x.clamp(min_x, max_x);
camera_transform.translation.y = camera_transform.translation.y.clamp(min_y, max_y);
}

#[cfg(debug_assertions)]
{
gizmos.rect_2d(
camera_boundary.center(),
0.,
camera_boundary.size(),
Color::RED,
);
gizmos.circle_2d(camera_transform.translation.truncate(), 10., Color::RED);
}
}
}
12 changes: 1 addition & 11 deletions src/game/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,6 @@ pub struct GamePlugin;

impl Plugin for GamePlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(AppState::InGame), (draw_background, spawn_player));
app.add_systems(OnEnter(AppState::InGame), spawn_player);
}
}

fn draw_background(mut commands: Commands, asset_server: Res<AssetServer>) {
let texture = asset_server
.get_handle("textures/background.png")
.unwrap_or_default();
commands.spawn(SpriteBundle {
texture,
..default()
});
}
Loading

0 comments on commit b25bc5f

Please sign in to comment.