survivor

graphical action game for the linux terminal
git clone https://git.ce9e.org/survivor.git

commit
23ff4fe4617456da7e46271acc6b05e36418da67
parent
05074c5c880d33d16d4a9bff89272f18e9b5f8f3
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-02-19 18:23
refactor Window

make it short lieved so it can hold a mutable reference to screen

Diffstat

M src/game.rs 46 +++++++++++++++-------------------------------
M src/main.rs 15 ++++++++++++---
M src/win.rs 28 +++++++++++-----------------

3 files changed, 38 insertions, 51 deletions


diff --git a/src/game.rs b/src/game.rs

@@ -1,7 +1,6 @@
    1     1 use crate::enemies;
    2     2 use crate::random;
    3     3 use crate::sprites;
    4    -1 use crate::term;
    5     4 use crate::win;
    6     5 
    7     6 const MAX_ENEMIES: usize = 100;
@@ -109,23 +108,16 @@ pub struct Game {
  109   108     pub diamonds: Vec<Diamond>,
  110   109     pub enemies: Vec<enemies::Enemy>,
  111   110     pub i_enemy: usize,
  112    -1     pub win: win::Window,
  113   111     rng: random::Rng,
  114   112 }
  115   113 
  116   114 impl Game {
  117    -1     pub fn new(screen: &term::Screen) -> Self {
   -1   115     pub fn new() -> Self {
  118   116         return Self {
  119   117             enemies: vec![],
  120   118             diamonds: vec![],
  121   119             i_enemy: 0,
  122   120             player: Player::new(),
  123    -1             win: win::Window {
  124    -1                 width: screen.width,
  125    -1                 height: screen.height - 6,
  126    -1                 dx: 0,
  127    -1                 dy: 3,
  128    -1             },
  129   121             rng: random::Rng::new(),
  130   122         };
  131   123     }
@@ -176,9 +168,7 @@ impl Game {
  176   168         }
  177   169     }
  178   170 
  179    -1     fn spawn_enemies(&mut self, dt: f32) {
  180    -1         let height = win::iconvert_y(self.win.height);
  181    -1         let width = win::iconvert_x(self.win.width);
   -1   171     fn spawn_enemies(&mut self, dt: f32, width: f32, height: f32) {
  182   172         let sprite_height = win::iconvert_y(sprites::HEIGHT);
  183   173         let sprite_width = win::iconvert_x(sprites::WIDTH);
  184   174 
@@ -200,9 +190,7 @@ impl Game {
  200   190         }
  201   191     }
  202   192 
  203    -1     fn despawn_enemies(&mut self) {
  204    -1         let height = win::iconvert_y(self.win.height);
  205    -1         let width = win::iconvert_x(self.win.width);
   -1   193     fn despawn_enemies(&mut self, width: f32, height: f32) {
  206   194         self.enemies = std::mem::take(&mut self.enemies)
  207   195             .into_iter()
  208   196             .filter(|e| (e.y - self.player.y).abs() < height && (e.x - self.player.x).abs() < width)
@@ -257,11 +245,11 @@ impl Game {
  257   245             .collect();
  258   246     }
  259   247 
  260    -1     pub fn step(&mut self, dt: f32) {
  261    -1         self.spawn_enemies(dt);
   -1   248     pub fn step(&mut self, dt: f32, width: f32, height: f32) {
   -1   249         self.spawn_enemies(dt, width, height);
  262   250         self.move_player(dt);
  263   251         self.move_enemies(dt);
  264    -1         self.despawn_enemies();
   -1   252         self.despawn_enemies(width, height);
  265   253 
  266   254         self.apply_damage(dt);
  267   255         self.pick_diamonds();
@@ -270,13 +258,12 @@ impl Game {
  270   258         self.player.levelup(&mut self.rng);
  271   259     }
  272   260 
  273    -1     pub fn render(&mut self, screen: &mut term::Screen) {
  274    -1         let height = win::iconvert_y(self.win.height);
  275    -1         let width = win::iconvert_x(self.win.width);
   -1   261     pub fn render(&mut self, win: &mut win::Window) {
   -1   262         let height = win::iconvert_y(win.height);
   -1   263         let width = win::iconvert_x(win.width);
  276   264 
  277    -1         self.win.fill(screen, [0x33, 0x88, 0x22]);
  278    -1         self.win.circle(
  279    -1             screen,
   -1   265         win.fill([0x33, 0x88, 0x22]);
   -1   266         win.circle(
  280   267             width / 2.0,
  281   268             height / 2.0,
  282   269             self.player.damage_radius,
@@ -286,15 +273,14 @@ impl Game {
  286   273         for diamond in self.diamonds.iter() {
  287   274             let sx = diamond.x - self.player.x + width / 2.0;
  288   275             let sy = diamond.y - self.player.y + height / 2.0;
  289    -1             self.win.sprite(screen, sx, sy, &sprites::DIAMOND, false);
   -1   276             win.sprite(sx, sy, &sprites::DIAMOND, false);
  290   277         }
  291   278 
  292   279         let mut player_rendered = false;
  293   280         self.enemies.sort_unstable_by_key(|e| e.y as i32);
  294   281         for enemy in self.enemies.iter() {
  295   282             if !player_rendered && enemy.y > self.player.y {
  296    -1                 self.win.sprite(
  297    -1                     screen,
   -1   283                 win.sprite(
  298   284                     width / 2.0,
  299   285                     height / 2.0,
  300   286                     &sprites::PLAYER,
@@ -305,12 +291,10 @@ impl Game {
  305   291 
  306   292             let sx = enemy.x - self.player.x + width / 2.0;
  307   293             let sy = enemy.y - self.player.y + height / 2.0;
  308    -1             self.win
  309    -1                 .sprite(screen, sx, sy, enemy.t.sprite, enemy.x > self.player.x);
   -1   294             win.sprite(sx, sy, enemy.t.sprite, enemy.x > self.player.x);
  310   295         }
  311   296         if !player_rendered {
  312    -1             self.win.sprite(
  313    -1                 screen,
   -1   297             win.sprite(
  314   298                 width / 2.0,
  315   299                 height / 2.0,
  316   300                 &sprites::PLAYER,

diff --git a/src/main.rs b/src/main.rs

@@ -47,7 +47,7 @@ fn render_health_bar(player: &game::Player, screen: &mut term::Screen) {
   47    47 fn main() {
   48    48     let input = input::Input::new();
   49    49     let mut screen = term::Screen::new();
   50    -1     let mut game = game::Game::new(&screen);
   -1    50     let mut game = game::Game::new();
   51    51 
   52    52     unsafe {
   53    53         libc::signal(libc::SIGINT, quit as usize);
@@ -77,8 +77,17 @@ fn main() {
   77    77             }
   78    78         }
   79    79 
   80    -1         game.step(dt);
   81    -1         game.render(&mut screen);
   -1    80         let mut win = win::Window {
   -1    81             width: screen.width,
   -1    82             height: screen.height - 6,
   -1    83             dx: 0,
   -1    84             dy: 3,
   -1    85             screen: &mut screen,
   -1    86         };
   -1    87         let width = win::iconvert_x(win.width);
   -1    88         let height = win::iconvert_y(win.height);
   -1    89         game.step(dt, width, height);
   -1    90         game.render(&mut win);
   82    91 
   83    92         render_xp_bar(&game.player, &mut screen);
   84    93         render_health_bar(&game.player, &mut screen);

diff --git a/src/win.rs b/src/win.rs

@@ -19,34 +19,28 @@ pub fn iconvert_y(y: usize) -> f32 {
   19    19     return y as f32 * Y_FACTOR;
   20    20 }
   21    21 
   22    -1 pub struct Window {
   -1    22 pub struct Window<'a> {
   23    23     pub height: usize,
   24    24     pub width: usize,
   25    25     pub dx: usize,
   26    26     pub dy: usize,
   -1    27     pub screen: &'a mut Screen,
   27    28 }
   28    29 
   29    -1 impl Window {
   30    -1     pub fn set(&self, screen: &mut Screen, x: usize, y: usize, color: [u8; 3]) {
   31    -1         screen.set(x + self.dx, y + self.dy, color);
   -1    30 impl Window<'_> {
   -1    31     pub fn set(&mut self, x: usize, y: usize, color: [u8; 3]) {
   -1    32         self.screen.set(x + self.dx, y + self.dy, color);
   32    33     }
   33    34 
   34    -1     pub fn fill(&self, screen: &mut Screen, color: [u8; 3]) {
   -1    35     pub fn fill(&mut self, color: [u8; 3]) {
   35    36         for y in 0..self.height {
   36    37             for x in 0..self.width {
   37    -1                 self.set(screen, x, y, color);
   -1    38                 self.set(x, y, color);
   38    39             }
   39    40         }
   40    41     }
   41    42 
   42    -1     pub fn sprite(
   43    -1         &self,
   44    -1         screen: &mut Screen,
   45    -1         cx: f32,
   46    -1         cy: f32,
   47    -1         sprite: &sprites::Sprite,
   48    -1         invert: bool,
   49    -1     ) {
   -1    43     pub fn sprite(&mut self, cx: f32, cy: f32, sprite: &sprites::Sprite, invert: bool) {
   50    44         let x0 = convert_x(cx) - sprites::WIDTH as i64 / 2;
   51    45         let y0 = convert_y(cy) + sprites::WIDTH as i64 / 2 - sprites::HEIGHT as i64;
   52    46 
@@ -69,13 +63,13 @@ impl Window {
   69    63                 let cx = if invert { sprites::WIDTH - dx - 1 } else { dx };
   70    64                 let c = sprite[dy][cx];
   71    65                 if c != sprite[0][0] {
   72    -1                     self.set(screen, x as usize, y as usize, c);
   -1    66                     self.set(x as usize, y as usize, c);
   73    67                 }
   74    68             }
   75    69         }
   76    70     }
   77    71 
   78    -1     pub fn circle(&self, screen: &mut Screen, cx: f32, cy: f32, r: f32, color: [u8; 3]) {
   -1    72     pub fn circle(&mut self, cx: f32, cy: f32, r: f32, color: [u8; 3]) {
   79    73         let r2 = r * r;
   80    74 
   81    75         let y0 = convert_y(cy - r).max(0).min(self.height as i64 - 1) as usize;
@@ -90,7 +84,7 @@ impl Window {
   90    84             for x in x0..=x1 {
   91    85                 let dx = iconvert_x(x) - cx;
   92    86                 if dx * dx + y2 <= r2 {
   93    -1                     self.set(screen, x, y, color);
   -1    87                     self.set(x, y, color);
   94    88                 }
   95    89             }
   96    90         }