ATCS Platform Game
# Globals
# Entirely written by humans
def init():
    global screen
    global scene_manager
    global SCREEN_WIDTH
    global SCREEN_HEIGHT

globals.py
Alexandre2006/PlatformGame
# Main File
# Entirely written by humans, with assistance from Copilot (75% human, 25% AI)

import pygame
from pygame.locals import *
from sys import exit
import globals
from scenes.death import DeathScene

from utils.scene_manager import SceneManager
from scenes.title import TitleScene

# Initialize globals
globals.init()

# Initialize pygame
pygame.init()

# Create game window
globals.SCREEN_WIDTH = 800
globals.SCREEN_HEIGHT = 800
globals.screen = pygame.display.set_mode((globals.SCREEN_WIDTH, globals.SCREEN_HEIGHT))

# Create clock
clock = pygame.time.Clock()

# Init Music
pygame.mixer.init()
pygame.mixer.music.set_volume(0.7)

# Set window caption
pygame.display.set_caption("ASCENT (ATCS PlatformGame)")

# Create scene manager
globals.scene_manager = SceneManager()

# Register scenes
globals.scene_manager.register_scene("title", TitleScene())

# Switch to the first scene
globals.scene_manager.switch_scene("title")

# Game loop
while True:
    # Get all events
    events = pygame.event.get()

    # Handle Quit event
    for event in events:
        if event.type == QUIT:
            pygame.quit()
            exit()

    # Update current scene
    globals.scene_manager.update_current_scene()

    # Render current scene 
    globals.scene_manager.render_current_scene()

    # Wait for next frame
    clock.tick(60)

    # Update screen
    pygame.display.flip()
main.py
Alexandre2006/PlatformGame
# Title Scene
# Entirely written by humans with assistance from Copilot (75% human, 25% AI)
import pygame
import globals

from utils.scene import SceneBase

class DeathScene(SceneBase):
    def __init__(self, score):
        self.title_font = pygame.font.Font("./shared/fonts/Pixeboy.ttf", 128)
        self.button_font = pygame.font.Font("./shared/fonts/Pixeboy.ttf", 40)
        self.mouse_pressed = False
        self.mouse_prev_pressed = False
        self.score = score

    def update(self, dt):
        self.dt = dt
        self.mouse_prev_pressed = self.mouse_pressed
        self.mouse_pressed = pygame.mouse.get_pressed()[0]
        pass

    def render(self):
        # Clear screen
        globals.screen.fill((0, 0, 0))

        # Draw title
        title = self.title_font.render("YOU DIED", True, (255, 0, 0))
        globals.screen.blit(title, ((globals.SCREEN_WIDTH - self.title_font.size("YOU DIED")[0]) / 2, 76))

        # Draw subtitle
        subtitle = self.button_font.render(f"Score: {self.score}", True, (255, 255, 255))
        globals.screen.blit(subtitle, ((globals.SCREEN_WIDTH - self.button_font.size(f"Score: {self.score}")[0]) / 2, 170))

        # Cursor Position
        mouse_x, mouse_y = pygame.mouse.get_pos()

        # Add play button
        play_button_x = (globals.SCREEN_WIDTH - self.button_font.size("Main Menu")[0]) / 2
        play_button_y = 350
        play_button_width = self.button_font.size("Main Menu")[0] 
        play_button_height = self.button_font.size("Main Menu")[1]

        play_box_x = play_button_x - 50
        play_box_y = play_button_y - (play_button_height / 2) - 20
        play_box_width = play_button_width + 100
        play_box_height = play_button_height + play_button_height + 40

        play_box_color = (128, 128, 128)

        if mouse_x > play_box_x and mouse_x < play_box_x + play_box_width and mouse_y > play_box_y and mouse_y < play_box_y + play_box_height:
            play_box_color = (196, 196, 196)
            if self.mouse_prev_pressed and not self.mouse_pressed:
                globals.scene_manager.switch_scene("title")
                
        pygame.draw.rect(globals.screen, play_box_color, (play_box_x, play_box_y, play_box_width, play_box_height))
        play_button = self.button_font.render("Main Menu", True, (0, 0, 0))
        globals.screen.blit(play_button, (play_button_x, play_button_y))

        # Add exit button
        exit_button_x = (globals.SCREEN_WIDTH - self.button_font.size("Quit Game")[0]) / 2
        exit_button_y = 550
        exit_button_width = self.button_font.size("Quit Game")[0] 
        exit_button_height = self.button_font.size("Quit Game")[1]

        exit_box_x = exit_button_x - 50
        exit_box_y = exit_button_y - (play_button_height / 2) - 20
        exit_box_width = exit_button_width + 100
        exit_box_height = exit_button_height + exit_button_height + 40 

        exit_box_color = (128, 128, 128)
        
        if mouse_x > exit_box_x and mouse_x < exit_box_x + exit_box_width and mouse_y > exit_box_y and mouse_y < exit_box_y + exit_box_height:
            exit_box_color = (196, 196, 196)
            if self.mouse_prev_pressed and not self.mouse_pressed:
                pygame.quit()
                exit()
        
        pygame.draw.rect(globals.screen, exit_box_color, (exit_box_x, exit_box_y, exit_box_width, exit_box_height))
        exit_button = self.button_font.render("Quit Game", True, (0, 0, 0))
        globals.screen.blit(exit_button, (exit_button_x, exit_button_y))
    
    def switch_to(self):
        # Play music
        pygame.mixer.music.load("./shared/music/death.wav")
        pygame.mixer.music.play(-1)

    def handle_events(self, events):        
        pass # Title scene does not handle any events
scenes/death.py
Alexandre2006/PlatformGame
# Main Game Scene
# Entirely written by humans with assistance from Copilot (75% human, 25% AI)
import math
import random
import pygame
import globals
from scenes.death import DeathScene
from utils.camera import Camera
from utils.platform import Platform
from utils.platform_gen import PlatformGenerator
from utils.player import Player

from utils.scene import SceneBase


class GameScene(SceneBase):
    def __init__(self):
        self.camera = Camera()
        self.player = Player()
        self.angle = 0
        self.score_font = pygame.font.Font("./shared/fonts/Pixeboy.ttf", 32)
        self.platforms = [
            Platform(0, 100, Platform.TYPE_GRASS, platform_width_type=Platform.WIDTH_FLOOR, platform_x_velocity=0),
            Platform(0, 400, Platform.TYPE_GRASS, platform_width_type=Platform.WIDTH_THICK, platform_x_velocity=0),
            Platform(560, 400, Platform.TYPE_GRASS, platform_width_type=Platform.WIDTH_THICK, platform_x_velocity=0),
            Platform(280, 700, Platform.TYPE_GRASS, platform_width_type=Platform.WIDTH_THICK, platform_x_velocity=0),
            Platform(0, 1000, Platform.TYPE_ICE, platform_width_type=Platform.WIDTH_THICK, platform_x_velocity=0),
            Platform(280, 1000, Platform.TYPE_SPIKE, platform_width_type=Platform.WIDTH_THIN, platform_x_velocity=0),
            Platform(560, 1000, Platform.TYPE_ICE, platform_width_type=Platform.WIDTH_THICK, platform_x_velocity=0),
            ]

    def update(self, dt):
        mouse_x, mouse_y = pygame.mouse.get_pos()
        player_x, player_y = self.player.x + (Player.CHARACTER_WIDTH / 2), self.camera.calculate_pygame_pos(self.player.y)

        # This line is entirely generated by Copilot
        self.angle = math.atan2(mouse_y - player_y, mouse_x - player_x)

        # Process Jump
        if pygame.mouse.get_pressed()[0] and self.player.checkCanJump(self.platforms):

            self.player.jump(self.angle, self.platforms)
        
        # Update player
        self.player.update(dt, self.platforms)

        # Update Camera
        self.camera.move_to(self.player.y - (Player.CHARACTER_HEIGHT + globals.SCREEN_HEIGHT / 2))

        # Remove any platforms that are off screen from list
        heights_removed = []
        for i in self.platforms:
            if i.y < self.camera.y:
                if i.y not in heights_removed:
                    heights_removed.append(i.y)
                self.platforms.remove(i)
        
        # Randomly add platforms from platform_templates (list of list of templates), for each height removed. first height is 300 above highest height remaining, second height is 300 above that, etc.
        greatest_height = 0
        for i in self.platforms:
            if i.y > greatest_height:
                greatest_height = i.y
    
        for i in range(0, len(heights_removed)):
            plat_template = PlatformGenerator.getPlatforms()
            for j in plat_template:
                j.y = greatest_height + ((i+1) * 300)
                self.platforms.append(j)
        
        # Update platforms
        for i in self.platforms:
            i.update(dt)
        
        # Check if player is dead
        if self.player.y < self.camera.y or self.player.dead:
            globals.scene_manager.register_scene("death", DeathScene(round(self.camera.y)))
            globals.scene_manager.switch_scene("death")

    def render(self):
        # Clear screen
        globals.screen.fill((255, 255, 255))

        # Add background
        background = pygame.image.load("./shared/backgrounds/title.png")
        globals.screen.blit(background, (0, 0))

        # Render player
        globals.screen.blit(self.player.IMAGE, (self.player.x, self.camera.calculate_pygame_pos(self.player.y)))

        # Render platforms (platform image repeats every 80 pixels)
        for i in self.platforms:
            for j in range(0, i.width, 80):
                globals.screen.blit(i.getPlatformImage(), (i.x + j, self.camera.calculate_pygame_pos(i.y)))
        
         # Render arrow (THIS LINE IS FULLY GENERATED BY COPILOT)
        pygame.draw.line(globals.screen, (0, 0, 0), (self.player.x + (Player.CHARACTER_WIDTH / 2), self.camera.calculate_pygame_pos(self.player.y)), (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]), 5)
        
        # Render Score (camera y = score)
        score_text = self.score_font.render(f"Score: {round(self.camera.y)}", True, (0, 0, 0))
        globals.screen.blit(score_text, (0, 0))
    
    def switch_to(self):
        # Play music
        pygame.mixer.music.load("./shared/music/climb.wav")
        pygame.mixer.music.play(-1)

    def handle_events(self, events):
        pass
scenes/game.py
Alexandre2006/PlatformGame
# Title Scene
# Entirely written by humans with assistance from Copilot (75% human, 25% AI)
import pygame
import globals
from scenes.game import GameScene

from utils.scene import SceneBase

class TitleScene(SceneBase):
    def __init__(self):
        self.title_font = pygame.font.Font("./shared/fonts/Pixeboy.ttf", 160)
        self.button_font = pygame.font.Font("./shared/fonts/Pixeboy.ttf", 40)
        self.mouse_pressed = False
        self.mouse_prev_pressed = False

    def update(self, dt):
        self.dt = dt
        self.mouse_prev_pressed = self.mouse_pressed
        self.mouse_pressed = pygame.mouse.get_pressed()[0]
        pass

    def render(self):
        # Clear screen
        globals.screen.fill((255, 255, 255))

        # Add background
        background = pygame.image.load("./shared/backgrounds/title.png")
        globals.screen.blit(background, (0, 0))

        # Draw title
        title = self.title_font.render("ASCENT", True, (0, 0, 0))
        globals.screen.blit(title, ((globals.SCREEN_WIDTH - self.title_font.size("ASCENT")[0]) / 2, 76))

        # Draw subtitle
        subtitle = self.button_font.render("A Platformer by Landon M. & Alexandre H.", True, (0, 0, 0))
        globals.screen.blit(subtitle, ((globals.SCREEN_WIDTH - self.button_font.size("A Platformer by Landon M. & Alexandre H.")[0]) / 2, 170))

        # Cursor Position
        mouse_x, mouse_y = pygame.mouse.get_pos()

        # Add play button
        play_button_x = (globals.SCREEN_WIDTH - self.button_font.size("Start Game")[0]) / 2
        play_button_y = 350
        play_button_width = self.button_font.size("Start Game")[0] 
        play_button_height = self.button_font.size("Start Game")[1]

        play_box_x = play_button_x - 50
        play_box_y = play_button_y - (play_button_height / 2) - 20
        play_box_width = play_button_width + 100
        play_box_height = play_button_height + play_button_height + 40

        play_box_color = (128, 128, 128)

        if mouse_x > play_box_x and mouse_x < play_box_x + play_box_width and mouse_y > play_box_y and mouse_y < play_box_y + play_box_height:
            play_box_color = (196, 196, 196)
            if self.mouse_prev_pressed and not self.mouse_pressed:
                globals.scene_manager.register_scene("game", GameScene())
                globals.scene_manager.switch_scene("game")
                
        pygame.draw.rect(globals.screen, play_box_color, (play_box_x, play_box_y, play_box_width, play_box_height))
        play_button = self.button_font.render("Start Game", True, (0, 0, 0))
        globals.screen.blit(play_button, (play_button_x, play_button_y))

        # Add exit button
        exit_button_x = (globals.SCREEN_WIDTH - self.button_font.size("Quit Game")[0]) / 2
        exit_button_y = 550
        exit_button_width = self.button_font.size("Quit Game")[0] 
        exit_button_height = self.button_font.size("Quit Game")[1]

        exit_box_x = exit_button_x - 50
        exit_box_y = exit_button_y - (play_button_height / 2) - 20
        exit_box_width = exit_button_width + 100
        exit_box_height = exit_button_height + exit_button_height + 40 

        exit_box_color = (128, 128, 128)
        
        if mouse_x > exit_box_x and mouse_x < exit_box_x + exit_box_width and mouse_y > exit_box_y and mouse_y < exit_box_y + exit_box_height:
            exit_box_color = (196, 196, 196)
            if self.mouse_prev_pressed and not self.mouse_pressed:
                pygame.quit()
                exit()
        
        pygame.draw.rect(globals.screen, exit_box_color, (exit_box_x, exit_box_y, exit_box_width, exit_box_height))
        exit_button = self.button_font.render("Quit Game", True, (0, 0, 0))
        globals.screen.blit(exit_button, (exit_button_x, exit_button_y))
    
    def switch_to(self):
        # Play music
        pygame.mixer.music.load("./shared/music/title.wav")
        pygame.mixer.music.play(1)

    def handle_events(self, events):        
        pass # Title scene does not handle any events
scenes/title.py
Alexandre2006/PlatformGame
# Camera Class
# Entirely written by humans

class Camera:
    def __init__(self):
        self.y = 0
    
    def move_to(self, y):
        if self.y < y:
            self.y = y
    
    def calculate_pygame_pos(self, y):
        return 800 - (y - self.y)
utils/camera.py
Alexandre2006/PlatformGame
# Platform Class
# Entirely written by humans with assistance from Copilot (75% human, 25% AI)

import pygame

class Platform:
    # Platform Types
    TYPE_GRASS = 0
    TYPE_ICE = 1
    TYPE_BOOST = 2
    TYPE_SPIKE = 3

    # Platform Images
    IMAGE_GRASS = pygame.image.load("./shared/tiles/grass.png")
    IMAGE_ICE = pygame.image.load("./shared/tiles/ice.png")
    IMAGE_BOOST = pygame.image.load("./shared/tiles/boost.png")
    IMAGE_SPIKE = pygame.image.load("./shared/tiles/spike.png")

    # Platform Widths
    WIDTH_THIN = 1
    WIDTH_NORMAL = 2
    WIDTH_THICK = 3
    WIDTH_FLOOR = 10

    # Platform Info
    width = 80
    x = 0
    y = 0
    x_velocity = 0
    type = TYPE_GRASS

    # Platform Stick Info
    move_player_by = 0

    # Constructor (x, y, type, width_type, velocity)
    def __init__(self, x_pos, y_pos, platform_type, platform_width_type, platform_x_velocity):
        self.x = x_pos
        self.y = y_pos
        self.type = platform_type
        self.width = platform_width_type * 80
        self.x_velocity = platform_x_velocity

    def update(self, dt):
        self.move_player_by = self.x_velocity * dt
        self.x += self.x_velocity * dt

        # Check if platform is off screen
        if self.x < 0:
            self.x = 0
            self.x_velocity *= -1
        
        if (self.x + self.width) > 800:
            self.x = 800 - self.width
            self.x_velocity *= -1
    
    def getPlatformImage(self):
        if self.type == Platform.TYPE_GRASS:
            return Platform.IMAGE_GRASS
        elif self.type == Platform.TYPE_ICE:
            return Platform.IMAGE_ICE
        elif self.type == Platform.TYPE_BOOST:
            return Platform.IMAGE_BOOST
        elif self.type == Platform.TYPE_SPIKE:
            return Platform.IMAGE_SPIKE
utils/platform.py
Alexandre2006/PlatformGame
# Platform Generator Class
# Entirely written by humans with assistance from Copilot (75% human, 25% AI)

import random
from utils.platform import Platform


class PlatformGenerator():
    def randWidth():
        widths = [Platform.WIDTH_THIN, Platform.WIDTH_NORMAL, Platform.WIDTH_THICK]
        return random.choice(widths)
    
    def randFloorType():
        types = [Platform.TYPE_GRASS, Platform.TYPE_ICE]
        return random.choice(types)

    def randEffectType():
        random_num = random.random();
        if random_num > 0.90:
            return Platform.TYPE_BOOST
        if random_num > 0.80:
            return Platform.TYPE_SPIKE
        else:
            return None

    def gen3Plat():
        has_effect = False

        plat1_width = PlatformGenerator.randWidth()
        plat1_type = PlatformGenerator.randFloorType()
        plat1_effect = PlatformGenerator.randEffectType()
        if plat1_effect != None:
            plat1_type = plat1_effect
            has_effect = True
        if plat1_width == Platform.WIDTH_THICK:
            plat1_width = Platform.WIDTH_NORMAL
        
        
        plat1 = Platform(0, 0, plat1_type, plat1_width, 0)

        plat2_width = PlatformGenerator.randWidth()
        plat2_type = 1
        plat2_effect = None
        if not has_effect:
            plat2_effect = PlatformGenerator.randEffectType()
        if plat2_effect != None:
            plat2_type = plat2_effect
            has_effect = True
        
        plat2 = Platform(400 - ((plat2_width * 80) / 2), 0, plat2_type, plat2_width, 0)
        
        plat3_width = PlatformGenerator.randWidth()
        plat3_type = PlatformGenerator.randFloorType()
        plat3_effect = None
        if not has_effect:
            plat3_effect = PlatformGenerator.randEffectType()
        if plat3_effect != None:
            plat3_type = plat3_effect
        if plat3_width == Platform.WIDTH_THICK:
            plat3_width = Platform.WIDTH_NORMAL
        
        plat3 = Platform(800 - (plat3_width * 80), 0, plat3_type, plat3_width, 0)
        
        return [plat1, plat2, plat3]

    def gen2Plat():
        has_effect = False

        plat1_width = PlatformGenerator.randWidth()
        plat1_type = PlatformGenerator.randFloorType()
        plat1_effect = PlatformGenerator.randEffectType()
        if plat1_effect != None:
            has_effect = True
            plat1_type = plat1_effect
        
        plat1 = Platform(200 - ((plat1_width * 80) / 2), 0, plat1_type, plat1_width, 0)

        plat2_width = PlatformGenerator.randWidth()
        plat2_type = PlatformGenerator.randFloorType()
        plat2_effect = None
        if not has_effect:
            plat2_effect = PlatformGenerator.randEffectType()
        if plat2_effect != None:
            plat2_type = plat2_effect
        
        plat2 = Platform(600 - ((plat2_width * 80) / 2), 0, plat2_type, plat2_width, 0)
        
        return [plat1, plat2]

    def gen1Plat():
        plat_width = PlatformGenerator.randWidth()
        plat_type = PlatformGenerator.randFloorType()

        plat1 = Platform(0, 0, plat_type, plat_width, 0)
        plat2 = Platform(400 - ((plat_width * 80) / 2), 0, plat_type, plat_width, 0)
        plat3 = Platform(800 - (plat_width * 80), 0, plat_type, plat_width, 0)

        platforms = [plat1, plat2, plat3]
        return [random.choice(platforms)]

    def genMovingPlat():
        plat_width = PlatformGenerator.randWidth()
        plat_type = PlatformGenerator.randFloorType()

        speed = random.randint(100, 300)

        plat1 = Platform(0, 0, plat_type, plat_width, speed)
        plat2 = Platform(400 - ((plat_width * 80) / 2), 0, plat_type, plat_width, speed)
        plat3 = Platform(800 - (plat_width * 80), 0, plat_type, plat_width, -speed)

        platforms = [plat1, plat2, plat3]
        return [random.choice(platforms)]
    
    def getPlatforms():
        generators = [PlatformGenerator.gen1Plat, PlatformGenerator.gen2Plat, PlatformGenerator.gen3Plat, PlatformGenerator.genMovingPlat]
        return random.choice(generators)()

utils/platform_gen.py
Alexandre2006/PlatformGame
# Player Class
# Entirely written by humans with assistance from Copilot (75% human, 25% AI)

import math
import pygame
import globals
from utils.platform import Platform

class Player:
    CHARACTER_WIDTH = 80
    CHARACTER_HEIGHT = 160
    IMAGE = pygame.transform.scale(pygame.image.load("./shared/player/player.png"), (80, 160))

    def __init__(self):
        self.x = globals.SCREEN_WIDTH / 2
        self.y = 400
        self.x_velocity = 0
        self.y_velocity = 0
        self.dead = False
    
    def checkWallCollision(self):
        # Check for collision with right side of the screen
        if (self.x + Player.CHARACTER_WIDTH) > globals.SCREEN_WIDTH:
            self.x = globals.SCREEN_WIDTH - Player.CHARACTER_WIDTH
        
        # Check for collision with left side of the screen
        if self.x < 0:
            self.x = 0
    
    def checkPlatformPerfectCollision(self, platforms):
        # Perfect collision triggers effects, and when y of player is same as y of platform
        for i in platforms:
            if self.y - Player.CHARACTER_HEIGHT == i.y and self.x <= i.x + i.width and self.x + Player.CHARACTER_WIDTH >= i.x:
                return i

    def checkPlatformCollision(self, prev_x, prev_y, platforms):
        # Check for collision with platforms (going down) #WORKING ISH
        for i in platforms:
            if prev_y - Player.CHARACTER_HEIGHT >= i.y and self.y - Player.CHARACTER_HEIGHT <= i.y and self.x <= i.x + i.width and self.x + Player.CHARACTER_WIDTH >= i.x:
                self.y = i.y + Player.CHARACTER_HEIGHT
                self.y_velocity = 0
                return True
        
        # Check for collision with platforms (going up) # WORKING
        for i in platforms:
            if prev_y < i.y - 80 and self.y >= i.y - 80 and self.x <= i.x + i.width and self.x + Player.CHARACTER_WIDTH >= i.x:
                self.y = i.y - 80
                self.y_velocity = 0
                return True
        
        # Check for collision with platforms (going right)
        for i in platforms:
            if prev_x + Player.CHARACTER_WIDTH < i.x and self.x + Player.CHARACTER_WIDTH >= i.x and prev_y <= i.y + 160 and self.y >= i.y - 80:
                self.x = i.x - Player.CHARACTER_WIDTH
                self.x_velocity = 0
                return True

        # Check for collision with platforms (going left)
        for i in platforms:
            if prev_x + Player.CHARACTER_WIDTH >= i.x + i.width and self.x < i.x + i.width and prev_y <= i.y + 160 and self.y >= i.y - 80:
                self.x = i.x + i.width
                self.x_velocity = 0
                return True
    
    def checkCanJump(self, platforms):
        if self.checkPlatformPerfectCollision(platforms) != None:
            return True
    
    def jump(self, angle, platforms):
        mult = 1
        if (self.checkPlatformPerfectCollision(platforms)) != None and self.checkPlatformPerfectCollision(platforms).type == Platform.TYPE_BOOST:
            mult = 2
        angle = abs(angle)
        self.y_velocity = (1250 * mult * math.sin(angle))
        self.x_velocity = 500 * mult * math.cos(angle)
        self.y += 1

    def update(self, dt, platforms):
        prev_x = self.x
        prev_y = self.y

        # Check for collisions with platforms
        perfect_collision = self.checkPlatformPerfectCollision(platforms)
        if perfect_collision != None:
            if perfect_collision.type == Platform.TYPE_SPIKE:
                self.dead = True
            elif perfect_collision.type == Platform.TYPE_ICE:
                self.x_velocity *= 0.95
                self.y_velocity = 0
            else:
                self.x_velocity *= 0.8
                self.y_velocity = 0

            self.x += perfect_collision.move_player_by

        # Update position based on velocity
        self.x += self.x_velocity * dt
        self.y += self.y_velocity * dt

        # Check for other collisions
        self.checkPlatformCollision(prev_x, prev_y, platforms)

        # Check for all types of collisions
        self.checkWallCollision()

        # Update gravity
        self.y_velocity -= 1000 * dt

utils/player.py
Alexandre2006/PlatformGame
# Base Scene class
# Entirely written by ChatGPT, modified by humans
class SceneBase:
    def __init__(self):
        pass

    def update(self, dt):
        pass

    def render(self):
        pass

    def switch_to(self):
        pass

    def handle_events(self, events):
        pass
utils/scene.py
Alexandre2006/PlatformGame
# Scene Manager
# Written by Copilot (except unregister_scene)
import pygame

class SceneManager:
    def __init__(self):
        self.scenes = {}
        self.current_scene = None

        # Setup delta time
        self.delta_time = 0
        self.current_time = pygame.time.get_ticks()
        self.last_time = self.current_time

    def register_scene(self, scene_name, scene_instance):
        self.scenes[scene_name] = scene_instance
    
    def unregister_scene(self, scene_name):
        if scene_name in self.scenes:
            del self.scenes[scene_name]
        else:
            print(f"Scene '{scene_name}' does not exist.")

    def switch_scene(self, scene_name):
        if scene_name in self.scenes:
            self.current_scene = self.scenes[scene_name]
            self.current_scene.switch_to()
        else:
            print(f"Scene '{scene_name}' does not exist.")

    def update_current_scene(self):
        if self.current_scene:
            # Calculate delta time
            self.current_time = pygame.time.get_ticks()
            self.delta_time = (self.current_time - self.last_time) / 1000.0
            self.last_time = self.current_time

            self.current_scene.update(self.delta_time)

    def render_current_scene(self):
        if self.current_scene:
            self.current_scene.render()

    def handle_events(self, events):
        if self.current_scene:
            self.current_scene.handle_events(events)
utils/scene_manager.py
Alexandre2006/PlatformGame