Got end of level working. Added floating coffins, shatter them and collect what comes out.
This commit is contained in:
		
							
								
								
									
										71
									
								
								src/level.py
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								src/level.py
									
									
									
									
									
								
							| @@ -7,7 +7,6 @@ from src.enemy import Enemy | ||||
| from src.object import Object | ||||
| from src.player import Player | ||||
| from src.projectile import Projectile | ||||
| from src.coffin import CoffinObject | ||||
| from src.powerup import PowerUp | ||||
|  | ||||
| class Level: | ||||
| @@ -17,10 +16,24 @@ class Level: | ||||
|         self.enemies = [] | ||||
|         self.bouncing_items = [] | ||||
|         self.projectiles = []  # Track active projectiles | ||||
|         self.player = Player(levelData["player_start"]["x"], levelData["player_start"]["y"]) | ||||
|         self.player = Player(levelData["player_start"]["x"], levelData["player_start"]["y"], sounds) | ||||
|         self.edge_warning_channel = None | ||||
|         self.weapon_hit_channel = None | ||||
|      | ||||
|         self.leftBoundary = levelData["boundaries"]["left"] | ||||
|         self.rightBoundary = levelData["boundaries"]["right"] | ||||
|         self.levelId = levelData["level_id"] | ||||
|  | ||||
|         # Create end of level object at right boundary | ||||
|         endLevel = Object( | ||||
|             self.rightBoundary, | ||||
|             0,  # Same y-level as player start | ||||
|             "end_of_level", | ||||
|             isStatic=True, | ||||
|             isCollectible=False, | ||||
|             isHazard=False | ||||
|         ) | ||||
|         self.objects.append(endLevel) | ||||
|  | ||||
|         # Load objects and enemies from level data | ||||
|         for obj in levelData["objects"]: | ||||
|             # Handle x position or range | ||||
| @@ -28,7 +41,7 @@ class Level: | ||||
|                 xPos = obj["x_range"] | ||||
|             else: | ||||
|                 xPos = [obj["x"], obj["x"]]  # Single position as range | ||||
|          | ||||
|      | ||||
|             # Check if this is a catapult | ||||
|             if obj.get("type") == "catapult": | ||||
|                 catapult = Catapult( | ||||
| @@ -40,6 +53,14 @@ class Level: | ||||
|                     firingRange=obj.get("range", 20) | ||||
|                 ) | ||||
|                 self.objects.append(catapult) | ||||
|             # Check if this is a coffin | ||||
|             elif obj.get("type") == "coffin": | ||||
|                 coffin = CoffinObject( | ||||
|                     xPos[0], | ||||
|                     obj["y"], | ||||
|                     self.sounds | ||||
|                 ) | ||||
|                 self.objects.append(coffin) | ||||
|             # Check if this is an enemy | ||||
|             elif "enemy_type" in obj: | ||||
|                 enemy = Enemy( | ||||
| @@ -66,6 +87,7 @@ class Level: | ||||
|                 self.objects.append(gameObject) | ||||
|  | ||||
|     def update_audio(self): | ||||
|         """Update all audio and entity state.""" | ||||
|         currentTime = pygame.time.get_ticks() | ||||
|          | ||||
|         # Update regular objects and check for zombie spawning | ||||
| @@ -156,7 +178,7 @@ class Level: | ||||
|                     if self.weapon_hit_channel is not None and not self.weapon_hit_channel.get_busy(): | ||||
|                         self.weapon_hit_channel = None | ||||
|  | ||||
|             # Check for coffin hits - only if we have any coffins | ||||
|             # Check for coffin hits | ||||
|             for obj in self.objects: | ||||
|                 if hasattr(obj, 'is_broken'):  # Check if it's a coffin without using isinstance | ||||
|                     if (not obj.is_broken and  | ||||
| @@ -164,25 +186,27 @@ class Level: | ||||
|                         obj.xPos <= attackRange[1] and | ||||
|                         self.player.isJumping):  # Must be jumping to hit floating coffins | ||||
|                      | ||||
|                             if obj.hit(self.player.xPos): | ||||
|                                     self.bouncing_items.append(obj.dropped_item) | ||||
|                                     speak(f"{obj.dropped_item.item_type} falls out!") | ||||
|                         if obj.hit(self.player.xPos): | ||||
|                             self.bouncing_items.append(obj.dropped_item) | ||||
|                             speak(f"{obj.dropped_item.item_type} falls out!") | ||||
|  | ||||
|     def handle_collisions(self): | ||||
|         """Handle all collision checks and return True if level is complete.""" | ||||
|         # First check if player is dead | ||||
|         if self.player.get_health() <= 0: | ||||
|             return False | ||||
|  | ||||
|         # Process object collisions for hazards and collectibles | ||||
|         for obj in self.objects: | ||||
|             if not obj.isActive: | ||||
|                 continue | ||||
|              | ||||
|          | ||||
|             # Handle grave edge warnings | ||||
|             if obj.isHazard: | ||||
|                 distance = abs(self.player.xPos - obj.xPos) | ||||
|                 # Check if within 1 tile and moving | ||||
|  | ||||
|                 if distance <= 2 and not self.player.isJumping: | ||||
|                     # Only play edge warning if not already playing | ||||
|                     if self.edge_warning_channel is None or not self.edge_warning_channel.get_busy(): | ||||
|                         self.edge_warning_channel = self.sounds['edge'].play() | ||||
|  | ||||
|             else: | ||||
|                 if self.edge_warning_channel is not None and not self.edge_warning_channel.get_busy(): | ||||
|                     self.edge_warning_channel = None | ||||
| @@ -200,7 +224,26 @@ class Level: | ||||
|                     self.sounds[obj.soundName].play() | ||||
|                     speak("You fell in an open grave!") | ||||
|                     self.player.set_health(0) | ||||
|                      | ||||
|                     return False | ||||
|  | ||||
|         # Handle boundaries | ||||
|         if self.player.xPos < self.leftBoundary: | ||||
|             self.player.xPos = self.leftBoundary | ||||
|             speak("Start of level!") | ||||
|  | ||||
|         # Check for level completion - takes precedence over everything except death | ||||
|         if self.player.get_health() > 0: | ||||
|             for obj in self.objects: | ||||
|                 if obj.soundName == "end_of_level": | ||||
|                     # Check if player has reached or passed the end marker | ||||
|                     if self.player.xPos >= obj.xPos: | ||||
|                         # Stop all current sounds and play end level sound | ||||
|                         pygame.mixer.stop() | ||||
|                         self.sounds["end_of_level"].play() | ||||
|                         return True | ||||
|  | ||||
|         return False | ||||
|  | ||||
|     def handle_projectiles(self, currentTime): | ||||
|         """Update projectiles and check for collisions""" | ||||
|         for proj in self.projectiles[:]:  # Copy list to allow removal | ||||
|   | ||||
		Reference in New Issue
	
	Block a user