Skip to content

Commit 4c9ea9a

Browse files
Add countdown
1 parent 48c21bc commit 4c9ea9a

10 files changed

+109
-23
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "klocki"
3-
version = "0.1.2"
3+
version = "0.1.4"
44
authors = ["Piotr Szczygieł <[email protected]>"]
55
edition = "2018"
66

resources/sfx/countdown.wav

17.3 KB
Binary file not shown.

resources/sfx/go.wav

42.2 KB
Binary file not shown.

src/game.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@ impl EventHandler for Game {
162162

163163
match &mut self.replay {
164164
Some(replay) => {
165-
replay.update(ctx);
165+
if !replay.gameplay.paused() && !self.g.imgui_state.paused {
166+
replay.update(ctx);
167+
}
166168
gameplay = &mut replay.gameplay;
167169
}
168170
None => {

src/gameplay.rs

+52-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use ggez::{
66
timer, Context, GameResult,
77
};
88

9+
use crate::popups::Popup;
910
use crate::{
1011
action::Action,
1112
bag::Bag,
@@ -42,6 +43,8 @@ pub struct Gameplay {
4243
blocks: Blocks,
4344

4445
explosion: bool,
46+
countdown: Option<i32>,
47+
countdown_switch: Duration,
4548
}
4649

4750
impl Gameplay {
@@ -83,6 +86,8 @@ impl Gameplay {
8386
font,
8487
blocks,
8588
explosion: false,
89+
countdown: Some(4),
90+
countdown_switch: Duration::new(0, 0),
8691
})
8792
}
8893

@@ -130,6 +135,10 @@ impl Gameplay {
130135
self.game_over
131136
}
132137

138+
pub fn paused(&self) -> bool {
139+
self.game_over || self.countdown.is_some() || self.matrix.blocked()
140+
}
141+
133142
fn process_action(&mut self, g: &mut Global, action: Action, sfx: bool) -> bool {
134143
match action {
135144
Action::HoldPiece => {
@@ -162,8 +171,13 @@ impl Gameplay {
162171
self.explode();
163172
let t_spin = self.piece.t_spin(&self.matrix);
164173
self.score.lock(rows, t_spin);
165-
self.popups
166-
.lock(rows, t_spin, self.score.btb(), self.score.combo());
174+
self.popups.lock(
175+
rows,
176+
t_spin,
177+
self.score.btb(),
178+
self.score.combo(),
179+
g.settings.gameplay.clear_delay.into(),
180+
);
167181
} else {
168182
self.score.reset_combo();
169183
}
@@ -201,6 +215,10 @@ impl Gameplay {
201215
self.matrix.game_over();
202216
self.explode();
203217

218+
let mut popup = Popup::new(Duration::from_secs(10));
219+
popup.add("Game Over", Color::new(0.9, 0.1, 0.2, 1.0), 4.0);
220+
self.popups.add(popup);
221+
204222
if sfx {
205223
g.sfx.play("gameover");
206224
}
@@ -314,6 +332,37 @@ impl Gameplay {
314332
self.blocks = Blocks::new(g.settings.tileset(ctx, &g.settings_state)?);
315333
}
316334

335+
if let Some(countdown) = self.countdown.as_mut() {
336+
if *countdown == 4 {
337+
self.countdown_switch = Duration::from_secs(1);
338+
}
339+
340+
self.countdown_switch += timer::delta(ctx);
341+
if self.countdown_switch >= Duration::from_secs(1) {
342+
self.countdown_switch = Duration::new(0, 0);
343+
*countdown -= 1;
344+
345+
let mut text = countdown.to_string();
346+
347+
if sfx {
348+
if *countdown == 0 {
349+
g.sfx.play("go");
350+
} else {
351+
g.sfx.play("countdown");
352+
}
353+
}
354+
355+
if *countdown == 0 {
356+
self.countdown = None;
357+
text = String::from("Go!");
358+
}
359+
360+
let mut popup = Popup::new(Duration::from_secs(2));
361+
popup.add(&text, Color::new(0.8, 0.9, 1.0, 1.0), 4.0);
362+
self.popups.add(popup);
363+
}
364+
}
365+
317366
self.popups.update(
318367
ctx,
319368
(g.settings.gameplay.block_size * self.matrix.width) as f32,
@@ -323,7 +372,7 @@ impl Gameplay {
323372

324373
self.matrix.update(ctx, g, sfx)?;
325374

326-
if self.game_over || self.matrix.blocked() || g.imgui_state.paused {
375+
if self.paused() || g.imgui_state.paused {
327376
return Ok(());
328377
}
329378

src/imgui_wrapper.rs

+2
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ impl ImGuiWrapper {
229229
Window::new(im_str!("Game over"))
230230
.opened(&mut opened)
231231
.resizable(false)
232+
.size([120.0, 180.0], Condition::Appearing)
233+
.position([w / 2.0 - 60.0, h / 3.0 * 2.0], Condition::Appearing)
232234
.collapsible(false)
233235
.build(&ui, || {
234236
ui.text(im_str!("Score: {}", g.imgui_state.replay_score));

src/matrix.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl Randomizer {
5959
uniform_vx: Uniform::new(-7.5, 7.5),
6060
normal_vy: Normal::new(-10.0, 5.0).unwrap(),
6161
uniform_vr: Uniform::new(-8.0 * std::f32::consts::PI, 8.0 * std::f32::consts::PI),
62-
uniform_lifetime: Uniform::new(250, 500),
62+
uniform_lifetime: Uniform::new(250, 750),
6363
}
6464
}
6565
}
@@ -380,6 +380,7 @@ impl Matrix {
380380
}
381381

382382
fn collapse_rows(&mut self, rows: &[i32]) {
383+
self.update_grid = true;
383384
let mut rng = rand::thread_rng();
384385

385386
for &row in rows {

src/popups.rs

+30-14
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use ggez::{
1010
use crate::utils;
1111

1212
#[derive(Default)]
13-
struct Popup {
13+
pub struct Popup {
1414
canvas: Option<Canvas>,
1515
fragments: Vec<PopupFragment>,
1616
visible: Duration,
@@ -144,23 +144,42 @@ impl Popup {
144144
}
145145
}
146146

147-
#[derive(Default)]
148147
pub struct Popups {
149148
active_popup: Option<Popup>,
150149
fading_popups: Vec<Popup>,
151150
font: Font,
151+
just_created: bool,
152152
}
153153

154154
impl Popups {
155155
pub fn new(ctx: &mut Context) -> GameResult<Popups> {
156156
Ok(Popups {
157+
active_popup: None,
158+
fading_popups: vec![],
157159
font: Font::new(ctx, utils::path(ctx, "fonts/bold.ttf"))?,
158-
..Default::default()
160+
just_created: true,
159161
})
160162
}
161163

162-
pub fn lock(&mut self, rows: i32, t_spin: bool, btb: bool, combo: Option<i32>) {
163-
let mut popup = Popup::new(Duration::from_millis(1500));
164+
pub fn add(&mut self, popup: Popup) {
165+
let mut popup = Some(popup);
166+
std::mem::swap(&mut popup, &mut self.active_popup);
167+
168+
if let Some(mut popup) = popup {
169+
if popup.hide < 0.5 {
170+
popup.visible = popup.lifetime / 2;
171+
}
172+
self.fading_popups.push(popup);
173+
}
174+
}
175+
176+
pub fn lock(&mut self, rows: i32, t_spin: bool, btb: bool, combo: Option<i32>, delay: u64) {
177+
let mut lifetime = delay;
178+
if lifetime < 250 {
179+
lifetime = 250;
180+
}
181+
182+
let mut popup = Popup::new(Duration::from_millis(lifetime * 2));
164183

165184
if t_spin {
166185
popup.add("T-Spin\n", Color::new(1.0, 0.5, 0.9, 1.0), 4.0);
@@ -196,20 +215,17 @@ impl Popups {
196215
}
197216
}
198217

199-
let mut popup = Some(popup);
200-
std::mem::swap(&mut popup, &mut self.active_popup);
201-
202-
if let Some(mut popup) = popup {
203-
if popup.hide < 0.5 {
204-
popup.visible = popup.lifetime / 2;
205-
}
206-
self.fading_popups.push(popup);
207-
}
218+
self.add(popup);
208219
}
209220

210221
pub fn update(&mut self, ctx: &mut Context, width: f32, height: f32, scale: f32) -> GameResult {
211222
let dt = timer::delta(ctx);
212223

224+
if self.just_created {
225+
self.just_created = false;
226+
return Ok(());
227+
}
228+
213229
let mut fading = false;
214230
if let Some(p) = self.active_popup.as_mut() {
215231
if p.canvas.is_none() {

src/settings.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl Settings {
8181
gameplay: Gameplay {
8282
block_size: 32,
8383
ghost_piece: 10,
84-
clear_delay: 0,
84+
clear_delay: 250,
8585
skin: String::from("default.png"),
8686
},
8787
audio: Audio {

src/sfx.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,25 @@ pub struct Sfx {
1616
impl Sfx {
1717
pub fn load(ctx: &mut Context, volume: u32) -> GameResult<Sfx> {
1818
let sounds = [
19-
"move", "rotate", "softdrop", "harddrop", "hold", "holdfail", "lock", "linefall",
20-
"gameover", "erase1", "erase2", "erase3", "erase4", "tspin0", "tspin1", "tspin2",
19+
"move",
20+
"rotate",
21+
"softdrop",
22+
"harddrop",
23+
"hold",
24+
"holdfail",
25+
"lock",
26+
"linefall",
27+
"gameover",
28+
"erase1",
29+
"erase2",
30+
"erase3",
31+
"erase4",
32+
"tspin0",
33+
"tspin1",
34+
"tspin2",
2135
"tspin3",
36+
"countdown",
37+
"go",
2238
]
2339
.iter()
2440
.map(|&s| (s, Sfx::source(ctx, s, volume)))

0 commit comments

Comments
 (0)