diff options
Diffstat (limited to 'src/renderer.rs')
| -rw-r--r-- | src/renderer.rs | 69 |
1 files changed, 61 insertions, 8 deletions
diff --git a/src/renderer.rs b/src/renderer.rs index 6eff9fa..aa87b54 100644 --- a/src/renderer.rs +++ b/src/renderer.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use crate::game::{Entity, Game, PickupType}; | 1 | use crate::game::{Entity, Game, GameState, PickupType}; |
| 2 | use crate::texture::TEX_SIZE; | 2 | use crate::texture::TEX_SIZE; |
| 3 | 3 | ||
| 4 | // ---- simple 5×5 ASCII glyphs ---- | 4 | // ---- simple 5×5 ASCII glyphs ---- |
| @@ -287,6 +287,11 @@ impl Renderer { | |||
| 287 | } | 287 | } |
| 288 | } | 288 | } |
| 289 | } | 289 | } |
| 290 | |||
| 291 | // ---- death screen ---- | ||
| 292 | if game.state == GameState::GameOver { | ||
| 293 | self.draw_death_screen(buffer, game); | ||
| 294 | } | ||
| 290 | } | 295 | } |
| 291 | 296 | ||
| 292 | // ---- entity sprites --------------------------------------------------- | 297 | // ---- entity sprites --------------------------------------------------- |
| @@ -350,13 +355,6 @@ impl Renderer { | |||
| 350 | let entity_h = (self.screen_h as f64 / cam_z * 0.4) as isize; | 355 | let entity_h = (self.screen_h as f64 / cam_z * 0.4) as isize; |
| 351 | let sy = (half_h - entity_h as f64 * 0.3) as isize; | 356 | let sy = (half_h - entity_h as f64 * 0.3) as isize; |
| 352 | 357 | ||
| 353 | // Occlusion: entity is visible only if its centre column is not behind a wall. | ||
| 354 | // Compare Euclidean distance to entity vs Euclidean distance to wall. | ||
| 355 | let col = sx.clamp(0, self.screen_w as isize - 1) as usize; | ||
| 356 | if cam_z >= wall_euclidean[col] { | ||
| 357 | continue; | ||
| 358 | } | ||
| 359 | |||
| 360 | let scale = (entity_h.max(6) as f64 / LETTER_H as f64).max(0.5); | 358 | let scale = (entity_h.max(6) as f64 / LETTER_H as f64).max(0.5); |
| 361 | let (ch, color) = entity_char_and_color(entity); | 359 | let (ch, color) = entity_char_and_color(entity); |
| 362 | 360 | ||
| @@ -585,6 +583,61 @@ impl Renderer { | |||
| 585 | let hint_w = hint.len() * (LETTER_W + 1) - 1; | 583 | let hint_w = hint.len() * (LETTER_W + 1) - 1; |
| 586 | self.draw_text(buffer, cx - hint_w / 2, y, hint, hint_color); | 584 | self.draw_text(buffer, cx - hint_w / 2, y, hint, hint_color); |
| 587 | } | 585 | } |
| 586 | |||
| 587 | fn draw_death_screen(&self, buffer: &mut [u32], game: &Game) { | ||
| 588 | // Full darken. | ||
| 589 | for py in 0..self.screen_h { | ||
| 590 | for px in 0..self.screen_w { | ||
| 591 | let idx = py * self.screen_w + px; | ||
| 592 | let c = buffer[idx]; | ||
| 593 | let r = ((c >> 16) & 0xFF) as u32; | ||
| 594 | let g = ((c >> 8) & 0xFF) as u32; | ||
| 595 | let b = (c & 0xFF) as u32; | ||
| 596 | buffer[idx] = 0xFF00_0000 | ((r / 5) << 16) | ((g / 5) << 8) | (b / 5); | ||
| 597 | } | ||
| 598 | } | ||
| 599 | |||
| 600 | let cx = self.screen_w / 2; | ||
| 601 | let mut y = self.screen_h as usize / 2 - 40; | ||
| 602 | |||
| 603 | let title_color = 0xFF_CC3333; | ||
| 604 | let text_color = 0xFF_CCCCCC; | ||
| 605 | let score_color = 0xFF_CC8844; | ||
| 606 | let hint_color = 0xFF_666666; | ||
| 607 | |||
| 608 | let title = "YOU HAVE DIED"; | ||
| 609 | let title_w = title.len() * (LETTER_W + 1) - 1; | ||
| 610 | self.draw_text(buffer, cx - title_w / 2, y, title, title_color); | ||
| 611 | y += LETTER_H + 12; | ||
| 612 | |||
| 613 | let msg = "YOU HAD BECOME YET ANOTHER"; | ||
| 614 | let msg_w = msg.len() * (LETTER_W + 1) - 1; | ||
| 615 | self.draw_text(buffer, cx - msg_w / 2, y, msg, text_color); | ||
| 616 | y += LETTER_H + 4; | ||
| 617 | |||
| 618 | let msg2 = "LEGEND OF THIS DUNGEON."; | ||
| 619 | let msg2_w = msg2.len() * (LETTER_W + 1) - 1; | ||
| 620 | self.draw_text(buffer, cx - msg2_w / 2, y, msg2, text_color); | ||
| 621 | y += LETTER_H + 16; | ||
| 622 | |||
| 623 | let score = game.score(); | ||
| 624 | let score_str = format!("SCORE: {}", score); | ||
| 625 | let score_w = score_str.len() * (LETTER_W + 1) - 1; | ||
| 626 | self.draw_text(buffer, cx - score_w / 2, y, &score_str, score_color); | ||
| 627 | y += LETTER_H + 4; | ||
| 628 | |||
| 629 | let kills_str = format!( | ||
| 630 | "KILLS: {} DEPTH: {} WPN:{}", | ||
| 631 | game.kills, game.depth, game.weapon_base_damage | ||
| 632 | ); | ||
| 633 | let kills_w = kills_str.len() * (LETTER_W + 1) - 1; | ||
| 634 | self.draw_text(buffer, cx - kills_w / 2, y, &kills_str, text_color); | ||
| 635 | y += LETTER_H + 20; | ||
| 636 | |||
| 637 | let hint = "PRESS ANY KEY TO EXIT"; | ||
| 638 | let hint_w = hint.len() * (LETTER_W + 1) - 1; | ||
| 639 | self.draw_text(buffer, cx - hint_w / 2, y, hint, hint_color); | ||
| 640 | } | ||
| 588 | } | 641 | } |
| 589 | 642 | ||
| 590 | // ---- helpers ---- | 643 | // ---- helpers ---- |
