-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add intro dialog and parallax effect
- Loading branch information
1 parent
f8e4fb8
commit 1f5067e
Showing
19 changed files
with
278 additions
and
49 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
}); | ||
}); | ||
} | ||
} |
Oops, something went wrong.