Skip to content

Commit

Permalink
Add intro dialog and parallax effect
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasmerlin committed Dec 9, 2023
1 parent f8e4fb8 commit 1f5067e
Show file tree
Hide file tree
Showing 19 changed files with 278 additions and 49 deletions.
Binary file added assets/bases/t-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/bases/t-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/bases/t-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/bases/t-7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/bases/t-9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/parallax/00_sky.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/parallax/01_far_city.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/parallax/02_middle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/parallax/03_main.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/parallax/04_street.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/parallax/05_foreground.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 5 additions & 5 deletions src/camera_movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@ pub fn camera_movement_system(
Without<Falling>,
)>,
) {
let mut highest = 0.0;
let mut highest = 100.0;
for (transform, block, ..) in query.iter_mut() {
if transform.translation.y > highest {
highest = transform.translation.y;
}
}

highest += 00.0;
let target_height = highest - 100.0;

let increase = 1.0;

if highest > camera_movement.height {
if target_height > camera_movement.height {
camera_movement.height += increase;
} else if highest < camera_movement.height - increase {
} else if target_height < camera_movement.height - increase {
camera_movement.height -= increase;
}

for mut transform in camera_query.iter_mut() {
transform.translation.y = camera_movement.height * 0.5 + 25.0;
transform.translation.y = camera_movement.height;
// camera should slowly zoom out as we get higher
//transform.scale = Vec3::new(1.0, 1.0, 1.0) * (1.0 + camera_movement.height / 1000.0);
}
Expand Down
6 changes: 5 additions & 1 deletion src/environment/car.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rand::{random, thread_rng, Rng};
use crate::block::{DestroyBlockOnContact, BLOCK_COLLISION_GROUP};
use crate::floor::FLOOR_COLLISION_GROUP;
use crate::level::{LevelLifecycle, UpdateLevelStats};
use crate::{CAR_MAX_HEIGHT, CAR_MIN_HEIGHT};

pub struct CarPlugin;

Expand Down Expand Up @@ -69,7 +70,10 @@ pub fn spawn_car_system(

let direction = if random() { 1.0 } else { -1.0 };

let car_position = Vec2::new(direction * 1000.0, random::<f32>() * 40.0 + -50.0);
let car_position = Vec2::new(
direction * 1000.0,
thread_rng().gen_range(CAR_MIN_HEIGHT..CAR_MAX_HEIGHT),
);

let car_velocity = Vec2::new(direction * -thread_rng().gen_range(70.0..100.0), 0.0);

Expand Down
175 changes: 153 additions & 22 deletions src/environment/city.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,174 @@
use crate::state::LevelState;
use crate::VERTICAL_VIEWPORT_SIZE;
use bevy::prelude::*;
use bevy::sprite::Anchor;

use crate::state::LevelState;
use crate::{MainCamera, FLOOR_HEIGHT, VERTICAL_VIEWPORT_SIZE};

pub struct CityPlugin;

impl Plugin for CityPlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(LevelState::Playing), (setup_city));
app.add_systems(OnEnter(LevelState::Playing), (setup_city))
.add_systems(Update, update_auto_width);
}
}

#[derive(Component)]
pub struct AutoWidth {
aspect_ratio: f32,
open_top: bool,
parallax: f32,
}

pub fn setup_city(mut commands: Commands, assets: Res<AssetServer>) {
commands.spawn(
(SpriteBundle {
transform: Transform::from_xyz(0.0, 20.0, 100.0),
texture: assets.load("foreground.png"),
let asset_size = Vec2::new(3840.0, 4634.0);

let aspect_ratio = asset_size.y / asset_size.x;

commands.spawn((
AutoWidth {
aspect_ratio,
open_top: true,
parallax: 0.5,
},
SpriteBundle {
transform: Transform::from_xyz(0.0, 0.0, 100.0),
texture: assets.load("parallax/05_foreground.png"),
sprite: Sprite {
custom_size: Some(Vec2::new(1.0, aspect_ratio)),
anchor: Anchor::BottomCenter,
..Default::default()
},
..Default::default()
},
));

commands.spawn((
AutoWidth {
aspect_ratio: 691.0 / 3840.0,
open_top: true,
parallax: 0.0,
},
SpriteBundle {
transform: Transform::from_xyz(0.0, 0.0, -5.0),
texture: assets.load("parallax/04_street.png"),
sprite: Sprite {
custom_size: Some(Vec2::new(1.0, 691.0 / 3840.0)),
anchor: Anchor::BottomCenter,
..Default::default()
},
..Default::default()
},
));
commands.spawn((
AutoWidth {
aspect_ratio: 818.0 / 3840.0,
open_top: true,
parallax: 0.0,
},
SpriteBundle {
transform: Transform::from_xyz(0.0, 0.0, -10.0),
texture: assets.load("parallax/03_main.png"),
sprite: Sprite {
custom_size: Some(Vec2::new(
VERTICAL_VIEWPORT_SIZE * 16.0 / 9.0,
VERTICAL_VIEWPORT_SIZE,
)),
custom_size: Some(Vec2::new(1.0, 818.0 / 3840.0)),
anchor: Anchor::BottomCenter,
..Default::default()
},
..Default::default()
}),
);
},
));
commands.spawn((
AutoWidth {
aspect_ratio,
open_top: true,
parallax: -0.2,
},
SpriteBundle {
transform: Transform::from_xyz(0.0, 0.0, -20.0),
texture: assets.load("parallax/02_middle.png"),
sprite: Sprite {
custom_size: Some(Vec2::new(1.0, aspect_ratio)),
anchor: Anchor::BottomCenter,
..Default::default()
},
..Default::default()
},
));
commands.spawn((
AutoWidth {
aspect_ratio,
open_top: true,
parallax: -0.4,
},
SpriteBundle {
transform: Transform::from_xyz(0.0, 0.0, -30.0),
texture: assets.load("parallax/01_far_city.png"),
sprite: Sprite {
custom_size: Some(Vec2::new(1.0, aspect_ratio)),
anchor: Anchor::BottomCenter,
..Default::default()
},
..Default::default()
},
));

commands.spawn(
(SpriteBundle {
commands.spawn((
AutoWidth {
aspect_ratio,
open_top: false,
parallax: -0.5,
},
SpriteBundle {
transform: Transform::from_xyz(0.0, 0.0, -100.0),
texture: assets.load("background.png"),
texture: assets.load("parallax/00_sky.png"),
sprite: Sprite {
custom_size: Some(Vec2::new(
VERTICAL_VIEWPORT_SIZE * 16.0 / 9.0,
VERTICAL_VIEWPORT_SIZE,
)),
custom_size: Some(Vec2::new(1.0, aspect_ratio)),
anchor: Anchor::BottomCenter,
..Default::default()
},
..Default::default()
}),
);
},
));
}

pub fn update_auto_width(
mut query: Query<(&AutoWidth, &mut Transform)>,
transform: Query<(&GlobalTransform, &Camera), With<MainCamera>>,
) {
let (camera_transform, camera) = transform.single();
let viewport = camera.logical_viewport_size().unwrap();
let top_left = camera
.viewport_to_world_2d(
camera_transform,
Vec2::new(-viewport.x / 2.0, viewport.y / 2.0),
)
.unwrap();
let bottom_right = camera
.viewport_to_world_2d(
camera_transform,
Vec2::new(viewport.x / 2.0, -viewport.y / 2.0),
)
.unwrap();

let world_width = bottom_right.x - top_left.x;
let world_height = bottom_right.y - top_left.y;

let world_aspect_ratio = world_width / world_height;

for (auto_width, mut transform) in &mut query.iter_mut() {
// the images should be scaled so they always fill the screen

transform.translation.y =
-VERTICAL_VIEWPORT_SIZE / 2.0 - camera_transform.translation().y * auto_width.parallax;

if world_aspect_ratio > auto_width.aspect_ratio || auto_width.open_top {
// the world is wider than the image
transform.scale.x = world_width;
transform.scale.y = world_width;
} else {
// the world is taller than the image
transform.scale.x = world_height * auto_width.aspect_ratio;
transform.scale.y = world_height * auto_width.aspect_ratio;
}
}
}
10 changes: 5 additions & 5 deletions src/floor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ pub fn setup_floor(mut commands: Commands) {

commands.spawn((
SpriteBundle {
sprite: Sprite {
custom_size: Some(Vec2::new(width, height)),
color: Color::rgb(0.0, 0.0, 0.0),
..Default::default()
},
// sprite: Sprite {
// custom_size: Some(Vec2::new(width, height)),
// color: Color::rgb(0.0, 0.0, 0.0),
// ..Default::default()
// },
transform: Transform::from_xyz(0.0, -height / 2.0 + FLOOR_HEIGHT, 0.0),
..Default::default()
},
Expand Down
19 changes: 19 additions & 0 deletions src/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ pub struct LevelBase {
pub rotation: f32,
}

#[derive(Debug, Clone)]
pub enum LaunchPlatformKind {
Static,
Vertical,
Free,
}

#[derive(Debug, Clone)]
pub struct LaunchPlatform {
pub translation: Vec2,
pub kind: LaunchPlatformKind,
}

const fn default_level_base() -> LevelBase {
LevelBase {
width: 100.0,
Expand All @@ -72,6 +85,7 @@ pub struct Level {
pub bases: &'static [LevelBase],
pub enabled_effects: &'static [(EffectType, f32)],
pub effect_likelihood: f32,
pub intro_text: &'static str,
}

pub const DEFAULT_EFFECTS: [(EffectType, f32); 2] =
Expand All @@ -88,6 +102,7 @@ pub const DEFAULT_LEVEL: Level = Level {
}],
enabled_effects: &DEFAULT_EFFECTS,
effect_likelihood: 0.05,
intro_text: "Welcome to the game!",
};

#[derive(Debug, Clone)]
Expand All @@ -105,6 +120,7 @@ pub struct LevelLifecycle;
pub static LEVELS: [Level; 6] = [
Level {
level: 0,
intro_text: "Test Level",
goal: LevelGoal::ReachHeight(200.0),
time_limit: Some(Duration::from_secs(60)),
max_blocks: None,
Expand All @@ -116,6 +132,9 @@ pub static LEVELS: [Level; 6] = [
},
Level {
level: 1,
intro_text: "Welcome to your first day at Big Bad Buildings, Inc. Your job is to operate the Tower Thrower 3000, a state-of-the-art machine that constructs buildings by throwing blocks.\
For your first building, reach a target height of 200m.\
",
goal: LevelGoal::ReachHeight(200.0),
time_limit: Some(Duration::from_secs(60)),
max_blocks: None,
Expand Down
56 changes: 56 additions & 0 deletions src/level_intro_dialog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::level::Level;
use crate::state::LevelState;
use bevy::prelude::*;
use bevy_egui::egui::{Color32, Frame};
use bevy_egui::{egui, EguiContext, EguiContexts};

pub struct LevelIntroDialogPlugin;

impl Plugin for LevelIntroDialogPlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(LevelState::Playing), setup_level_intro_dialog)
.add_systems(Update, update_level_intro_dialog)
.init_resource::<LevelIntroDialog>();
}
}

#[derive(Resource, Default)]
pub struct LevelIntroDialog {
pub visible: bool,
}

pub fn setup_level_intro_dialog(mut dialog: ResMut<LevelIntroDialog>) {
dialog.visible = true;
}

pub fn update_level_intro_dialog(
mut dialog: ResMut<LevelIntroDialog>,
mut egui: EguiContexts,
level: Res<Level>,
) {
if dialog.visible {
egui::Window::new("Level Intro")
.collapsible(false)
.resizable(false)
.title_bar(false)
.anchor(egui::Align2::CENTER_CENTER, egui::Vec2::ZERO)
.frame(
Frame::none()
.fill(Color32::from_rgba_unmultiplied(0, 0, 0, 250))
.inner_margin(8.0),
)
.show(egui.ctx_mut(), |ui| {
ui.set_min_size(egui::Vec2::new(400.0, 300.0));

ui.heading("Level Intro");

ui.label(level.intro_text);

ui.with_layout(egui::Layout::bottom_up(egui::Align::Center), |ui| {
if ui.button("START").clicked() {
dialog.visible = false;
}
});
});
}
}
Loading

0 comments on commit 1f5067e

Please sign in to comment.