Implement fog of dungeon
This commit is contained in:
		
							parent
							
								
									d44c0fd53e
								
							
						
					
					
						commit
						1cfe16c4ef
					
				
							
								
								
									
										12
									
								
								src/game.rs
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/game.rs
									
									
									
									
									
								
							| @ -11,7 +11,7 @@ impl Game { | |||||||
|         // check if move is allowed first
 |         // check if move is allowed first
 | ||||||
|         let player = &self.player; |         let player = &self.player; | ||||||
|         let player_pos = player.get_position(); |         let player_pos = player.get_position(); | ||||||
|         let level = &self.levels[player_pos.get_level() as usize]; |         let mut level = &self.levels[player_pos.get_level() as usize]; | ||||||
|         let new_x = ((player_pos.get_x() as i16) + dx as i16) as u16; |         let new_x = ((player_pos.get_x() as i16) + dx as i16) as u16; | ||||||
|         let new_y = ((player_pos.get_y() as i16) + dy as i16) as u16; |         let new_y = ((player_pos.get_y() as i16) + dy as i16) as u16; | ||||||
|         let can_go: bool = match level.get_element(new_x as i16, new_y as i16) { |         let can_go: bool = match level.get_element(new_x as i16, new_y as i16) { | ||||||
| @ -25,11 +25,10 @@ impl Game { | |||||||
|         }; |         }; | ||||||
|         if can_go { |         if can_go { | ||||||
|             if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairDown { |             if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairDown { | ||||||
|                 self.player.set_position( |                 let start_x = self.levels[(player_pos.get_level() + 1) as usize].start_x; | ||||||
|                     player_pos.get_level() + 1, |                 let start_y = self.levels[(player_pos.get_level() + 1) as usize].start_y; | ||||||
|                     self.levels[(player_pos.get_level() + 1) as usize].start_x as u16, |                 self.player.set_position(player_pos.get_level() + 1, start_x as u16, start_y as u16); | ||||||
|                     self.levels[(player_pos.get_level() + 1) as usize].start_y as u16, |                 self.levels[(player_pos.get_level() + 1) as usize].discover(start_x as i16, start_y as i16); | ||||||
|                 ); |  | ||||||
|             } else if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairUp { |             } else if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairUp { | ||||||
|                 self.player.set_position( |                 self.player.set_position( | ||||||
|                     player_pos.get_level() - 1, |                     player_pos.get_level() - 1, | ||||||
| @ -38,6 +37,7 @@ impl Game { | |||||||
|                 ); |                 ); | ||||||
|             } else { |             } else { | ||||||
|                 self.player.change_position(dx, dy); |                 self.player.change_position(dx, dy); | ||||||
|  |                 self.levels[player_pos.get_level() as usize].discover(new_x as i16, new_y as i16); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
							
								
								
									
										50
									
								
								src/level.rs
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/level.rs
									
									
									
									
									
								
							| @ -1,3 +1,5 @@ | |||||||
|  | use std::cmp::{max, min}; | ||||||
|  | 
 | ||||||
| pub const LEVEL_WIDTH: usize = 50; | pub const LEVEL_WIDTH: usize = 50; | ||||||
| pub const LEVEL_HEIGHT: usize = 25; | pub const LEVEL_HEIGHT: usize = 25; | ||||||
| 
 | 
 | ||||||
| @ -7,6 +9,7 @@ pub enum LevelElement { | |||||||
|     Floor, |     Floor, | ||||||
|     StairDown, |     StairDown, | ||||||
|     StairUp, |     StairUp, | ||||||
|  |     Unknown, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Copy, Clone, Debug, PartialEq)] | #[derive(Copy, Clone, Debug, PartialEq)] | ||||||
| @ -22,6 +25,7 @@ pub enum RoomType { | |||||||
| #[derive(Copy, Clone, Debug, PartialEq)] | #[derive(Copy, Clone, Debug, PartialEq)] | ||||||
| pub struct Level { | pub struct Level { | ||||||
|     pub(crate) structure: [[LevelElement; LEVEL_HEIGHT]; LEVEL_WIDTH], |     pub(crate) structure: [[LevelElement; LEVEL_HEIGHT]; LEVEL_WIDTH], | ||||||
|  |     pub(crate) discovered: [[bool; LEVEL_HEIGHT]; LEVEL_WIDTH], | ||||||
|     pub(crate) start_x: usize, |     pub(crate) start_x: usize, | ||||||
|     pub(crate) start_y: usize, |     pub(crate) start_y: usize, | ||||||
|     pub(crate) end_x: usize, |     pub(crate) end_x: usize, | ||||||
| @ -33,10 +37,11 @@ impl Level { | |||||||
|         let s = [[LevelElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH]; |         let s = [[LevelElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH]; | ||||||
|         Level { |         Level { | ||||||
|             structure: s, |             structure: s, | ||||||
|  |             discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH], | ||||||
|             start_x: 1, |             start_x: 1, | ||||||
|             start_y: 1, |             start_y: 1, | ||||||
|             end_x: 1, |             end_x: 1, | ||||||
|             end_y: 1 |             end_y: 1, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     pub fn get_element(&self, x: i16, y: i16) -> Option<LevelElement> { |     pub fn get_element(&self, x: i16, y: i16) -> Option<LevelElement> { | ||||||
| @ -46,7 +51,48 @@ impl Level { | |||||||
|         if x >= LEVEL_WIDTH as i16 || y >= LEVEL_HEIGHT as i16 { |         if x >= LEVEL_WIDTH as i16 || y >= LEVEL_HEIGHT as i16 { | ||||||
|             return None; |             return None; | ||||||
|         } |         } | ||||||
|         Some(self.structure[x as usize][y as usize]) |         if self.discovered[x as usize][y as usize] { | ||||||
|  |             return Some(self.structure[x as usize][y as usize]); | ||||||
|  |         } | ||||||
|  |         return Some(LevelElement::Unknown); | ||||||
|  |     } | ||||||
|  |     /// discover the area with in the level around the given position
 | ||||||
|  |     pub fn discover(&mut self, x: i16, y: i16) { | ||||||
|  |         for x_r in x - 1..=x + 1 { | ||||||
|  |             for y_r in y - 1..=y + 1 { | ||||||
|  |                 let tx = min(max(x_r, 0), (LEVEL_WIDTH - 1) as i16) as usize; | ||||||
|  |                 let ty = min(max(y_r, 0), (LEVEL_HEIGHT - 1) as i16) as usize; | ||||||
|  |                 self.discovered[tx][ty] = true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         for x_r in x..=x + 2 { | ||||||
|  |             let tx = min(max(x_r, 0), (LEVEL_WIDTH - 1) as i16) as usize; | ||||||
|  |             self.discovered[tx][y as usize] = true; | ||||||
|  |             if self.structure[tx][y as usize] == LevelElement::Wall { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         for y_r in y..=y + 2 { | ||||||
|  |             let ty = min(max(y_r, 0), (LEVEL_HEIGHT - 1) as i16) as usize; | ||||||
|  |             self.discovered[x as usize][ty] = true; | ||||||
|  |             if self.structure[x as usize][ty] == LevelElement::Wall { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         for x_r in (x-2..x).rev() { | ||||||
|  |             let tx = min(max(x_r, 0), (LEVEL_WIDTH - 1) as i16) as usize; | ||||||
|  |             self.discovered[tx][y as usize] = true; | ||||||
|  |             if self.structure[tx][y as usize] == LevelElement::Wall { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         for y_r in (y-2..y).rev() { | ||||||
|  |             let ty = min(max(y_r, 0), (LEVEL_HEIGHT - 1) as i16) as usize; | ||||||
|  |             self.discovered[x as usize][ty] = true; | ||||||
|  |             if self.structure[x as usize][ty] == LevelElement::Wall { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -284,6 +284,7 @@ impl LevelGenerator { | |||||||
|         } |         } | ||||||
|         Level { |         Level { | ||||||
|             structure: s, |             structure: s, | ||||||
|  |             discovered: [[false; 1 + ROOMS_HORIZONTAL * ROOM_HEIGHT]; 1 + ROOMS_VERTICAL * ROOM_WIDTH], | ||||||
|             start_x, |             start_x, | ||||||
|             start_y, |             start_y, | ||||||
|             end_x, |             end_x, | ||||||
|  | |||||||
| @ -101,6 +101,9 @@ impl<'a> Widget for LevelWidget<'a> { | |||||||
|                             LevelElement::StairUp => { |                             LevelElement::StairUp => { | ||||||
|                                 self.set_cell(buf, x, y, "<", Color::Black, Color::Gray); |                                 self.set_cell(buf, x, y, "<", Color::Black, Color::Gray); | ||||||
|                             } |                             } | ||||||
|  |                             LevelElement::Unknown => { | ||||||
|  |                                 self.set_cell(buf, x, y, "▒", Color::DarkGray, Color::Gray); | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -36,7 +36,7 @@ fn main() -> Result<()> { | |||||||
|         levels, |         levels, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     g.player.change_position((levels[0].start_x) as i8, (levels[0].start_y) as i8); |     g.move_player((levels[0].start_x) as i8, (levels[0].start_y) as i8); | ||||||
| 
 | 
 | ||||||
|     stdout().execute(EnterAlternateScreen)?; |     stdout().execute(EnterAlternateScreen)?; | ||||||
|     enable_raw_mode()?; |     enable_raw_mode()?; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user