survivor

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

commit
e1c50a4021ca58af2a6ab58d22a71afb5e345ec5
parent
77f22affadbd2d3802a25578a984777f7cc9b1ab
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-02-19 15:06
do not include bars in game area

Diffstat

M src/main.rs 91 ++++++++++---------------------------------------------------
A src/win.rs 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2 files changed, 95 insertions, 76 deletions


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

@@ -5,6 +5,7 @@ mod input;
    5     5 mod random;
    6     6 mod sprites;
    7     7 mod term;
   -1     8 mod win;
    8     9 
    9    10 use std::sync::atomic::{AtomicBool, Ordering};
   10    11 use std::{thread, time};
@@ -40,74 +41,6 @@ fn quit(_sig: i32) {
   40    41     RUNNING.fetch_and(false, Ordering::Relaxed);
   41    42 }
   42    43 
   43    -1 fn fill(screen: &mut term::Screen, color: [u8; 3]) {
   44    -1     for y in 0..screen.height {
   45    -1         for x in 0..screen.width {
   46    -1             screen.set(x, y, color);
   47    -1         }
   48    -1     }
   49    -1 }
   50    -1 
   51    -1 fn clear(screen: &mut term::Screen) {
   52    -1     fill(screen, [0x33, 0x88, 0x22]);
   53    -1 }
   54    -1 
   55    -1 fn sprite(screen: &mut term::Screen, cx: f32, cy: f32, sprite: &sprites::Sprite, invert: bool) {
   56    -1     let x0 = screen.convert_x(cx) - sprites::WIDTH as i64 / 2;
   57    -1     let y0 = screen.convert_y(cy) + sprites::WIDTH as i64 / 2 - sprites::HEIGHT as i64;
   58    -1 
   59    -1     for dy in 0..sprites::HEIGHT {
   60    -1         let y = y0 + dy as i64;
   61    -1         if y < 0 {
   62    -1             continue;
   63    -1         }
   64    -1         if y >= screen.height as i64 {
   65    -1             break;
   66    -1         }
   67    -1         for dx in 0..sprites::WIDTH {
   68    -1             let x = x0 + dx as i64;
   69    -1             if x < 0 {
   70    -1                 continue;
   71    -1             }
   72    -1             if x >= screen.width as i64 {
   73    -1                 break;
   74    -1             }
   75    -1             let cx = if invert { sprites::WIDTH - dx - 1 } else { dx };
   76    -1             let c = sprite[dy][cx];
   77    -1             if c != sprite[0][0] {
   78    -1                 screen.set(x as usize, y as usize, c);
   79    -1             }
   80    -1         }
   81    -1     }
   82    -1 }
   83    -1 
   84    -1 fn circle(screen: &mut term::Screen, cx: f32, cy: f32, r: f32, color: [u8; 3]) {
   85    -1     let r2 = r * r;
   86    -1 
   87    -1     let y0 = screen
   88    -1         .convert_y(cy - r)
   89    -1         .max(0)
   90    -1         .min(screen.height as i64 - 1) as usize;
   91    -1     let x0 = screen.convert_x(cx - r).max(0).min(screen.width as i64 - 1) as usize;
   92    -1 
   93    -1     let y1 = screen
   94    -1         .convert_y(cy + r)
   95    -1         .max(0)
   96    -1         .min(screen.height as i64 - 1) as usize;
   97    -1     let x1 = screen.convert_x(cx + r).max(0).min(screen.width as i64 - 1) as usize;
   98    -1 
   99    -1     for y in y0..=y1 {
  100    -1         let dy = screen.iconvert_y(y) - cy;
  101    -1         let y2 = dy * dy;
  102    -1         for x in x0..=x1 {
  103    -1             let dx = screen.iconvert_x(x) - cx;
  104    -1             if dx * dx + y2 <= r2 {
  105    -1                 screen.set(x, y, color);
  106    -1             }
  107    -1         }
  108    -1     }
  109    -1 }
  110    -1 
  111    44 struct Diamond {
  112    45     pub x: f32,
  113    46     pub y: f32,
@@ -134,9 +67,15 @@ struct Player {
  134    67 fn main() {
  135    68     let input = input::Input::new();
  136    69     let mut screen = term::Screen::new();
   -1    70     let win = win::Window {
   -1    71         width: screen.width,
   -1    72         height: screen.height - 6,
   -1    73         dx: 0,
   -1    74         dy: 3,
   -1    75     };
  137    76     let mut rng = random::Rng::new();
  138    -1     let width = screen.iconvert_x(screen.width);
  139    -1     let height = screen.iconvert_y(screen.height);
   -1    77     let width = screen.iconvert_x(win.width);
   -1    78     let height = screen.iconvert_y(win.height);
  140    79     let sprite_width = screen.iconvert_x(sprites::WIDTH);
  141    80     let sprite_height = screen.iconvert_y(sprites::HEIGHT);
  142    81     let mut enemies: Vec<enemies::Enemy> = vec![];
@@ -337,8 +276,8 @@ fn main() {
  337   276         }
  338   277 
  339   278         // render
  340    -1         clear(&mut screen);
  341    -1         circle(
   -1   279         win.fill(&mut screen, [0x33, 0x88, 0x22]);
   -1   280         win.circle(
  342   281             &mut screen,
  343   282             width / 2.0,
  344   283             height / 2.0,
@@ -349,14 +288,14 @@ fn main() {
  349   288         for diamond in diamonds.iter() {
  350   289             let sx = diamond.x - player.x + width / 2.0;
  351   290             let sy = diamond.y - player.y + height / 2.0;
  352    -1             sprite(&mut screen, sx, sy, &sprites::DIAMOND, false);
   -1   291             win.sprite(&mut screen, sx, sy, &sprites::DIAMOND, false);
  353   292         }
  354   293 
  355   294         enemies.sort_unstable_by_key(|e| e.y as i32);
  356   295         let mut player_rendered = false;
  357   296         for enemy in enemies.iter() {
  358   297             if !player_rendered && enemy.y > player.y {
  359    -1                 sprite(
   -1   298                 win.sprite(
  360   299                     &mut screen,
  361   300                     width / 2.0,
  362   301                     height / 2.0,
@@ -368,10 +307,10 @@ fn main() {
  368   307 
  369   308             let sx = enemy.x - player.x + width / 2.0;
  370   309             let sy = enemy.y - player.y + height / 2.0;
  371    -1             sprite(&mut screen, sx, sy, enemy.t.sprite, enemy.x > player.x);
   -1   310             win.sprite(&mut screen, sx, sy, enemy.t.sprite, enemy.x > player.x);
  372   311         }
  373   312         if !player_rendered {
  374    -1             sprite(
   -1   313             win.sprite(
  375   314                 &mut screen,
  376   315                 width / 2.0,
  377   316                 height / 2.0,

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

@@ -0,0 +1,80 @@
   -1     1 use crate::sprites;
   -1     2 use crate::term::Screen;
   -1     3 
   -1     4 pub struct Window {
   -1     5     pub height: usize,
   -1     6     pub width: usize,
   -1     7     pub dx: usize,
   -1     8     pub dy: usize,
   -1     9 }
   -1    10 
   -1    11 impl Window {
   -1    12     pub fn set(&self, screen: &mut Screen, x: usize, y: usize, color: [u8; 3]) {
   -1    13         screen.set(x + self.dx, y + self.dy, color);
   -1    14     }
   -1    15 
   -1    16     pub fn fill(&self, screen: &mut Screen, color: [u8; 3]) {
   -1    17         for y in 0..self.height {
   -1    18             for x in 0..self.width {
   -1    19                 self.set(screen, x, y, color);
   -1    20             }
   -1    21         }
   -1    22     }
   -1    23 
   -1    24     pub fn sprite(
   -1    25         &self,
   -1    26         screen: &mut Screen,
   -1    27         cx: f32,
   -1    28         cy: f32,
   -1    29         sprite: &sprites::Sprite,
   -1    30         invert: bool,
   -1    31     ) {
   -1    32         let x0 = screen.convert_x(cx) - sprites::WIDTH as i64 / 2;
   -1    33         let y0 = screen.convert_y(cy) + sprites::WIDTH as i64 / 2 - sprites::HEIGHT as i64;
   -1    34 
   -1    35         for dy in 0..sprites::HEIGHT {
   -1    36             let y = y0 + dy as i64;
   -1    37             if y < 0 {
   -1    38                 continue;
   -1    39             }
   -1    40             if y >= self.height as i64 {
   -1    41                 break;
   -1    42             }
   -1    43             for dx in 0..sprites::WIDTH {
   -1    44                 let x = x0 + dx as i64;
   -1    45                 if x < 0 {
   -1    46                     continue;
   -1    47                 }
   -1    48                 if x >= self.width as i64 {
   -1    49                     break;
   -1    50                 }
   -1    51                 let cx = if invert { sprites::WIDTH - dx - 1 } else { dx };
   -1    52                 let c = sprite[dy][cx];
   -1    53                 if c != sprite[0][0] {
   -1    54                     self.set(screen, x as usize, y as usize, c);
   -1    55                 }
   -1    56             }
   -1    57         }
   -1    58     }
   -1    59 
   -1    60     pub fn circle(&self, screen: &mut Screen, cx: f32, cy: f32, r: f32, color: [u8; 3]) {
   -1    61         let r2 = r * r;
   -1    62 
   -1    63         let y0 = screen.convert_y(cy - r).max(0).min(self.height as i64 - 1) as usize;
   -1    64         let x0 = screen.convert_x(cx - r).max(0).min(self.width as i64 - 1) as usize;
   -1    65 
   -1    66         let y1 = screen.convert_y(cy + r).max(0).min(self.height as i64 - 1) as usize;
   -1    67         let x1 = screen.convert_x(cx + r).max(0).min(self.width as i64) as usize;
   -1    68 
   -1    69         for y in y0..=y1 {
   -1    70             let dy = screen.iconvert_y(y) - cy;
   -1    71             let y2 = dy * dy;
   -1    72             for x in x0..=x1 {
   -1    73                 let dx = screen.iconvert_x(x) - cx;
   -1    74                 if dx * dx + y2 <= r2 {
   -1    75                     self.set(screen, x, y, color);
   -1    76                 }
   -1    77             }
   -1    78         }
   -1    79     }
   -1    80 }