Chore: Big clean up: UFOs enter and leave the screen correctly now.
This commit is contained in:
parent
2d19a53586
commit
38b2677ed1
2 changed files with 43 additions and 41 deletions
13
src/main.rs
13
src/main.rs
|
@ -3,9 +3,9 @@ use std::time::Duration;
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use ufo::Ufo;
|
use crate::Direction::Left;
|
||||||
|
|
||||||
use crate::movable::Movable;
|
use crate::movable::Movable;
|
||||||
|
use crate::ufo::Ufo;
|
||||||
|
|
||||||
mod movable;
|
mod movable;
|
||||||
mod terminal;
|
mod terminal;
|
||||||
|
@ -27,14 +27,14 @@ const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let terminal = terminal::setup();
|
let terminal = terminal::setup();
|
||||||
|
|
||||||
const MAX_UFOS: u8 = 100;
|
const MAX_UFOS: u8 = 100;
|
||||||
let mut ufos = vec![Ufo::create(), Ufo::create(), Ufo::create(), Ufo::create(), Ufo::create()];
|
let mut ufos = vec![Ufo::create(), Ufo::create(), Ufo::create(), Ufo::create(), Ufo::create()];
|
||||||
let mut n_ufos = ufos.len() as u8;
|
let mut n_ufos = ufos.len() as u8;
|
||||||
loop {
|
loop {
|
||||||
let iter_mut = ufos.iter_mut();
|
let iter_mut = ufos.iter_mut();
|
||||||
for x in iter_mut {
|
for x in iter_mut {
|
||||||
x.mov(Direction::Left);
|
x.mov(Left);
|
||||||
x.draw();
|
|
||||||
}
|
}
|
||||||
if rand::thread_rng().gen_bool(0.1) && n_ufos < MAX_UFOS {
|
if rand::thread_rng().gen_bool(0.1) && n_ufos < MAX_UFOS {
|
||||||
ufos.push(Ufo::create());
|
ufos.push(Ufo::create());
|
||||||
|
@ -50,10 +50,7 @@ fn main() {
|
||||||
terminal::restore(terminal);
|
terminal::restore(terminal);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tank_at(col: u16) {
|
#[derive(PartialEq)]
|
||||||
terminal::print_str_at(col, TANK_ROW, TANK_STR);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Direction {
|
pub enum Direction {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
|
|
71
src/ufo.rs
71
src/ufo.rs
|
@ -1,8 +1,11 @@
|
||||||
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use crate::{Direction, MAX_UFO_ROW, MIN_UFO_ROW, UFO_STR, WIDTH};
|
use crate::{Direction, MAX_UFO_ROW, MIN_UFO_ROW, UFO_STR, WIDTH};
|
||||||
use crate::Direction::{Down, Left, Right};
|
use crate::Direction::{Down, Left, Right};
|
||||||
use crate::movable::Movable;
|
use crate::movable::Movable;
|
||||||
use crate::terminal::print_str_at;
|
use crate::terminal::{clear_pos, print_str_at};
|
||||||
|
|
||||||
pub struct Ufo {
|
pub struct Ufo {
|
||||||
row: u16,
|
row: u16,
|
||||||
|
@ -17,29 +20,32 @@ impl Movable<Ufo> for Ufo {
|
||||||
let row = rng.gen_range(MIN_UFO_ROW..=MAX_UFO_ROW);
|
let row = rng.gen_range(MIN_UFO_ROW..=MAX_UFO_ROW);
|
||||||
let column = match direction {
|
let column = match direction {
|
||||||
// If the UFO is moving right, we will initially place it just at the left edge.
|
// If the UFO is moving right, we will initially place it just at the left edge.
|
||||||
Right => -(UFO_STR.len() as i16) + 1,
|
Right => -(UFO_STR.len() as i16),
|
||||||
// If the UFO is moving left, we will initially place it just at the right edge.
|
// If the UFO is moving left, we will initially place it just at the right edge.
|
||||||
Left => WIDTH as i16 - 1,
|
Left => WIDTH as i16,
|
||||||
// Above, we're creating either a Left or a Right direction value. So, we CANNOT get here. Hence: PANIC!
|
// Above, we're creating either a Left or a Right direction value. So, we CANNOT get here. Hence: PANIC!
|
||||||
_ => panic!("Programming error. We're not supposed to get here.")
|
_ => panic!("Programming error. We're not supposed to get here.")
|
||||||
};
|
};
|
||||||
Ufo { row, column, direction }
|
let ufo = Ufo { row, column, direction };
|
||||||
|
ufo.draw();
|
||||||
|
ufo
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mov(&mut self, direction: Direction) {
|
fn mov(&mut self, direction: Direction) {
|
||||||
let ufo_str_len = UFO_STR.len() as i16;
|
clear(self);
|
||||||
|
|
||||||
match direction {
|
match direction {
|
||||||
Down => { todo!("Implement crash movement (down + direction)") }
|
Down => { todo!("Implement crash movement (down + direction)") }
|
||||||
_ => {
|
_ => {
|
||||||
match self.direction {
|
match self.direction {
|
||||||
Left => {
|
Left => {
|
||||||
|
let ufo_str_len = UFO_STR.len() as i16;
|
||||||
if self.column >= -ufo_str_len {
|
if self.column >= -ufo_str_len {
|
||||||
self.column -= 1;
|
self.column -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Right => {
|
Right => {
|
||||||
if self.column < WIDTH as i16 {
|
if self.column <= WIDTH as i16 {
|
||||||
self.column += 1;
|
self.column += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,40 +53,39 @@ impl Movable<Ufo> for Ufo {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self) {
|
fn draw(&self) {
|
||||||
let mut body: String;
|
|
||||||
let ufo_str_len = UFO_STR.len() as i16;
|
let ufo_str_len = UFO_STR.len() as i16;
|
||||||
|
let left_cutoff = min(max(0, -self.column), ufo_str_len) as usize;
|
||||||
|
let right_cutoff = max(0, min(ufo_str_len, WIDTH as i16 - self.column)) as usize;
|
||||||
|
|
||||||
if self.column < -ufo_str_len {
|
let ufo_str_slice = &UFO_STR[left_cutoff..right_cutoff];
|
||||||
// left outside
|
let col = max(0, min(self.column, (WIDTH as i16) - (right_cutoff as i16))) as u16;
|
||||||
body = String::new();
|
print_str_at(col, self.row, ufo_str_slice);
|
||||||
} else if self.column < 0 {
|
|
||||||
// left transitioning in/out
|
|
||||||
body = String::new();
|
|
||||||
} else if self.column < (WIDTH as i16 - ufo_str_len) {
|
|
||||||
// normal range
|
|
||||||
body = String::from(UFO_STR);
|
|
||||||
match self.direction {
|
|
||||||
Left => { body.push(' ') }
|
|
||||||
Right => { body = String::from(" ") + body.as_str() }
|
|
||||||
Down => { todo!("How do we handle the downward movement?") }
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
let max_len = WIDTH as i16 - self.column;
|
|
||||||
body.truncate(max_len as usize)
|
|
||||||
} else if self.column < WIDTH as i16 {
|
|
||||||
// right transitioning in/out
|
|
||||||
body = String::new();
|
|
||||||
} else {
|
|
||||||
// right outside
|
|
||||||
body = String::new();
|
|
||||||
}
|
|
||||||
print_str_at(if self.column < 0 { 0 } else { self.column as u16 }, self.row, body.as_str())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_on_screen(&self) -> bool {
|
fn is_on_screen(&self) -> bool {
|
||||||
self.column > -(UFO_STR.len() as i16) && self.column < WIDTH as i16
|
self.column >= -(UFO_STR.len() as i16)
|
||||||
|
&& self.column <= (WIDTH as i16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clear(ufo: &Ufo) {
|
||||||
|
match ufo.direction {
|
||||||
|
Right => {
|
||||||
|
if ufo.column >= 0 {
|
||||||
|
clear_pos(ufo.column as u16, ufo.row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Left => {
|
||||||
|
let current_right = ufo.column + (UFO_STR.len() as i16) - 1;
|
||||||
|
if current_right >= 0 && current_right < (WIDTH as i16) {
|
||||||
|
clear_pos(current_right as u16, ufo.row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue