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 ufo::Ufo; | ||||
| 
 | ||||
| use crate::Direction::Left; | ||||
| use crate::movable::Movable; | ||||
| use crate::ufo::Ufo; | ||||
| 
 | ||||
| mod movable; | ||||
| mod terminal; | ||||
|  | @ -27,14 +27,14 @@ const VERSION: &str = env!("CARGO_PKG_VERSION"); | |||
| 
 | ||||
| fn main() { | ||||
|     let terminal = terminal::setup(); | ||||
| 
 | ||||
|     const MAX_UFOS: u8 = 100; | ||||
|     let mut ufos = vec![Ufo::create(), Ufo::create(), Ufo::create(), Ufo::create(), Ufo::create()]; | ||||
|     let mut n_ufos = ufos.len() as u8; | ||||
|     loop { | ||||
|         let iter_mut = ufos.iter_mut(); | ||||
|         for x in iter_mut { | ||||
|             x.mov(Direction::Left); | ||||
|             x.draw(); | ||||
|             x.mov(Left); | ||||
|         } | ||||
|         if rand::thread_rng().gen_bool(0.1) && n_ufos < MAX_UFOS { | ||||
|             ufos.push(Ufo::create()); | ||||
|  | @ -50,10 +50,7 @@ fn main() { | |||
|     terminal::restore(terminal); | ||||
| } | ||||
| 
 | ||||
| fn tank_at(col: u16) { | ||||
|     terminal::print_str_at(col, TANK_ROW, TANK_STR); | ||||
| } | ||||
| 
 | ||||
| #[derive(PartialEq)] | ||||
| pub enum Direction { | ||||
|     Left, | ||||
|     Right, | ||||
|  |  | |||
							
								
								
									
										71
									
								
								src/ufo.rs
									
										
									
									
									
								
							
							
						
						
									
										71
									
								
								src/ufo.rs
									
										
									
									
									
								
							|  | @ -1,8 +1,11 @@ | |||
| use std::cmp::{max, min}; | ||||
| 
 | ||||
| use rand::Rng; | ||||
| 
 | ||||
| use crate::{Direction, MAX_UFO_ROW, MIN_UFO_ROW, UFO_STR, WIDTH}; | ||||
| use crate::Direction::{Down, Left, Right}; | ||||
| use crate::movable::Movable; | ||||
| use crate::terminal::print_str_at; | ||||
| use crate::terminal::{clear_pos, print_str_at}; | ||||
| 
 | ||||
| pub struct Ufo { | ||||
|     row: u16, | ||||
|  | @ -17,29 +20,32 @@ impl Movable<Ufo> for Ufo { | |||
|         let row = rng.gen_range(MIN_UFO_ROW..=MAX_UFO_ROW); | ||||
|         let column = match direction { | ||||
|             // 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.
 | ||||
|             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!
 | ||||
|             _ => 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) { | ||||
|         let ufo_str_len = UFO_STR.len() as i16; | ||||
|         clear(self); | ||||
| 
 | ||||
|         match direction { | ||||
|             Down => { todo!("Implement crash movement (down + direction)") } | ||||
|             _ => { | ||||
|                 match self.direction { | ||||
|                     Left => { | ||||
|                         let ufo_str_len = UFO_STR.len() as i16; | ||||
|                         if self.column >= -ufo_str_len { | ||||
|                             self.column -= 1; | ||||
|                         } | ||||
|                     } | ||||
|                     Right => { | ||||
|                         if self.column < WIDTH as i16 { | ||||
|                         if self.column <= WIDTH as i16 { | ||||
|                             self.column += 1; | ||||
|                         } | ||||
|                     } | ||||
|  | @ -47,40 +53,39 @@ impl Movable<Ufo> for Ufo { | |||
|                 }; | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         self.draw(); | ||||
|     } | ||||
| 
 | ||||
|     fn draw(&self) { | ||||
|         let mut body: String; | ||||
|         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 { | ||||
|             // left outside
 | ||||
|             body = String::new(); | ||||
|         } 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()) | ||||
|         let ufo_str_slice = &UFO_STR[left_cutoff..right_cutoff]; | ||||
|         let col = max(0, min(self.column, (WIDTH as i16) - (right_cutoff as i16))) as u16; | ||||
|         print_str_at(col, self.row, ufo_str_slice); | ||||
|     } | ||||
| 
 | ||||
|     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…
	
	Add table
		Add a link
		
	
		Reference in a new issue