mirror of
https://github.com/BreizhHardware/project_sanic.git
synced 2026-03-18 21:50:33 +01:00
Feat(Exit) - Implement Exit class for level completion; update game initialization and map parsing to support exits
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,4 +4,5 @@
|
||||
.idea
|
||||
.idea/*
|
||||
|
||||
checkpoint.db
|
||||
checkpoint.db
|
||||
checkpoint.db-journal
|
||||
11
main.py
11
main.py
@@ -3,7 +3,12 @@ import sys
|
||||
from pygame.locals import *
|
||||
|
||||
from src.Entity.Enemy import Enemy
|
||||
from src.game import initialize_game, reset_game, reset_game_with_checkpoint
|
||||
from src.game import (
|
||||
initialize_game,
|
||||
reset_game,
|
||||
reset_game_with_checkpoint,
|
||||
clear_checkpoint_database,
|
||||
)
|
||||
from src.constant import GameResources
|
||||
from src.Menu.Menu import Menu
|
||||
from src.Menu.Leaderboard import Leaderboard
|
||||
@@ -38,8 +43,10 @@ def main():
|
||||
menu = Menu(game_resources)
|
||||
leaderboard = Leaderboard(WIDTH, HEIGHT, font)
|
||||
|
||||
clear_checkpoint_database()
|
||||
|
||||
# Initialize game components
|
||||
P1, PT1, platforms, all_sprites, background, checkpoints = initialize_game(
|
||||
P1, PT1, platforms, all_sprites, background, checkpoints, exits = initialize_game(
|
||||
game_resources, "map_test.json"
|
||||
)
|
||||
projectiles = pygame.sprite.Group()
|
||||
|
||||
@@ -173,12 +173,14 @@
|
||||
"y": 700
|
||||
},
|
||||
|
||||
"exit": {
|
||||
"x": 2300,
|
||||
"y": 700,
|
||||
"width": 50,
|
||||
"height": 80,
|
||||
"next_level": "Level 2",
|
||||
"sprite": "assets/map/exit/door.png"
|
||||
}
|
||||
"exits": [
|
||||
{
|
||||
"x": 2300,
|
||||
"y": 700,
|
||||
"width": 50,
|
||||
"height": 80,
|
||||
"next_level": "Level 2",
|
||||
"sprite": "assets/map/exit/door.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -68,3 +68,12 @@ class CheckpointDB:
|
||||
"""Close database connection"""
|
||||
if self.conn:
|
||||
self.conn.close()
|
||||
|
||||
def clear_all(self):
|
||||
"""
|
||||
Clear all checkpoints from the database
|
||||
"""
|
||||
try:
|
||||
self.cursor.execute("DELETE FROM checkpoints")
|
||||
except Exception as e:
|
||||
print(f"Error clearing checkpoint database: {e}")
|
||||
|
||||
62
src/Entity/Exit.py
Normal file
62
src/Entity/Exit.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import pygame
|
||||
from src.Entity.Entity import Entity
|
||||
|
||||
|
||||
class Exit(Entity):
|
||||
"""
|
||||
Class representing a level exit/goal point that triggers level completion when touched.
|
||||
Inherits from Entity base class.
|
||||
"""
|
||||
|
||||
def __init__(self, x, y, width, height, next_level, sprite_path=None):
|
||||
"""
|
||||
Initialize the exit object.
|
||||
|
||||
Args:
|
||||
x (int): X-coordinate position
|
||||
y (int): Y-coordinate position
|
||||
width (int): Width of the exit
|
||||
height (int): Height of the exit
|
||||
next_level (str): ID or name of the level to load when exiting
|
||||
sprite_path (str, optional): Path to the sprite image for the exit
|
||||
"""
|
||||
super().__init__(pos=(x, y), size=(width, height), color=(0, 255, 0))
|
||||
self.next_level = next_level # Store the next level to load
|
||||
self.active = True # Flag to prevent multiple triggers
|
||||
self.player = None # Will store the player reference
|
||||
|
||||
# Load sprite if provided
|
||||
if sprite_path:
|
||||
try:
|
||||
self.image = pygame.image.load(sprite_path).convert_alpha()
|
||||
self.image = pygame.transform.scale(self.image, (width, height))
|
||||
self.surf = self.image
|
||||
except Exception as e:
|
||||
print(f"Error loading exit sprite: {e}")
|
||||
|
||||
def set_player(self, player):
|
||||
"""
|
||||
Set the player reference for collision detection.
|
||||
|
||||
Args:
|
||||
player: The player entity to check collision with
|
||||
"""
|
||||
self.player = player
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Check for collision with the player and trigger level completion.
|
||||
"""
|
||||
# Skip collision check if player reference is not set
|
||||
if not self.player or not self.active:
|
||||
return
|
||||
|
||||
# Check if player is colliding with exit
|
||||
if self.rect.colliderect(self.player.rect):
|
||||
# Create and post a level complete event
|
||||
exit_event = pygame.event.Event(
|
||||
pygame.USEREVENT,
|
||||
{"action": "level_complete", "next_level": self.next_level},
|
||||
)
|
||||
pygame.event.post(exit_event)
|
||||
self.active = False # Prevent multiple triggers
|
||||
@@ -5,6 +5,7 @@ from src.Entity.Platform import Platform
|
||||
from src.Entity.Player import Player
|
||||
from src.Entity.Enemy import Enemy
|
||||
from src.Entity.Checkpoint import Checkpoint
|
||||
from src.Entity.Exit import Exit
|
||||
|
||||
|
||||
class MapParser:
|
||||
@@ -12,6 +13,7 @@ class MapParser:
|
||||
self.game_resources = game_resources
|
||||
self.all_sprites = self.game_resources.all_sprites
|
||||
self.platforms = self.game_resources.platforms
|
||||
self.exits = self.game_resources.exits
|
||||
self.enemies = pygame.sprite.Group()
|
||||
self.collectibles = pygame.sprite.Group()
|
||||
self.checkpoints = pygame.sprite.Group()
|
||||
@@ -38,6 +40,7 @@ class MapParser:
|
||||
"height": map_data.get("height", self.game_resources.HEIGHT),
|
||||
},
|
||||
"checkpoints": self.checkpoints,
|
||||
"exits": self.exits,
|
||||
}
|
||||
except Exception as e:
|
||||
print(f"Error loading map: {e}")
|
||||
@@ -51,6 +54,7 @@ class MapParser:
|
||||
self.enemies.empty()
|
||||
self.collectibles.empty()
|
||||
self.checkpoints.empty()
|
||||
self.exits.empty()
|
||||
|
||||
# Create ground elements
|
||||
if "ground" in map_data:
|
||||
@@ -146,3 +150,16 @@ class MapParser:
|
||||
)
|
||||
self.checkpoints.add(checkpoint)
|
||||
self.all_sprites.add(checkpoint)
|
||||
|
||||
if "exits" in map_data:
|
||||
for exit_data in map_data["exits"]:
|
||||
exit = Exit(
|
||||
exit_data["x"],
|
||||
exit_data["y"],
|
||||
exit_data["width"],
|
||||
exit_data["height"],
|
||||
exit_data["next_level"],
|
||||
exit_data.get("sprite"),
|
||||
)
|
||||
self.exits.add(exit)
|
||||
self.all_sprites.add(exit)
|
||||
|
||||
@@ -18,13 +18,14 @@ class GameResources:
|
||||
|
||||
# Ressources
|
||||
self.platforms = pygame.sprite.Group()
|
||||
self.all_sprites = pygame.sprite.Group()
|
||||
self.exits = pygame.sprite.Group()
|
||||
self.vec = pygame.math.Vector2
|
||||
self.displaysurface = pygame.display.set_mode(
|
||||
(self.WIDTH, self.HEIGHT), pygame.RESIZABLE
|
||||
)
|
||||
pygame.display.set_caption("Project Sanic")
|
||||
self.FramePerSec = pygame.time.Clock()
|
||||
self.all_sprites = pygame.sprite.Group()
|
||||
|
||||
# Font
|
||||
try:
|
||||
|
||||
36
src/game.py
36
src/game.py
@@ -8,7 +8,16 @@ from src.Database.CheckpointDB import CheckpointDB
|
||||
|
||||
|
||||
def initialize_game(game_resources, map_file="map_test.json"):
|
||||
"""Initialize game with map from JSON file"""
|
||||
"""
|
||||
Initialize game with map from JSON file
|
||||
|
||||
Args:
|
||||
game_resources: GameResources object containing pygame resources
|
||||
map_file (str): Name of the map JSON file to load
|
||||
|
||||
Returns:
|
||||
tuple: (player, platform, platforms_group, all_sprites, background, checkpoints, exits)
|
||||
"""
|
||||
parser = MapParser(game_resources)
|
||||
map_objects = parser.load_map(map_file)
|
||||
|
||||
@@ -31,8 +40,15 @@ def initialize_game(game_resources, map_file="map_test.json"):
|
||||
game_resources.all_sprites,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
|
||||
# Set player reference for exits if they exist
|
||||
exits = map_objects.get("exits", None)
|
||||
if exits and map_objects["player"]:
|
||||
for exit_obj in exits:
|
||||
exit_obj.set_player(map_objects["player"])
|
||||
|
||||
return (
|
||||
map_objects["player"],
|
||||
None,
|
||||
@@ -40,13 +56,14 @@ def initialize_game(game_resources, map_file="map_test.json"):
|
||||
map_objects["all_sprites"],
|
||||
parser.background,
|
||||
map_objects["checkpoints"],
|
||||
exits,
|
||||
)
|
||||
|
||||
|
||||
def reset_game(game_resources):
|
||||
"""Reset the game to initial state"""
|
||||
# Reload game objects
|
||||
player, _, platforms, all_sprites, background, checkpoints = initialize_game(
|
||||
player, _, platforms, all_sprites, background, checkpoints, exits = initialize_game(
|
||||
game_resources, "map_test.json"
|
||||
)
|
||||
|
||||
@@ -66,7 +83,7 @@ def reset_game_with_checkpoint(map_name, game_resources):
|
||||
checkpoint_pos = db.get_checkpoint(map_name)
|
||||
|
||||
# Initialize game
|
||||
player, _, platforms, all_sprites, background, checkpoints = initialize_game(
|
||||
player, _, platforms, all_sprites, background, checkpoints, exits = initialize_game(
|
||||
game_resources, map_name
|
||||
)
|
||||
|
||||
@@ -78,5 +95,18 @@ def reset_game_with_checkpoint(map_name, game_resources):
|
||||
return player, platforms, all_sprites, background, checkpoints
|
||||
|
||||
|
||||
def clear_checkpoint_database():
|
||||
"""
|
||||
Clear all checkpoints from the database.
|
||||
Used when starting a new game session.
|
||||
"""
|
||||
try:
|
||||
db = CheckpointDB()
|
||||
db.clear_all()
|
||||
print("Checkpoint database cleared successfully")
|
||||
except Exception as e:
|
||||
print(f"Error clearing checkpoint database: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Please run the game using main.py")
|
||||
|
||||
Reference in New Issue
Block a user