Skip to content

Commit 6937142

Browse files
author
Paul Reesman
committed
Add medium difficulty and main menu
1 parent b7ac725 commit 6937142

15 files changed

+340
-31
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "evil_penguin"
3-
version = "0.8.0"
3+
version = "0.8.1"
44
authors = ["Paul Reesman <[email protected]>"]
55
edition = "2018"
66

TODO.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
- [x] Player sprite
44
- [ ] Main menu
55
- [X] Title Menu
6-
- [ ] Main Menu
6+
- [x] Main Menu
77
- [ ] How to Play Menu
88
- [ ] Settings Menu
9-
- [ ] Play Menu
10-
- [ ] Pause Menu
9+
- [x] Play Menu
10+
- [x] Pause Menu
1111
- [x] End game menu
1212
- [ ] Configurable difficulty
13-
- [ ] Machine learned difficulty as hardest
13+
- [x] Easy
14+
- [x] Medium
15+
- [ ] Hard

resources/assets/ui_layouts/main_menu.ron

+52-3
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ Container(
1111
id: "main_title",
1212
anchor: Middle,
1313
x: 0.0,
14-
y: 100.0,
14+
y: 150.0,
1515
z: 1.0,
1616
height: 100.0,
1717
width: 500.0
1818
),
1919
text: (
20-
text: "Evil Penguin",
21-
font_size: 50,
20+
text: "Main Menu",
21+
font_size: 40,
2222
color: (1.0, 1.0, 1.0, 1.0),
2323
align: Middle
2424
)
@@ -31,6 +31,55 @@ Container(
3131
background: SolidColor(0.0, 0.0, 0.0, 1.0),
3232
children: [
3333
Button(
34+
transform: (
35+
id: "play_easy",
36+
anchor: Middle,
37+
x: 0.0,
38+
y: 100.0,
39+
z: 1.0,
40+
height: 50.0,
41+
width: 500.0
42+
),
43+
button: (
44+
id: 0,
45+
text: "Play: Easy",
46+
font_size: 20,
47+
normal_text_color: (1.0, 1.0, 1.0, 1.0)
48+
)
49+
),
50+
Button(
51+
transform: (
52+
id: "play_medium",
53+
anchor: Middle,
54+
x: 0.0,
55+
y: 50.0,
56+
z: 1.0,
57+
height: 50.0,
58+
width: 500.0
59+
),
60+
button: (
61+
id: 1,
62+
text: "Play: Medium",
63+
font_size: 20,
64+
normal_text_color: (1.0, 1.0, 1.0, 1.0)
65+
)
66+
),
67+
Button(
68+
transform: (
69+
id: "play_hard",
70+
anchor: Middle,
71+
x: 0.0,
72+
y: 0.0,
73+
z: 1.0,
74+
height: 50.0,
75+
width: 500.0
76+
),
77+
button: (
78+
id: 2,
79+
text: "Play: Hard",
80+
font_size: 20,
81+
normal_text_color: (1.0, 1.0, 1.0, 1.0)
82+
)
3483
)
3584
]
3685
)

src/states/loading.state.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ use crate::{
1616
RunState,
1717
menu::{
1818
LoseMenuState,
19+
MainMenuState,
1920
StartMenuState,
2021
WinMenuState
2122
}
2223
},
24+
systems::movement::Difficulty,
2325
util::types::SpritesheetLoadingData
2426
};
2527

@@ -28,7 +30,8 @@ use std::collections::HashMap;
2830
pub enum NextLoadingState {
2931
Paused,
3032
UnPaused,
31-
Run,
33+
Run(Difficulty),
34+
MainMenu,
3235
StartMenu,
3336
EndMenu(bool)
3437
}
@@ -45,12 +48,13 @@ impl SimpleState for LoadingState {
4548

4649
let sprite_sheet_dependencies = match self.next_state {
4750
NextLoadingState::Paused => PausedState::get_dependent_spritesheets(),
48-
NextLoadingState::Run => RunState::get_dependent_spritesheets(),
51+
NextLoadingState::Run(_) => RunState::get_dependent_spritesheets(),
4952
NextLoadingState::StartMenu => StartMenuState::get_dependent_spritesheets(),
5053
NextLoadingState::EndMenu(is_win) => match is_win {
5154
true => WinMenuState::get_dependent_spritesheets(),
5255
false => LoseMenuState::get_dependent_spritesheets()
5356
},
57+
NextLoadingState::MainMenu => MainMenuState::get_dependent_spritesheets(),
5458
_ => vec![]
5559
};
5660

@@ -61,22 +65,24 @@ impl SimpleState for LoadingState {
6165

6266
fn update(&mut self, _data: &mut StateData<GameData>) -> SimpleTrans {
6367
if self.progress_counter.is_complete() {
64-
return match self.next_state {
68+
return match &self.next_state {
6569
NextLoadingState::Paused => Trans::Switch(Box::new(PausedState::default())),
6670
NextLoadingState::UnPaused => Trans::Pop,
67-
NextLoadingState::Run => {
71+
NextLoadingState::Run(difficulty) => {
6872
let mut run_state = RunState::default();
73+
run_state.set_difficulty((*difficulty).clone());
6974
run_state.set_dependent_spritesheet_handles(&mut self.loading_assets);
7075
Trans::Switch(Box::new(run_state))
7176
},
7277
NextLoadingState::StartMenu => Trans::None,
7378
NextLoadingState::EndMenu(is_win) => {
74-
if is_win {
79+
if *is_win {
7580
return Trans::Switch(Box::new(WinMenuState::default()));
7681
}
7782

7883
Trans::Switch(Box::new(LoseMenuState::default()))
79-
}
84+
},
85+
NextLoadingState::MainMenu => Trans::Switch(Box::new(MainMenuState::default()))
8086
}
8187
}
8288

src/states/menu/lose_menu.state.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a, 'b> SimpleState for LoseMenuState<'a, 'b> {
4444
fn handle_event(&mut self, _data: StateData<'_, GameData<'_, '_>>, event: StateEvent) -> SimpleTrans {
4545
if let StateEvent::Window(e) = &event {
4646
if is_key_down(&e, VirtualKeyCode::Return) || is_key_down(&e, VirtualKeyCode::NumpadEnter) {
47-
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::Run)));
47+
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::MainMenu)));
4848
}
4949
}
5050

src/states/menu/main_menu.state.rs

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use amethyst::{
2+
assets::ProgressCounter,
3+
ecs::{Dispatcher, DispatcherBuilder},
4+
prelude::*,
5+
ui::{FontHandle, UiFinder, UiEventType}
6+
};
7+
8+
use crate::{
9+
states::{
10+
BaseState,
11+
LoadingState,
12+
NextLoadingState,
13+
menu::BaseMenuState
14+
},
15+
systems::movement::Difficulty,
16+
util::constants::MAIN_MENU_RON_PATH
17+
};
18+
19+
#[derive(Default)]
20+
pub struct MainMenuState<'a, 'b> {
21+
font: Option<FontHandle>,
22+
dispatcher: Option<Dispatcher<'a, 'b>>,
23+
progress_counter: ProgressCounter
24+
}
25+
26+
impl<'a, 'b> SimpleState for MainMenuState<'a, 'b> {
27+
fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
28+
let world = data.world;
29+
let dispatcher_builder = DispatcherBuilder::new();
30+
31+
self.dispatcher = self.initialize_dispatcher(world, dispatcher_builder);
32+
self.font = self.initialize_font(world);
33+
self.initialize_menu(world, MAIN_MENU_RON_PATH);
34+
self.initialize_camera(world);
35+
}
36+
37+
fn on_stop(&mut self, data: StateData<'_, GameData<'_, '_>>) {
38+
data.world.delete_all();
39+
}
40+
41+
fn handle_event(&mut self, data: StateData<'_, GameData<'_, '_>>, event: StateEvent) -> SimpleTrans {
42+
if let StateEvent::Ui(ui_event) = &event {
43+
if ui_event.event_type == UiEventType::Click {
44+
let (easy, medium, hard) = data.world.exec(|ui_finder: UiFinder<'_>| {
45+
(ui_finder.find("play_easy"), ui_finder.find("play_medium"), ui_finder.find("play_hard"))
46+
});
47+
48+
if Some(ui_event.target) == easy {
49+
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::Run(Difficulty::Easy))))
50+
} else if Some(ui_event.target) == medium {
51+
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::Run(Difficulty::Medium))))
52+
} else if Some(ui_event.target) == hard {
53+
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::Run(Difficulty::Hard))))
54+
}
55+
}
56+
}
57+
58+
Trans::None
59+
}
60+
61+
fn update(&mut self, data: &mut StateData<GameData>) -> SimpleTrans {
62+
if self.progress_counter.is_complete() {
63+
if let Some(dispatcher) = self.dispatcher.as_mut() {
64+
dispatcher.dispatch(&data.world);
65+
}
66+
}
67+
68+
Trans::None
69+
}
70+
}
71+
72+
impl<'a, 'b> BaseState for MainMenuState<'a,'b> {}
73+
74+
impl<'a, 'b, 'c> BaseMenuState<'_, '_> for MainMenuState<'a, 'b> {
75+
fn get_progress_counter(&mut self) -> &mut ProgressCounter {
76+
&mut self.progress_counter
77+
}
78+
}

src/states/menu/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#[path = "lose_menu.state.rs"]
22
mod lose_menu_state;
3+
#[path = "main_menu.state.rs"]
4+
mod main_menu_state;
35
#[path = "start_menu.state.rs"]
46
mod start_menu_state;
57
#[path = "win_menu.state.rs"]
68
mod win_menu_state;
79

810
pub use self::{
911
lose_menu_state::LoseMenuState,
12+
main_menu_state::MainMenuState,
1013
start_menu_state::StartMenuState,
1114
win_menu_state::WinMenuState
1215
};

src/states/menu/start_menu.state.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a, 'b> SimpleState for StartMenuState<'a, 'b> {
4444
fn handle_event(&mut self, _data: StateData<'_, GameData<'_, '_>>, event: StateEvent) -> SimpleTrans {
4545
if let StateEvent::Window(e) = &event {
4646
if is_key_down(&e, VirtualKeyCode::Return) || is_key_down(&e, VirtualKeyCode::NumpadEnter) {
47-
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::Run)));
47+
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::MainMenu)));
4848
}
4949
}
5050

src/states/menu/win_menu.state.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a, 'b> SimpleState for WinMenuState<'a, 'b> {
4444
fn handle_event(&mut self, _data: StateData<'_, GameData<'_, '_>>, event: StateEvent) -> SimpleTrans {
4545
if let StateEvent::Window(e) = &event {
4646
if is_key_down(&e, VirtualKeyCode::Return) || is_key_down(&e, VirtualKeyCode::NumpadEnter) {
47-
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::Run)));
47+
return Trans::Switch(Box::new(LoadingState::new(NextLoadingState::MainMenu)));
4848
}
4949
}
5050

src/states/run.state.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ use crate::{
3434
EndConditionSystem
3535
},
3636
movement::{
37-
PenguinMovementSystem,
37+
EasyPenguinMovementSystem,
38+
Difficulty,
39+
MediumPenguinMovementSystem,
3840
PlayerMovementSystem
3941
}
4042
},
@@ -58,6 +60,7 @@ use crate::{
5860
}
5961
};
6062
use std::collections::HashMap;
63+
use crate::systems::movement::HardPenguinMovementSystem;
6164

6265
/// Run State
6366
///
@@ -70,7 +73,8 @@ pub struct RunState<'a, 'b> {
7073
progress_counter: ProgressCounter,
7174
coin_texture_handle: Option<Handle<SpriteSheet>>,
7275
penguin_texture_handle: Option<Handle<SpriteSheet>>,
73-
player_texture_handle: Option<Handle<SpriteSheet>>
76+
player_texture_handle: Option<Handle<SpriteSheet>>,
77+
difficulty: Difficulty
7478
}
7579

7680
impl<'a, 'b> SimpleState for RunState<'a, 'b> {
@@ -127,7 +131,8 @@ impl<'a, 'b> RunState<'a, 'b> {
127131
progress_counter: ProgressCounter::new(),
128132
coin_texture_handle: None,
129133
penguin_texture_handle: None,
130-
player_texture_handle: None
134+
player_texture_handle: None,
135+
difficulty: Difficulty::Easy
131136
}
132137
}
133138

@@ -137,9 +142,15 @@ impl<'a, 'b> RunState<'a, 'b> {
137142

138143
fn initialize_dispatcher(&mut self, world: &mut World) {
139144
let mut dispatcher_builder = DispatcherBuilder::new();
140-
dispatcher_builder.add(CoinRotationSystem, "coin_rotation_system", &[]);
141145
dispatcher_builder.add(PlayerMovementSystem, "player_movement_system", &[]);
142-
dispatcher_builder.add(PenguinMovementSystem, "penguin_movement_system", &["player_movement_system"]);
146+
147+
match self.difficulty {
148+
Difficulty::Easy => dispatcher_builder.add(EasyPenguinMovementSystem, "penguin_movement_system", &["player_movement_system"]),
149+
Difficulty::Medium => dispatcher_builder.add(MediumPenguinMovementSystem, "penguin_movement_system", &["player_movement_system"]),
150+
Difficulty::Hard => dispatcher_builder.add(HardPenguinMovementSystem, "penguin_movement_system", &["player_movement_system"])
151+
}
152+
153+
dispatcher_builder.add(CoinRotationSystem, "coin_rotation_system", &[]);
143154
dispatcher_builder.add(CoinCollectionSystem, "coin_collection_system", &["player_movement_system"]);
144155
dispatcher_builder.add(EndConditionSystem, "end_condition_system", &["penguin_movement_system", "coin_collection_system"]);
145156

@@ -221,6 +232,10 @@ impl<'a, 'b> RunState<'a, 'b> {
221232
.with(EndConditionComponent::default())
222233
.build();
223234
}
235+
236+
pub fn set_difficulty(&mut self, difficulty: Difficulty) {
237+
self.difficulty = difficulty;
238+
}
224239
}
225240

226241
impl<'a, 'b> Default for RunState<'a, 'b> {

src/systems/movement/penguin_movement.system.rs src/systems/movement/easy_penguin_movement.system.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ use crate::{
1616
systems::movement::EntityMovement
1717
};
1818

19-
pub struct PenguinMovementSystem;
19+
pub struct EasyPenguinMovementSystem;
2020

21-
impl<'a> System<'a> for PenguinMovementSystem {
21+
impl<'a> System<'a> for EasyPenguinMovementSystem {
2222
type SystemData = (
2323
ReadStorage<'a, PenguinComponent>,
2424
ReadStorage<'a, PlayerComponent>,
@@ -29,21 +29,21 @@ impl<'a> System<'a> for PenguinMovementSystem {
2929
Read<'a, AssetStorage<SpriteSheet>>
3030
);
3131

32-
fn run(&mut self, (penguin, player, sprite_renders, mut transform, mut movement, time, spritesheet_storage): Self::SystemData) {
32+
fn run(&mut self, (penguin, player, sprite_renders, mut transform, mut movement, time, sprite_sheet_storage): Self::SystemData) {
3333
if let Some((player_transform, _)) = (&transform, &player).join().next() {
3434
let player_translation = player_transform.translation().clone();
3535
let (penguin_transform, penguin_movement, penguin_sprite_render, _) = (&mut transform, &mut movement, &sprite_renders, &penguin).join().next().unwrap();
3636
let penguin_translation = penguin_transform.translation().clone();
3737

38-
if let Some(penguin_spritesheet) = spritesheet_storage.get(&penguin_sprite_render.sprite_sheet) {
39-
let penguin_sprite = penguin_spritesheet.sprites.get(0).unwrap();
38+
if let Some(penguin_sprite_sheet) = sprite_sheet_storage.get(&penguin_sprite_render.sprite_sheet) {
39+
let penguin_sprite = penguin_sprite_sheet.sprites.get(0).unwrap();
4040
self.transform_entity(penguin_transform, &(player_translation, penguin_translation), &time, penguin_movement, penguin_sprite);
4141
}
4242
}
4343
}
4444
}
4545

46-
impl EntityMovement for PenguinMovementSystem {
46+
impl EntityMovement for EasyPenguinMovementSystem {
4747
type AccelerationDirection = (
4848
Vector3<f32>,
4949
Vector3<f32>

0 commit comments

Comments
 (0)