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
 | ||||
|         let player = &self.player; | ||||
|         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_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) { | ||||
| @ -25,11 +25,10 @@ impl Game { | ||||
|         }; | ||||
|         if can_go { | ||||
|             if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairDown { | ||||
|                 self.player.set_position( | ||||
|                     player_pos.get_level() + 1, | ||||
|                     self.levels[(player_pos.get_level() + 1) as usize].start_x as u16, | ||||
|                     self.levels[(player_pos.get_level() + 1) as usize].start_y as u16, | ||||
|                 ); | ||||
|                 let start_x = self.levels[(player_pos.get_level() + 1) as usize].start_x; | ||||
|                 let start_y = self.levels[(player_pos.get_level() + 1) as usize].start_y; | ||||
|                 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].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 { | ||||
|                 self.player.set_position( | ||||
|                     player_pos.get_level() - 1, | ||||
| @ -38,6 +37,7 @@ impl Game { | ||||
|                 ); | ||||
|             } else { | ||||
|                 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_HEIGHT: usize = 25; | ||||
| 
 | ||||
| @ -7,6 +9,7 @@ pub enum LevelElement { | ||||
|     Floor, | ||||
|     StairDown, | ||||
|     StairUp, | ||||
|     Unknown, | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, Debug, PartialEq)] | ||||
| @ -22,6 +25,7 @@ pub enum RoomType { | ||||
| #[derive(Copy, Clone, Debug, PartialEq)] | ||||
| pub struct Level { | ||||
|     pub(crate) structure: [[LevelElement; LEVEL_HEIGHT]; LEVEL_WIDTH], | ||||
|     pub(crate) discovered: [[bool; LEVEL_HEIGHT]; LEVEL_WIDTH], | ||||
|     pub(crate) start_x: usize, | ||||
|     pub(crate) start_y: usize, | ||||
|     pub(crate) end_x: usize, | ||||
| @ -33,10 +37,11 @@ impl Level { | ||||
|         let s = [[LevelElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH]; | ||||
|         Level { | ||||
|             structure: s, | ||||
|             discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH], | ||||
|             start_x: 1, | ||||
|             start_y: 1, | ||||
|             end_x: 1, | ||||
|             end_y: 1 | ||||
|             end_y: 1, | ||||
|         } | ||||
|     } | ||||
|     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 { | ||||
|             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 { | ||||
|             structure: s, | ||||
|             discovered: [[false; 1 + ROOMS_HORIZONTAL * ROOM_HEIGHT]; 1 + ROOMS_VERTICAL * ROOM_WIDTH], | ||||
|             start_x, | ||||
|             start_y, | ||||
|             end_x, | ||||
|  | ||||
| @ -101,6 +101,9 @@ impl<'a> Widget for LevelWidget<'a> { | ||||
|                             LevelElement::StairUp => { | ||||
|                                 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, | ||||
|     }; | ||||
| 
 | ||||
|     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)?; | ||||
|     enable_raw_mode()?; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user