From e09c2213d798191dec548b8338124befff836eb5 Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sat, 25 Mar 2023 15:41:04 +0800
Subject: [PATCH 1/9] Added R key to reset game
---
examples/invaders/simple-invaders/src/lib.rs | 79 ++++++++++++++------
examples/invaders/src/main.rs | 9 +++
2 files changed, 64 insertions(+), 24 deletions(-)
diff --git a/examples/invaders/simple-invaders/src/lib.rs b/examples/invaders/simple-invaders/src/lib.rs
index 97921fb9..f4deaf7a 100644
--- a/examples/invaders/simple-invaders/src/lib.rs
+++ b/examples/invaders/simple-invaders/src/lib.rs
@@ -459,6 +459,43 @@ impl World {
});
}
}
+
+ pub fn reset_game(&mut self) {
+ // Recreate the alien
+ self.invaders = Invaders {
+ grid: make_invader_grid(&self.assets),
+ stepper: Point::new(COLS - 1, 0),
+ direction: Direction::Right,
+ descend: false,
+ bounds: Bounds::default(),
+ };
+
+ // Empty laser
+ self.lasers.clear();
+
+ // Recreate the shield
+ self.shields = (0..4)
+ .map(|i| Shield {
+ sprite: Sprite::new(&self.assets, Frame::Shield1),
+ pos: Point::new(i * 45 + 32, 192),
+ })
+ .collect();
+
+ // Reset player position
+ self.player.pos = PLAYER_START;
+
+ // Remove bullet
+ self.bullet = None;
+
+ // Reset collision state
+ self.collision.clear();
+
+ // Reset game score
+ self._score = 0;
+
+ // Set gameover to false
+ self.gameover = false;
+ }
}
/// Create a default `World` with a static PRNG seed.
@@ -498,46 +535,40 @@ impl Invaders {
let mut right = 0;
let mut bottom = 0;
let mut left = COLS;
-
+
// Scan through the entire grid
for (y, row) in self.grid.iter().enumerate() {
- for (x, col) in row.iter().enumerate() {
- if col.is_some() {
- // Build a boundary box of invaders in the grid
- if top > y {
- top = y;
- }
- if bottom < y {
- bottom = y;
- }
- if left > x {
- left = x;
- }
- if right < x {
- right = x;
- }
- }
- }
+ row.iter().enumerate().filter(|(_, col)| col.is_some()).for_each(|(x, _)| {
+ top = top.min(y);
+ bottom = bottom.max(y);
+ left = left.min(x);
+ right = right.max(x);
+ });
}
-
+
if top > bottom || left > right {
// No more invaders left alive
return true;
}
-
+
+ let bounds_changed = self.bounds.left_col != left
+ || self.bounds.right_col != right
+ || self.bounds.top_row != top
+ || self.bounds.bottom_row != bottom;
+
// Adjust the bounding box position
self.bounds.pos.x += (left - self.bounds.left_col) * GRID.x;
self.bounds.pos.y += (top - self.bounds.top_row) * GRID.y;
-
+
// Adjust the bounding box columns and rows
self.bounds.left_col = left;
self.bounds.right_col = right;
self.bounds.top_row = top;
self.bounds.bottom_row = bottom;
-
- // No more changes
- false
+
+ bounds_changed
}
+
fn get_closest_invader(&self, mut col: usize) -> &Invader {
let mut row = ROWS - 1;
diff --git a/examples/invaders/src/main.rs b/examples/invaders/src/main.rs
index 299bfd63..5edb6783 100644
--- a/examples/invaders/src/main.rs
+++ b/examples/invaders/src/main.rs
@@ -95,6 +95,10 @@ impl Game {
Controls { direction, fire }
};
}
+
+ fn reset_game(&mut self) {
+ self.world.reset_game();
+ }
}
fn main() -> Result<(), Error> {
@@ -165,6 +169,11 @@ fn main() -> Result<(), Error> {
return;
}
+ // Reset game
+ if g.game.input.key_pressed(VirtualKeyCode::R) {
+ g.game.reset_game();
+ }
+
// Resize the window
if let Some(size) = g.game.input.window_resized() {
if let Err(err) = g.game.pixels.resize_surface(size.width, size.height) {
From aa94512b16c1ce4af28c192018533a94e777f885 Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sat, 25 Mar 2023 15:58:21 +0800
Subject: [PATCH 2/9] Format code
---
examples/invaders/simple-invaders/src/lib.rs | 28 +++++++++++---------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/examples/invaders/simple-invaders/src/lib.rs b/examples/invaders/simple-invaders/src/lib.rs
index f4deaf7a..0e8cac5a 100644
--- a/examples/invaders/simple-invaders/src/lib.rs
+++ b/examples/invaders/simple-invaders/src/lib.rs
@@ -535,40 +535,42 @@ impl Invaders {
let mut right = 0;
let mut bottom = 0;
let mut left = COLS;
-
+
// Scan through the entire grid
for (y, row) in self.grid.iter().enumerate() {
- row.iter().enumerate().filter(|(_, col)| col.is_some()).for_each(|(x, _)| {
- top = top.min(y);
- bottom = bottom.max(y);
- left = left.min(x);
- right = right.max(x);
- });
+ row.iter()
+ .enumerate()
+ .filter(|(_, col)| col.is_some())
+ .for_each(|(x, _)| {
+ top = top.min(y);
+ bottom = bottom.max(y);
+ left = left.min(x);
+ right = right.max(x);
+ });
}
-
+
if top > bottom || left > right {
// No more invaders left alive
return true;
}
-
+
let bounds_changed = self.bounds.left_col != left
|| self.bounds.right_col != right
|| self.bounds.top_row != top
|| self.bounds.bottom_row != bottom;
-
+
// Adjust the bounding box position
self.bounds.pos.x += (left - self.bounds.left_col) * GRID.x;
self.bounds.pos.y += (top - self.bounds.top_row) * GRID.y;
-
+
// Adjust the bounding box columns and rows
self.bounds.left_col = left;
self.bounds.right_col = right;
self.bounds.top_row = top;
self.bounds.bottom_row = bottom;
-
+
bounds_changed
}
-
fn get_closest_invader(&self, mut col: usize) -> &Invader {
let mut row = ROWS - 1;
From 42f82d7cd1302d3379e5da845f5d8e4312ce4dc8 Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sat, 25 Mar 2023 17:05:39 +0800
Subject: [PATCH 3/9] Restore 'false'
---
examples/invaders/simple-invaders/src/lib.rs | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/examples/invaders/simple-invaders/src/lib.rs b/examples/invaders/simple-invaders/src/lib.rs
index 0e8cac5a..cd3240b6 100644
--- a/examples/invaders/simple-invaders/src/lib.rs
+++ b/examples/invaders/simple-invaders/src/lib.rs
@@ -554,11 +554,6 @@ impl Invaders {
return true;
}
- let bounds_changed = self.bounds.left_col != left
- || self.bounds.right_col != right
- || self.bounds.top_row != top
- || self.bounds.bottom_row != bottom;
-
// Adjust the bounding box position
self.bounds.pos.x += (left - self.bounds.left_col) * GRID.x;
self.bounds.pos.y += (top - self.bounds.top_row) * GRID.y;
@@ -569,7 +564,7 @@ impl Invaders {
self.bounds.top_row = top;
self.bounds.bottom_row = bottom;
- bounds_changed
+ false
}
fn get_closest_invader(&self, mut col: usize) -> &Invader {
From b7fe9bb351a5134769758ff69c5db2f804b84114 Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sat, 25 Mar 2023 17:07:01 +0800
Subject: [PATCH 4/9] Restore 'false'
---
examples/invaders/simple-invaders/src/lib.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/examples/invaders/simple-invaders/src/lib.rs b/examples/invaders/simple-invaders/src/lib.rs
index cd3240b6..f824c10b 100644
--- a/examples/invaders/simple-invaders/src/lib.rs
+++ b/examples/invaders/simple-invaders/src/lib.rs
@@ -564,6 +564,7 @@ impl Invaders {
self.bounds.top_row = top;
self.bounds.bottom_row = bottom;
+ // No more changes
false
}
From 04f9100dc3e27c9437e0093990139bbc169da9c3 Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sat, 25 Mar 2023 17:49:16 +0800
Subject: [PATCH 5/9] [Fix] /examples/invaders/README.md
---
examples/invaders/README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/examples/invaders/README.md b/examples/invaders/README.md
index 43970d22..7f9f73d9 100644
--- a/examples/invaders/README.md
+++ b/examples/invaders/README.md
@@ -18,6 +18,8 @@ cargo run --release --package invaders
Pause P: Pause
+Reset R: Reset Game
+
## GamePad Controls
`D-Pad 🡰` `D-Pad 🡲`: Move tank
From 62359c5fdd0d148e0b113e61da5e9deb3cd59f21 Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sat, 25 Mar 2023 18:05:39 +0800
Subject: [PATCH 6/9] [Fix] /examples/invaders/README.md
---
examples/invaders/README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/examples/invaders/README.md b/examples/invaders/README.md
index 7f9f73d9..18c2f898 100644
--- a/examples/invaders/README.md
+++ b/examples/invaders/README.md
@@ -18,7 +18,9 @@ cargo run --release --package invaders
Pause P: Pause
-Reset R: Reset Game
+R: Reset Game
+
+escape: Quit
## GamePad Controls
From 9a545f7b1ee23707ed9eb3f9526750d28d3e441c Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sun, 26 Mar 2023 12:14:50 +0800
Subject: [PATCH 7/9] Invaders, Shield, Player module processing
---
examples/invaders/simple-invaders/src/lib.rs | 69 ++++++++++++--------
1 file changed, 41 insertions(+), 28 deletions(-)
diff --git a/examples/invaders/simple-invaders/src/lib.rs b/examples/invaders/simple-invaders/src/lib.rs
index f824c10b..6686e850 100644
--- a/examples/invaders/simple-invaders/src/lib.rs
+++ b/examples/invaders/simple-invaders/src/lib.rs
@@ -140,6 +140,17 @@ trait DeltaTime {
}
}
+impl Player {
+ pub fn new(assets: &Assets) -> Self {
+ let sprite = SpriteRef::new(assets, Frame::Player1, Duration::from_millis(100));
+ let pos = PLAYER_START;
+ let dt = Duration::default();
+
+ Player { sprite, pos, dt }
+ }
+}
+
+
impl DeltaTime for Player {
fn update(&mut self) -> usize {
Self::update_dt(&mut self.dt, ONE_FRAME)
@@ -184,31 +195,17 @@ impl World {
/// let world = World::new(seed, false);
/// ```
pub fn new(seed: (u64, u64), debug: bool) -> World {
- use Frame::*;
// Load assets first
let assets = load_assets();
// TODO: Create invaders one-at-a-time
- let invaders = Invaders {
- grid: make_invader_grid(&assets),
- stepper: Point::new(COLS - 1, 0),
- direction: Direction::Right,
- descend: false,
- bounds: Bounds::default(),
- };
+ let invaders = Invaders::new(&assets);
let lasers = Vec::new();
let shields = (0..4)
- .map(|i| Shield {
- sprite: Sprite::new(&assets, Shield1),
- pos: Point::new(i * 45 + 32, 192),
- })
+ .map(|i| Shield::new(&assets, Point::new(i * 45 + 32, 192)))
.collect();
- let player = Player {
- sprite: SpriteRef::new(&assets, Player1, Duration::from_millis(100)),
- pos: PLAYER_START,
- dt: Duration::default(),
- };
+ let player = Player::new(&assets);
let bullet = None;
let collision = Collision::default();
let _score = 0;
@@ -462,23 +459,14 @@ impl World {
pub fn reset_game(&mut self) {
// Recreate the alien
- self.invaders = Invaders {
- grid: make_invader_grid(&self.assets),
- stepper: Point::new(COLS - 1, 0),
- direction: Direction::Right,
- descend: false,
- bounds: Bounds::default(),
- };
+ self.invaders = Invaders::new(&self.assets);
// Empty laser
self.lasers.clear();
// Recreate the shield
self.shields = (0..4)
- .map(|i| Shield {
- sprite: Sprite::new(&self.assets, Frame::Shield1),
- pos: Point::new(i * 45 + 32, 192),
- })
+ .map(|i| Shield::new(&self.assets, Point::new(i * 45 + 32, 192)))
.collect();
// Reset player position
@@ -508,6 +496,22 @@ impl Default for World {
}
impl Invaders {
+ // New
+ pub fn new(assets: &Assets) -> Self {
+ let grid = make_invader_grid(assets);
+ let stepper = Point::new(COLS - 1, 0);
+ let direction = Direction::Right;
+ let descend = false;
+ let bounds = Bounds::default();
+
+ Invaders {
+ grid,
+ stepper,
+ direction,
+ descend,
+ bounds,
+ }
+ }
/// Compute the bounding box for the Invader fleet.
///
/// # Returns
@@ -588,6 +592,15 @@ impl Invaders {
}
}
+impl Shield {
+ // New
+ pub fn new(assets: &Assets, pos: Point) -> Self {
+ let sprite = Sprite::new(assets, Frame::Shield1);
+
+ Shield { sprite, pos }
+ }
+}
+
impl Default for Bounds {
fn default() -> Self {
Self {
From 2d68f03bd159472414b314ac1f36fda8ab7fea16 Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sun, 26 Mar 2023 12:24:34 +0800
Subject: [PATCH 8/9] [Fix] The check
---
examples/invaders/simple-invaders/src/lib.rs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/examples/invaders/simple-invaders/src/lib.rs b/examples/invaders/simple-invaders/src/lib.rs
index 6686e850..833e2268 100644
--- a/examples/invaders/simple-invaders/src/lib.rs
+++ b/examples/invaders/simple-invaders/src/lib.rs
@@ -145,12 +145,10 @@ impl Player {
let sprite = SpriteRef::new(assets, Frame::Player1, Duration::from_millis(100));
let pos = PLAYER_START;
let dt = Duration::default();
-
Player { sprite, pos, dt }
}
}
-
impl DeltaTime for Player {
fn update(&mut self) -> usize {
Self::update_dt(&mut self.dt, ONE_FRAME)
@@ -195,7 +193,6 @@ impl World {
/// let world = World::new(seed, false);
/// ```
pub fn new(seed: (u64, u64), debug: bool) -> World {
-
// Load assets first
let assets = load_assets();
From 93d0a1c374559e56b9f273cd60f2d183320f854b Mon Sep 17 00:00:00 2001
From: imizao <2313466338@qq.com>
Date: Sun, 26 Mar 2023 13:07:43 +0800
Subject: [PATCH 9/9] Improve the processing of Shield and Player modules
---
examples/invaders/simple-invaders/src/lib.rs | 40 +++----------------
.../invaders/simple-invaders/src/player.rs | 24 +++++++++++
.../invaders/simple-invaders/src/shield.rs | 20 ++++++++++
3 files changed, 49 insertions(+), 35 deletions(-)
create mode 100644 examples/invaders/simple-invaders/src/player.rs
create mode 100644 examples/invaders/simple-invaders/src/shield.rs
diff --git a/examples/invaders/simple-invaders/src/lib.rs b/examples/invaders/simple-invaders/src/lib.rs
index 833e2268..92cb9efd 100644
--- a/examples/invaders/simple-invaders/src/lib.rs
+++ b/examples/invaders/simple-invaders/src/lib.rs
@@ -15,7 +15,9 @@ use crate::collision::Collision;
pub use crate::controls::{Controls, Direction};
use crate::geo::Point;
use crate::loader::{load_assets, Assets};
-use crate::sprites::{blit, Animation, Drawable, Frame, Sprite, SpriteRef};
+use crate::player::Player;
+use crate::shield::Shield;
+use crate::sprites::{blit, Animation, Drawable, Frame, SpriteRef};
use core::time::Duration;
use randomize::PCG32;
@@ -24,6 +26,8 @@ mod controls;
mod debug;
mod geo;
mod loader;
+mod player;
+mod shield;
mod sprites;
/// The screen width is constant (units are in pixels)
@@ -96,22 +100,6 @@ struct Bounds {
bottom_row: usize,
}
-/// The player entity.
-#[derive(Debug)]
-struct Player {
- sprite: SpriteRef,
- pos: Point,
- dt: Duration,
-}
-
-/// The shield entity.
-#[derive(Debug)]
-struct Shield {
- // Shield sprite is not referenced because we want to deform it when it gets shot
- sprite: Sprite,
- pos: Point,
-}
-
/// The laser entity.
#[derive(Debug)]
struct Laser {
@@ -140,15 +128,6 @@ trait DeltaTime {
}
}
-impl Player {
- pub fn new(assets: &Assets) -> Self {
- let sprite = SpriteRef::new(assets, Frame::Player1, Duration::from_millis(100));
- let pos = PLAYER_START;
- let dt = Duration::default();
- Player { sprite, pos, dt }
- }
-}
-
impl DeltaTime for Player {
fn update(&mut self) -> usize {
Self::update_dt(&mut self.dt, ONE_FRAME)
@@ -589,15 +568,6 @@ impl Invaders {
}
}
-impl Shield {
- // New
- pub fn new(assets: &Assets, pos: Point) -> Self {
- let sprite = Sprite::new(assets, Frame::Shield1);
-
- Shield { sprite, pos }
- }
-}
-
impl Default for Bounds {
fn default() -> Self {
Self {
diff --git a/examples/invaders/simple-invaders/src/player.rs b/examples/invaders/simple-invaders/src/player.rs
new file mode 100644
index 00000000..35ac1999
--- /dev/null
+++ b/examples/invaders/simple-invaders/src/player.rs
@@ -0,0 +1,24 @@
+use crate::geo::Point;
+use crate::loader::Assets;
+use crate::sprites::{Frame, SpriteRef};
+use core::time::Duration;
+
+// Player positioning
+const PLAYER_START: Point = Point::new(80, 216);
+
+/// The player entity.
+#[derive(Debug)]
+pub(crate) struct Player {
+ pub sprite: SpriteRef,
+ pub pos: Point,
+ pub dt: Duration,
+}
+
+impl Player {
+ pub fn new(assets: &Assets) -> Self {
+ let sprite = SpriteRef::new(assets, Frame::Player1, Duration::from_millis(100));
+ let pos = PLAYER_START;
+ let dt = Duration::default();
+ Player { sprite, pos, dt }
+ }
+}
diff --git a/examples/invaders/simple-invaders/src/shield.rs b/examples/invaders/simple-invaders/src/shield.rs
new file mode 100644
index 00000000..c44f5b60
--- /dev/null
+++ b/examples/invaders/simple-invaders/src/shield.rs
@@ -0,0 +1,20 @@
+use crate::geo::Point;
+use crate::loader::Assets;
+use crate::sprites::{Frame, Sprite};
+
+/// The shield entity.
+#[derive(Debug)]
+pub(crate) struct Shield {
+ // Shield sprite is not referenced because we want to deform it when it gets shot
+ pub sprite: Sprite,
+ pub pos: Point,
+}
+
+impl Shield {
+ // New
+ pub fn new(assets: &Assets, pos: Point) -> Self {
+ let sprite = Sprite::new(assets, Frame::Shield1);
+
+ Shield { sprite, pos }
+ }
+}