mirror of
https://github.com/BreizhHardware/project_sanic.git
synced 2026-03-18 21:50:33 +01:00
Merge pull request #13 from BreizhHardware/dev_felix
Refactor(Game) - Introduce GameResources class to centralize game con…
This commit is contained in:
45
main.py
45
main.py
@@ -4,17 +4,7 @@ from pygame.locals import *
|
||||
|
||||
from src.Entity.Enemy import Enemy
|
||||
from src.game import initialize_game, reset_game, reset_game_with_checkpoint
|
||||
from src.constant import (
|
||||
displaysurface,
|
||||
FramePerSec,
|
||||
font,
|
||||
FPS,
|
||||
WIDTH,
|
||||
HEIGHT,
|
||||
ORIGINAL_WIDTH,
|
||||
ORIGINAL_HEIGHT,
|
||||
fullscreen,
|
||||
)
|
||||
from src.constant import GameResources
|
||||
from src.Menu.Menu import Menu
|
||||
from src.Menu.Leaderboard import Leaderboard
|
||||
from src.Camera import Camera
|
||||
@@ -22,11 +12,20 @@ from src.Database.CheckpointDB import CheckpointDB
|
||||
|
||||
|
||||
def main():
|
||||
# Declare globals that we'll modify
|
||||
global displaysurface, fullscreen, ORIGINAL_WIDTH, ORIGINAL_HEIGHT
|
||||
# Initialize Pygame and game resources
|
||||
game_resources = GameResources()
|
||||
displaysurface = game_resources.displaysurface
|
||||
FramePerSec = game_resources.FramePerSec
|
||||
font = game_resources.font
|
||||
FPS = game_resources.FPS
|
||||
WIDTH = game_resources.WIDTH
|
||||
HEIGHT = game_resources.HEIGHT
|
||||
ORIGINAL_WIDTH = game_resources.ORIGINAL_WIDTH
|
||||
ORIGINAL_HEIGHT = game_resources.ORIGINAL_HEIGHT
|
||||
fullscreen = game_resources.fullscreen
|
||||
|
||||
# Add camera initialization
|
||||
camera = Camera(WIDTH, HEIGHT)
|
||||
camera = Camera(WIDTH, HEIGHT, game_resources)
|
||||
|
||||
# Game states
|
||||
MENU = 0
|
||||
@@ -36,12 +35,12 @@ def main():
|
||||
|
||||
# Initialize game state and objects
|
||||
current_state = MENU
|
||||
menu = Menu()
|
||||
leaderboard = Leaderboard()
|
||||
menu = Menu(game_resources)
|
||||
leaderboard = Leaderboard(WIDTH, HEIGHT, font)
|
||||
|
||||
# Initialize game components
|
||||
P1, PT1, platforms, all_sprites, background, checkpoints = initialize_game(
|
||||
"map_test.json"
|
||||
game_resources, "map_test.json"
|
||||
)
|
||||
projectiles = pygame.sprite.Group()
|
||||
|
||||
@@ -88,14 +87,12 @@ def main():
|
||||
if checkpoint_pos:
|
||||
# Respawn player at checkpoint
|
||||
P1, platforms, all_sprites, background, checkpoints = (
|
||||
reset_game_with_checkpoint("map_test.json")
|
||||
reset_game_with_checkpoint("map_test.json", game_resources)
|
||||
)
|
||||
projectiles.empty()
|
||||
print("Joueur réanimé au checkpoint")
|
||||
else:
|
||||
# No checkpoint found, return to menu
|
||||
current_state = MENU
|
||||
print("Game over - retour au menu")
|
||||
if event.dict.get("action") == "create_projectile":
|
||||
projectile = event.dict.get("projectile")
|
||||
projectiles.add(projectile)
|
||||
@@ -104,7 +101,9 @@ def main():
|
||||
if current_state == MENU:
|
||||
action = menu.handle_event(event)
|
||||
if action == "play":
|
||||
P1, platforms, all_sprites, background, checkpoints = reset_game()
|
||||
P1, platforms, all_sprites, background, checkpoints = reset_game(
|
||||
game_resources
|
||||
)
|
||||
current_state = PLAYING
|
||||
elif action == "infinite":
|
||||
current_state = INFINITE
|
||||
@@ -185,10 +184,6 @@ def main():
|
||||
camera_adjusted_rect.y += camera.camera.y
|
||||
displaysurface.blit(projectile.surf, camera_adjusted_rect)
|
||||
|
||||
print(
|
||||
f"Projectile: pos={projectile.pos}, rect={projectile.rect}, camera={camera.camera}"
|
||||
)
|
||||
|
||||
checkpoints_hit = pygame.sprite.spritecollide(P1, checkpoints, False)
|
||||
for checkpoint in checkpoints_hit:
|
||||
checkpoint.activate()
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# src/Camera.py
|
||||
import pygame
|
||||
from src.constant import WIDTH, HEIGHT
|
||||
|
||||
|
||||
class Camera:
|
||||
def __init__(self, width, height):
|
||||
def __init__(self, width, height, game_resources):
|
||||
self.camera = pygame.Rect(0, 0, width, height)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.game_resources = game_resources
|
||||
|
||||
def update(self, target):
|
||||
# Center the target in the camera view
|
||||
x = -target.rect.centerx + WIDTH // 2
|
||||
y = -target.rect.centery + HEIGHT // 2
|
||||
x = -target.rect.centerx + self.game_resources.WIDTH // 2
|
||||
y = -target.rect.centery + self.game_resources.HEIGHT // 2
|
||||
|
||||
# Update camera position
|
||||
self.camera = pygame.Rect(x, y, self.width, self.height)
|
||||
|
||||
@@ -43,6 +43,5 @@ class Checkpoint(Entity):
|
||||
# Save checkpoint to database
|
||||
self.db.save_checkpoint(self.map_name, self.pos.x, self.pos.y)
|
||||
|
||||
print("checkpoint")
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import pygame
|
||||
from src.Entity.Entity import Entity
|
||||
from src.constant import FPS
|
||||
from pygame.math import Vector2 as vec
|
||||
from src.Entity.Projectile import Projectile
|
||||
|
||||
@@ -98,7 +97,7 @@ class Enemy(Entity):
|
||||
else:
|
||||
self.detected_player = False
|
||||
|
||||
def stationary_attack(self, player):
|
||||
def stationary_attack(self, player, FPS=60):
|
||||
"""Remote attack for turret-like enemies"""
|
||||
distance_to_player = vec(
|
||||
player.pos.x - self.pos.x, player.pos.y - self.pos.y
|
||||
@@ -140,7 +139,6 @@ class Enemy(Entity):
|
||||
self.health -= amount
|
||||
if self.health <= 0:
|
||||
self.kill()
|
||||
print("Enemy killed!")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
from src.Entity.Entity import Entity
|
||||
from src.constant import WIDTH, vec, ACC, FRIC, platforms, FPS, life_icon_width
|
||||
from pygame import *
|
||||
import pygame
|
||||
import os
|
||||
|
||||
|
||||
class Player(Entity):
|
||||
def __init__(self, width=100, height=100, x=10, y=385):
|
||||
def __init__(self, game_resources, width=100, height=100, x=10, y=385):
|
||||
super().__init__(pos=(x, y), size=(width, height), color=(128, 255, 40))
|
||||
|
||||
# Game ressources
|
||||
self.game_resources = game_resources
|
||||
|
||||
# Animation variables
|
||||
self.animation_frames = []
|
||||
self.jump_frames = []
|
||||
@@ -106,11 +108,20 @@ class Player(Entity):
|
||||
"assets/player/Sanic Head.png"
|
||||
).convert_alpha()
|
||||
self.life_icon = pygame.transform.scale(
|
||||
self.life_icon, (life_icon_width, life_icon_width)
|
||||
self.life_icon,
|
||||
(
|
||||
self.game_resources.life_icon_width,
|
||||
self.game_resources.life_icon_width,
|
||||
),
|
||||
)
|
||||
else:
|
||||
# Backup: use a red square
|
||||
self.life_icon = pygame.Surface((life_icon_width, life_icon_width))
|
||||
self.life_icon = pygame.Surface(
|
||||
(
|
||||
self.game_resources.life_icon_width,
|
||||
self.game_resources.life_icon_width,
|
||||
)
|
||||
)
|
||||
self.life_icon.fill((255, 0, 0))
|
||||
|
||||
except Exception as e:
|
||||
@@ -155,7 +166,7 @@ class Player(Entity):
|
||||
if self.dashing and current_time - self.dash_start_time >= self.dash_duration:
|
||||
self.dashing = False
|
||||
|
||||
self.acc = vec(0, 1) # Gravity
|
||||
self.acc = self.game_resources.vec(0, 1)
|
||||
|
||||
# Reset flags
|
||||
self.moving = False
|
||||
@@ -164,15 +175,15 @@ class Player(Entity):
|
||||
if pressed_keys[K_q]:
|
||||
# Check if X is > 0 to prevent player from going off screen
|
||||
if self.pos.x > 0:
|
||||
self.acc.x = -ACC
|
||||
self.acc.x = -self.game_resources.ACC
|
||||
self.moving = True
|
||||
if pressed_keys[K_a]:
|
||||
self.dash(-ACC)
|
||||
self.dash(-self.game_resources.ACC)
|
||||
if pressed_keys[K_d]:
|
||||
self.acc.x = ACC
|
||||
self.acc.x = self.game_resources.ACC
|
||||
self.moving = True
|
||||
if pressed_keys[K_a]:
|
||||
self.dash(ACC)
|
||||
self.dash(self.game_resources.ACC)
|
||||
|
||||
# Also consider the player moving if they have significant horizontal velocity
|
||||
if abs(self.vel.x) > 0.5:
|
||||
@@ -184,8 +195,8 @@ class Player(Entity):
|
||||
self.jumping = True
|
||||
|
||||
# Apply friction
|
||||
self.acc.y += self.vel.y * FRIC
|
||||
self.acc.x += self.vel.x * FRIC
|
||||
self.acc.y += self.vel.y * self.game_resources.FRIC
|
||||
self.acc.x += self.vel.x * self.game_resources.FRIC
|
||||
self.vel += self.acc
|
||||
self.pos += self.vel + 0.5 * self.acc
|
||||
|
||||
@@ -215,7 +226,7 @@ class Player(Entity):
|
||||
)
|
||||
|
||||
def update(self):
|
||||
hits = pygame.sprite.spritecollide(self, platforms, False)
|
||||
hits = pygame.sprite.spritecollide(self, self.game_resources.platforms, False)
|
||||
if hits:
|
||||
if self.vel.y > 0:
|
||||
self.pos.y = hits[0].rect.top
|
||||
@@ -223,7 +234,7 @@ class Player(Entity):
|
||||
self.jumping = False
|
||||
|
||||
if self.invulnerable:
|
||||
self.invulnerable_timer += 1 / FPS
|
||||
self.invulnerable_timer += 1 / self.game_resources.FPS
|
||||
if self.invulnerable_timer >= self.invulnerable_duration:
|
||||
self.invulnerable = False
|
||||
self.invulnerable_timer = 0
|
||||
@@ -249,14 +260,20 @@ class Player(Entity):
|
||||
def draw_lives(self, surface):
|
||||
"""Draws the player's remaining lives as icons in the top right corner."""
|
||||
spacing = 5
|
||||
start_x = surface.get_width() - (self.max_lives * (life_icon_width + spacing))
|
||||
start_x = surface.get_width() - (
|
||||
self.max_lives * (self.game_resources.life_icon_width + spacing)
|
||||
)
|
||||
start_y = 10
|
||||
|
||||
for i in range(self.max_lives):
|
||||
if i < self.lives:
|
||||
# Vie active: afficher l'icône normale
|
||||
surface.blit(
|
||||
self.life_icon, (start_x + i * (life_icon_width + spacing), start_y)
|
||||
self.life_icon,
|
||||
(
|
||||
start_x + i * (self.game_resources.life_icon_width + spacing),
|
||||
start_y,
|
||||
),
|
||||
)
|
||||
else:
|
||||
# Vie perdue: afficher l'icône grisée
|
||||
@@ -268,5 +285,9 @@ class Player(Entity):
|
||||
gray = (color[0] + color[1] + color[2]) // 3
|
||||
grayscale_icon.set_at((x, y), (gray, gray, gray, color[3]))
|
||||
surface.blit(
|
||||
grayscale_icon, (start_x + i * (life_icon_width + spacing), start_y)
|
||||
grayscale_icon,
|
||||
(
|
||||
start_x + i * (self.game_resources.life_icon_width + spacing),
|
||||
start_y,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -5,13 +5,13 @@ 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.constant import WIDTH, HEIGHT, all_sprites, platforms
|
||||
|
||||
|
||||
class MapParser:
|
||||
def __init__(self):
|
||||
self.all_sprites = all_sprites
|
||||
self.platforms = platforms
|
||||
def __init__(self, game_resources):
|
||||
self.game_resources = game_resources
|
||||
self.all_sprites = self.game_resources.all_sprites
|
||||
self.platforms = self.game_resources.platforms
|
||||
self.enemies = pygame.sprite.Group()
|
||||
self.collectibles = pygame.sprite.Group()
|
||||
self.checkpoints = pygame.sprite.Group()
|
||||
@@ -34,8 +34,8 @@ class MapParser:
|
||||
"collectibles": self.collectibles,
|
||||
"map_properties": {
|
||||
"name": map_data.get("name", "Unnamed Level"),
|
||||
"width": map_data.get("width", WIDTH),
|
||||
"height": map_data.get("height", HEIGHT),
|
||||
"width": map_data.get("width", self.game_resources.WIDTH),
|
||||
"height": map_data.get("height", self.game_resources.HEIGHT),
|
||||
},
|
||||
"checkpoints": self.checkpoints,
|
||||
}
|
||||
@@ -105,7 +105,7 @@ class MapParser:
|
||||
|
||||
# Create player at spawn point
|
||||
spawn = map_data.get("spawn_point", {"x": 50, "y": 700})
|
||||
self.player = Player()
|
||||
self.player = Player(self.game_resources)
|
||||
self.player.pos.x = spawn["x"]
|
||||
self.player.pos.y = spawn["y"]
|
||||
self.all_sprites.add(self.player)
|
||||
@@ -125,12 +125,12 @@ class MapParser:
|
||||
|
||||
# Create background image
|
||||
if "background" in map_data:
|
||||
print(f"Loading background image: {map_data['background']}")
|
||||
if os.path.isfile(map_data["background"]):
|
||||
background = pygame.image.load(map_data["background"]).convert_alpha()
|
||||
background = pygame.transform.scale(background, (WIDTH, HEIGHT))
|
||||
background = pygame.transform.scale(
|
||||
background, (self.game_resources.WIDTH, self.game_resources.HEIGHT)
|
||||
)
|
||||
self.background = background
|
||||
print("Background image loaded")
|
||||
else:
|
||||
print(f"Background image not found: {map_data['background']}")
|
||||
else:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from pygame.locals import *
|
||||
import pygame
|
||||
from src.constant import font
|
||||
|
||||
|
||||
class Button:
|
||||
@@ -13,7 +12,7 @@ class Button:
|
||||
self.action = action
|
||||
self.hover = False
|
||||
|
||||
def draw(self, surface):
|
||||
def draw(self, surface, font):
|
||||
# Button colors
|
||||
color = (100, 149, 237) if self.hover else (65, 105, 225)
|
||||
border_color = (255, 255, 255)
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
import pygame
|
||||
from src.constant import WIDTH, HEIGHT, font
|
||||
from src.Menu.Button import Button
|
||||
|
||||
|
||||
class Leaderboard:
|
||||
def __init__(self):
|
||||
def __init__(self, HEIGHT, WIDTH, font):
|
||||
self.HEIGHT = HEIGHT
|
||||
self.WIDTH = WIDTH
|
||||
self.font = font
|
||||
self.tabs = ["Mode Normal", "Mode Infini"]
|
||||
self.current_tab = 0
|
||||
self.scores = {
|
||||
0: [("Player1", 1000), ("Player2", 800), ("Player3", 600)],
|
||||
1: [("Player1", 2000), ("Player2", 1500), ("Player3", 1200)],
|
||||
}
|
||||
self.back_button = Button("Retour", 20, HEIGHT - 70, 120, 50, "menu")
|
||||
self.back_button = Button("Retour", 20, self.HEIGHT - 70, 120, 50, "menu")
|
||||
tab_width = 150
|
||||
self.tab_buttons = [
|
||||
Button(self.tabs[0], WIDTH // 2 - tab_width, 80, tab_width, 40, "tab_0"),
|
||||
Button(self.tabs[1], WIDTH // 2, 80, tab_width, 40, "tab_1"),
|
||||
Button(
|
||||
self.tabs[0], self.WIDTH // 2 - tab_width, 80, tab_width, 40, "tab_0"
|
||||
),
|
||||
Button(self.tabs[1], self.WIDTH // 2, 80, tab_width, 40, "tab_1"),
|
||||
]
|
||||
|
||||
def draw(self, surface):
|
||||
@@ -23,7 +27,7 @@ class Leaderboard:
|
||||
title = pygame.font.SysFont("Arial", 48).render(
|
||||
"Classement", True, (0, 191, 255)
|
||||
)
|
||||
title_rect = title.get_rect(center=(WIDTH // 2, 40))
|
||||
title_rect = title.get_rect(center=(self.WIDTH // 2, 40))
|
||||
surface.blit(title, title_rect)
|
||||
|
||||
# Draw tabs
|
||||
@@ -39,8 +43,12 @@ class Leaderboard:
|
||||
# Draw scores
|
||||
y_pos = 150
|
||||
for i, (name, score) in enumerate(self.scores[self.current_tab]):
|
||||
rank_text = font.render(f"{i+1}. {name}: {score}", True, (255, 255, 255))
|
||||
surface.blit(rank_text, (WIDTH // 2 - rank_text.get_width() // 2, y_pos))
|
||||
rank_text = self.font.render(
|
||||
f"{i+1}. {name}: {score}", True, (255, 255, 255)
|
||||
)
|
||||
surface.blit(
|
||||
rank_text, (self.WIDTH // 2 - rank_text.get_width() // 2, y_pos)
|
||||
)
|
||||
y_pos += 40
|
||||
|
||||
self.back_button.draw(surface)
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import pygame
|
||||
from src.constant import HEIGHT, WIDTH
|
||||
from src.Menu.Button import Button
|
||||
|
||||
|
||||
class Menu:
|
||||
def __init__(self):
|
||||
def __init__(self, game_resources):
|
||||
self.game_resources = game_resources
|
||||
self.buttons = []
|
||||
button_width = 250
|
||||
button_height = 60
|
||||
button_spacing = 20
|
||||
start_y = HEIGHT // 2 - 100
|
||||
start_y = self.game_resources.HEIGHT // 2 - 100
|
||||
|
||||
# Create buttons centered horizontally
|
||||
self.buttons.append(
|
||||
Button(
|
||||
"Jouer",
|
||||
WIDTH // 2 - button_width // 2,
|
||||
self.game_resources.WIDTH // 2 - button_width // 2,
|
||||
start_y,
|
||||
button_width,
|
||||
button_height,
|
||||
@@ -27,7 +27,7 @@ class Menu:
|
||||
self.buttons.append(
|
||||
Button(
|
||||
"Jouer en mode infini",
|
||||
WIDTH // 2 - button_width // 2,
|
||||
self.game_resources.WIDTH // 2 - button_width // 2,
|
||||
start_y,
|
||||
button_width,
|
||||
button_height,
|
||||
@@ -39,7 +39,7 @@ class Menu:
|
||||
self.buttons.append(
|
||||
Button(
|
||||
"Classement",
|
||||
WIDTH // 2 - button_width // 2,
|
||||
self.game_resources.WIDTH // 2 - button_width // 2,
|
||||
start_y,
|
||||
button_width,
|
||||
button_height,
|
||||
@@ -51,7 +51,7 @@ class Menu:
|
||||
self.buttons.append(
|
||||
Button(
|
||||
"Quitter",
|
||||
WIDTH // 2 - button_width // 2,
|
||||
self.game_resources.WIDTH // 2 - button_width // 2,
|
||||
start_y,
|
||||
button_width,
|
||||
button_height,
|
||||
@@ -64,12 +64,14 @@ class Menu:
|
||||
title = pygame.font.SysFont("Arial", 72).render(
|
||||
"Project Sanic", True, (0, 191, 255)
|
||||
)
|
||||
title_rect = title.get_rect(center=(WIDTH // 2, HEIGHT // 4))
|
||||
title_rect = title.get_rect(
|
||||
center=(self.game_resources.WIDTH // 2, self.game_resources.HEIGHT // 4)
|
||||
)
|
||||
surface.blit(title, title_rect)
|
||||
|
||||
# Draw buttons
|
||||
for button in self.buttons:
|
||||
button.draw(surface)
|
||||
button.draw(surface, self.game_resources.font)
|
||||
|
||||
def handle_event(self, event):
|
||||
for button in self.buttons:
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
import pygame
|
||||
|
||||
pygame.init()
|
||||
|
||||
FPS = 60
|
||||
ACC = 0.5
|
||||
FRIC = -0.12
|
||||
WIDTH = 1200
|
||||
HEIGHT = 800
|
||||
platforms = pygame.sprite.Group()
|
||||
vec = pygame.math.Vector2
|
||||
displaysurface = pygame.display.set_mode((WIDTH, HEIGHT), pygame.RESIZABLE)
|
||||
pygame.display.set_caption("Project Sanic")
|
||||
FramePerSec = pygame.time.Clock()
|
||||
all_sprites = pygame.sprite.Group()
|
||||
fullscreen = False
|
||||
ORIGINAL_WIDTH = WIDTH
|
||||
ORIGINAL_HEIGHT = HEIGHT
|
||||
life_icon_width = 50
|
||||
class GameResources:
|
||||
def __init__(self):
|
||||
pygame.init()
|
||||
|
||||
try:
|
||||
font = pygame.font.SysFont("Arial", 20)
|
||||
except:
|
||||
font = pygame.font.Font(None, 20)
|
||||
# Constantes
|
||||
self.FPS = 60
|
||||
self.ACC = 0.5
|
||||
self.FRIC = -0.12
|
||||
self.WIDTH = 1200
|
||||
self.HEIGHT = 800
|
||||
self.ORIGINAL_WIDTH = self.WIDTH
|
||||
self.ORIGINAL_HEIGHT = self.HEIGHT
|
||||
self.life_icon_width = 50
|
||||
self.fullscreen = False
|
||||
|
||||
# Ressources
|
||||
self.platforms = 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:
|
||||
self.font = pygame.font.SysFont("Arial", 20)
|
||||
except:
|
||||
self.font = pygame.font.Font(None, 20)
|
||||
|
||||
66
src/game.py
66
src/game.py
@@ -3,83 +3,77 @@ import sys
|
||||
from pygame.locals import *
|
||||
from src.Entity.Platform import Platform
|
||||
from src.Entity.Player import Player
|
||||
from src.constant import (
|
||||
displaysurface,
|
||||
FramePerSec,
|
||||
font,
|
||||
FPS,
|
||||
platforms,
|
||||
all_sprites,
|
||||
vec,
|
||||
)
|
||||
from src.Map.parser import MapParser
|
||||
from src.Database.CheckpointDB import CheckpointDB
|
||||
|
||||
|
||||
def initialize_game(map_file="map_test.json"):
|
||||
def initialize_game(game_resources, map_file="map_test.json"):
|
||||
"""Initialize game with map from JSON file"""
|
||||
parser = MapParser()
|
||||
parser = MapParser(game_resources)
|
||||
map_objects = parser.load_map(map_file)
|
||||
|
||||
if not map_objects:
|
||||
# Fallback to default setup if map loading fails
|
||||
platforms.empty()
|
||||
all_sprites.empty()
|
||||
game_resources.platforms.empty()
|
||||
game_resources.all_sprites.empty()
|
||||
|
||||
PT1 = Platform(1200, 20, 600, 400)
|
||||
P1 = Player()
|
||||
P1 = Player(game_resources)
|
||||
|
||||
platforms.add(PT1)
|
||||
all_sprites.add(PT1)
|
||||
all_sprites.add(P1)
|
||||
game_resources.platforms.add(PT1)
|
||||
game_resources.all_sprites.add(PT1)
|
||||
game_resources.all_sprites.add(P1)
|
||||
|
||||
return P1, PT1, platforms, all_sprites, None # Return None for background
|
||||
return (
|
||||
P1,
|
||||
PT1,
|
||||
game_resources.platforms,
|
||||
game_resources.all_sprites,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
|
||||
return (
|
||||
map_objects["player"],
|
||||
None, # No specific platform reference needed
|
||||
None,
|
||||
map_objects["platforms"],
|
||||
map_objects["all_sprites"],
|
||||
parser.background, # Return the loaded background
|
||||
parser.background,
|
||||
map_objects["checkpoints"],
|
||||
)
|
||||
|
||||
|
||||
def reset_game():
|
||||
def reset_game(game_resources):
|
||||
"""Reset the game to initial state"""
|
||||
global platforms, all_sprites, camera
|
||||
|
||||
# Empty all sprite groups
|
||||
platforms.empty()
|
||||
all_sprites.empty()
|
||||
|
||||
# Reload game objects
|
||||
player, _, platforms, all_sprites, background, checkpoints = initialize_game(
|
||||
"map_test.json"
|
||||
game_resources, "map_test.json"
|
||||
)
|
||||
|
||||
return player, platforms, all_sprites, background, checkpoints
|
||||
|
||||
|
||||
def reset_game_with_checkpoint(map_name="map_test.json"):
|
||||
def reset_game_with_checkpoint(map_name, game_resources):
|
||||
"""
|
||||
Reset the game and respawn player at checkpoint if available
|
||||
|
||||
Args:
|
||||
map_name: Name of the current map
|
||||
game_resources: GameResources object
|
||||
"""
|
||||
# Initialize game normally
|
||||
player, platforms, all_sprites, background, checkpoints = reset_game()
|
||||
|
||||
# Check if there's a saved checkpoint
|
||||
# Check the checkpoint database for saved checkpoint
|
||||
db = CheckpointDB()
|
||||
checkpoint_pos = db.get_checkpoint(map_name)
|
||||
|
||||
# If checkpoint exists, teleport player there
|
||||
# Initialize game
|
||||
player, _, platforms, all_sprites, background, checkpoints = initialize_game(
|
||||
game_resources, map_name
|
||||
)
|
||||
|
||||
# If checkpoint exists, respawn player at checkpoint
|
||||
if checkpoint_pos:
|
||||
player.pos = vec(checkpoint_pos[0], checkpoint_pos[1])
|
||||
player.pos = game_resources.vec(checkpoint_pos[0], checkpoint_pos[1])
|
||||
player.update_rect()
|
||||
print(f"Player respawned at checkpoint: {checkpoint_pos}")
|
||||
|
||||
return player, platforms, all_sprites, background, checkpoints
|
||||
|
||||
|
||||
Reference in New Issue
Block a user