5/15

i used ai and some of the code from the platform game we are working on and some from tetris

import pygame
import random
import math

pygame.init()

SCREEN_WIDTH = 1400
SCREEN_HEIGHT = 1000
FPS = 60

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (34, 177, 76)
BLUE = (52, 152, 219)
RED = (231, 76, 60)
YELLOW = (241, 196, 15)
ORANGE = (230, 126, 34)
PURPLE = (155, 89, 182)
CYAN = (52, 211, 153)
PINK = (236, 112, 186)
LIME = (46, 204, 113)

GRAVITY = 0.7
JUMP_POWER = -18
PLAYER_SPEED = 7
MAX_FALL_SPEED = 20

STATE_PLAYING = "playing"
STATE_GAME_OVER = "game_over"
STATE_LEVEL_COMPLETE = "level_complete"
STATE_MENU = "menu"
STATE_PAUSED = "paused"
STATE_PLAYER_SELECT = "player_select"

POWERUP_SHIELD = "shield"
POWERUP_SPEED = "speed"
POWERUP_SLOW_TIME = "slow_time"
POWERUP_MAGNET = "magnet"
POWERUP_SMALL = "small"
POWERUP_BIG = "big"
POWERUP_INVINCIBLE = "invincible"

class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height, color=GREEN, platform_type="normal", moving=False, move_range=0, crumble_time=0):
        super().__init__()
        self.x = x
        self.y = y
        self.start_x = x
        self.start_y = y
        self.width = width
        self.height = height
        self.color = color
        self.platform_type = platform_type
        self.image = pygame.Surface((width, height))
        self.image.fill(color)
        self.rect = self.image.get_rect(topleft=(x, y))
        
        self.moving = moving
        self.move_range = move_range
        self.speed = 3
        self.direction = 1
        
        self.crumble_time = crumble_time
        self.crumble_counter = 0
        self.is_crumbling = False
        
        self.draw_platform()
        
    def draw_platform(self):
        self.image.fill(self.color)
        pygame.draw.rect(self.image, (255, 255, 255), self.image.get_rect(), 2)
        
        if self.platform_type == "bouncy":
            pygame.draw.circle(self.image, YELLOW, (self.width // 2, self.height // 2), 4)
        elif self.platform_type == "crumbling":
            for i in range(3):
                pygame.draw.line(self.image, RED, (i * self.width // 3, 0), (i * self.width // 3, self.height), 1)
        elif self.platform_type == "ice":
            for i in range(self.width // 10):
                pygame.draw.line(self.image, CYAN, (i * 10, 0), (i * 10 + 5, self.height), 1)
        elif self.platform_type == "spike":
            for i in range(0, self.width, 15):
                pygame.draw.polygon(self.image, RED, [(i, self.height), (i + 7, 0), (i + 14, self.height)])
        
    def update(self):
        if self.moving:
            self.x += self.speed * self.direction
            if abs(self.x - self.start_x) >= self.move_range:
                self.direction *= -1
            self.rect.x = self.x
            
        if self.platform_type == "crumbling" and self.is_crumbling:
            self.crumble_counter += 1
            if self.crumble_counter > self.crumble_time:
                self.kill()
            
    def trigger_crumble(self):
        if self.platform_type == "crumbling":
            self.is_crumbling = True
            
    def draw(self, surface):
        surface.blit(self.image, self.rect)

class Particle(pygame.sprite.Sprite):
    def __init__(self, x, y, vel_x, vel_y, color, lifetime=30):
        super().__init__()
        self.x = x
        self.y = y
        self.vel_x = vel_x
        self.vel_y = vel_y
        self.color = color
        self.lifetime = lifetime
        self.age = 0
        self.image = pygame.Surface((5, 5))
        self.image.fill(color)
        self.rect = self.image.get_rect(center=(x, y))
        
    def update(self):
        self.age += 1
        self.x += self.vel_x
        self.y += self.vel_y
        self.vel_y += 0.5
        self.rect.center = (self.x, self.y)
        
        if self.age >= self.lifetime:
            self.kill()

class PowerUp(pygame.sprite.Sprite):
    def __init__(self, x, y, powerup_type=POWERUP_SHIELD):
        super().__init__()
        self.x = x
        self.y = y
        self.powerup_type = powerup_type
        self.size = 20
        self.image = pygame.Surface((self.size, self.size))
        self.rect = self.image.get_rect(center=(x, y))
        self.rotation_angle = 0
        self.bounce_offset = 0
        
        self.update_image()
        
    def update_image(self):
        self.image.fill(BLACK)
        self.image.set_colorkey(BLACK)
        
        if self.powerup_type == POWERUP_SHIELD:
            pygame.draw.circle(self.image, PINK, (self.size // 2, self.size // 2), self.size // 2)
            pygame.draw.circle(self.image, (255, 200, 200), (self.size // 2, self.size // 2), self.size // 2 - 3)
        elif self.powerup_type == POWERUP_SPEED:
            pygame.draw.rect(self.image, LIME, (2, 2, self.size - 4, self.size - 4))
            pygame.draw.polygon(self.image, WHITE, [(15, 5), (15, 15), (18, 10)])
        elif self.powerup_type == POWERUP_SLOW_TIME:
            pygame.draw.circle(self.image, PURPLE, (self.size // 2, self.size // 2), self.size // 2)
            pygame.draw.circle(self.image, WHITE, (self.size // 2, self.size // 2), 3)
        elif self.powerup_type == POWERUP_MAGNET:
            pygame.draw.polygon(self.image, RED, [(5, 2), (15, 2), (15, 12), (5, 12)])
            pygame.draw.polygon(self.image, BLUE, [(5, 12), (15, 12), (15, 18), (5, 18)])
        elif self.powerup_type == POWERUP_SMALL:
            pygame.draw.circle(self.image, CYAN, (self.size // 2, self.size // 2), 3)
        elif self.powerup_type == POWERUP_BIG:
            pygame.draw.circle(self.image, ORANGE, (self.size // 2, self.size // 2), self.size // 2)
        elif self.powerup_type == POWERUP_INVINCIBLE:
            pygame.draw.polygon(self.image, YELLOW, [(self.size // 2, 2), (self.size - 2, self.size // 2), (self.size // 2, self.size - 2), (2, self.size // 2)])
    
    def update(self):
        self.rotation_angle += 5
        self.bounce_offset = abs(math.sin(pygame.time.get_ticks() / 200) * 5)
        self.rect.y = self.y - self.bounce_offset
        self.update_image()

class Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y, width=40, height=40, color=RED, enemy_type="walker"):
        super().__init__()
        self.x = x
        self.y = y
        self.start_x = x
        self.width = width
        self.height = height
        self.color = color
        self.enemy_type = enemy_type
        self.image = pygame.Surface((width, height))
        self.image.fill(color)
        self.rect = self.image.get_rect(topleft=(x, y))
        
        self.speed = 3
        self.direction = 1
        self.move_range = 150
        self.vel_y = 0
        
        self.float_offset = 0
        
        if enemy_type == "walker":
            pygame.draw.polygon(self.image, (255, 100, 100), [(width//2, 0), (width, height//2), (width//2, height), (0, height//2)])
        elif enemy_type == "flyer":
            pygame.draw.circle(self.image, PINK, (width//2, height//2), width//2)
            pygame.draw.line(self.image, (255, 100, 100), (5, height//2), (width-5, height//2), 2)
        elif enemy_type == "jumper":
            pygame.draw.rect(self.image, (255, 150, 100), (0, 0, width, height))
            pygame.draw.circle(self.image, WHITE, (10, 10), 3)
            pygame.draw.circle(self.image, WHITE, (width-10, 10), 3)
        
    def update(self, platforms):
        if self.enemy_type == "walker" or self.enemy_type == "jumper":
            self.x += self.speed * self.direction
            if abs(self.x - self.start_x) >= self.move_range:
                self.direction *= -1
            self.rect.x = self.x
            
            self.vel_y += GRAVITY
            if self.vel_y > MAX_FALL_SPEED:
                self.vel_y = MAX_FALL_SPEED
            self.rect.y += self.vel_y
            
            for platform in platforms:
                if (self.vel_y > 0 and 
                    self.rect.bottom >= platform.rect.top and 
                    self.rect.bottom <= platform.rect.bottom and
                    self.rect.right > platform.rect.left and
                    self.rect.left < platform.rect.right):
                    
                    self.rect.bottom = platform.rect.top
                    self.vel_y = 0
                    
                    if self.enemy_type == "jumper" and random.random() < 0.1:
                        self.vel_y = -12
                        
        elif self.enemy_type == "flyer":
            self.x += self.speed * self.direction
            if abs(self.x - self.start_x) >= self.move_range:
                self.direction *= -1
            self.rect.x = self.x
            
            self.float_offset += 0.05
            self.rect.y = self.start_x + math.sin(self.float_offset) * 30

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y, player_num=1):
        super().__init__()
        self.width = 40
        self.height = 40
        self.player_num = player_num
        self.image = pygame.Surface((self.width, self.height))
        
        if player_num == 1:
            self.color = BLUE
        else:
            self.color = ORANGE
            
        self.image.fill(self.color)
        self.rect = self.image.get_rect(topleft=(x, y))
        
        pygame.draw.circle(self.image, WHITE, (10, 10), 3)
        pygame.draw.circle(self.image, WHITE, (30, 10), 3)
        pygame.draw.circle(self.image, BLACK, (10, 10), 1)
        pygame.draw.circle(self.image, BLACK, (30, 10), 1)
        
        self.vel_y = 0
        self.vel_x = 0
        self.on_ground = False
        self.double_jump_available = True
        
        self.health = 3
        self.max_health = 3
        self.invincible_time = 0
        self.score_multiplier = 1
        self.current_size = 1.0
        
        self.shield = False
        self.shield_time = 0
        self.speed_boost = False
        self.speed_boost_time = 0
        self.slow_time = False
        self.slow_time_time = 0
        self.magnet = False
        self.magnet_time = 0
        self.magnet_range = 150
        self.invincible = False
        self.invincible_time_powerup = 0
        
    def handle_input(self, keys, player_num):
        speed = PLAYER_SPEED
        if self.speed_boost:
            speed = PLAYER_SPEED * 1.5
            
        self.vel_x = 0
        
        if player_num == 1:
            if keys[pygame.K_a]:
                self.vel_x = -speed
            if keys[pygame.K_d]:
                self.vel_x = speed
            if keys[pygame.K_w]:
                if self.on_ground:
                    self.vel_y = JUMP_POWER
                    self.on_ground = False
                    self.double_jump_available = True
                elif self.double_jump_available:
                    self.vel_y = JUMP_POWER
                    self.double_jump_available = False
        else:
            if keys[pygame.K_LEFT]:
                self.vel_x = -speed
            if keys[pygame.K_RIGHT]:
                self.vel_x = speed
            if keys[pygame.K_UP]:
                if self.on_ground:
                    self.vel_y = JUMP_POWER
                    self.on_ground = False
                    self.double_jump_available = True
                elif self.double_jump_available:
                    self.vel_y = JUMP_POWER
                    self.double_jump_available = False
                
    def update(self, platforms, enemies, particles, powerups):
        gravity = GRAVITY
        if self.slow_time:
            gravity *= 0.5
            
        self.vel_y += gravity
        if self.vel_y > MAX_FALL_SPEED:
            self.vel_y = MAX_FALL_SPEED
        
        self.rect.x += self.vel_x
        
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.right > SCREEN_WIDTH:
            self.rect.right = SCREEN_WIDTH
            
        self.rect.y += self.vel_y
        self.on_ground = False
        
        for platform in platforms:
            if (self.vel_y > 0 and 
                self.rect.bottom >= platform.rect.top and 
                self.rect.bottom <= platform.rect.bottom + 5 and
                self.rect.right > platform.rect.left and
                self.rect.left < platform.rect.right):
                
                self.rect.bottom = platform.rect.top
                self.vel_y = 0
                self.on_ground = True
                self.double_jump_available = True
                
                if platform.platform_type == "ice":
                    self.vel_x *= 1.1
                
                elif platform.platform_type == "spike":
                    if not self.shield and not self.invincible:
                        self.health -= 1
                        self.invincible_time = 60
                    else:
                        self.shield = False
                        self.shield_time = 0
                
                elif platform.platform_type == "bouncy":
                    self.vel_y = JUMP_POWER * 1.5
                    self.on_ground = False
                    
                elif platform.platform_type == "crumbling":
                    platform.trigger_crumble()
                    
                for _ in range(5):
                    angle = random.uniform(0, 2 * math.pi)
                    speed = random.uniform(2, 6)
                    vx = math.cos(angle) * speed
                    vy = math.sin(angle) * speed - 2
                    particles.add(Particle(self.rect.centerx, self.rect.centery, vx, vy, CYAN))
        
        for enemy in enemies:
            if self.rect.colliderect(enemy.rect):
                if self.vel_y > 0 and self.rect.bottom <= enemy.rect.centery:
                    self.vel_y = JUMP_POWER
                    self.on_ground = False
                    enemy.kill()
                    self.score_multiplier += 0.1
                else:
                    if not self.shield and not self.invincible:
                        self.health -= 1
                        self.invincible_time = 60
                    else:
                        self.shield = False
                        self.shield_time = 0
        
        for powerup in powerups:
            if self.rect.colliderect(powerup.rect):
                self.activate_powerup(powerup.powerup_type)
                powerup.kill()
        
        if self.magnet:
            for powerup in powerups:
                dx = self.rect.centerx - powerup.rect.centerx
                dy = self.rect.centery - powerup.rect.centery
                distance = math.sqrt(dx**2 + dy**2)
                if distance < self.magnet_range and distance > 0:
                    speed = 5
                    powerup.x += (dx / distance) * speed
                    powerup.y += (dy / distance) * speed
                    powerup.rect.center = (int(powerup.x), int(powerup.y))
        
        if self.shield:
            self.shield_time -= 1
            if self.shield_time <= 0:
                self.shield = False
                
        if self.speed_boost:
            self.speed_boost_time -= 1
            if self.speed_boost_time <= 0:
                self.speed_boost = False
                
        if self.slow_time:
            self.slow_time_time -= 1
            if self.slow_time_time <= 0:
                self.slow_time = False
                
        if self.magnet:
            self.magnet_time -= 1
            if self.magnet_time <= 0:
                self.magnet = False
        
        if self.invincible:
            self.invincible_time_powerup -= 1
            if self.invincible_time_powerup <= 0:
                self.invincible = False
        
        if self.invincible_time > 0:
            self.invincible_time -= 1
            
    def activate_powerup(self, powerup_type):
        if powerup_type == POWERUP_SHIELD:
            self.shield = True
            self.shield_time = 300
        elif powerup_type == POWERUP_SPEED:
            self.speed_boost = True
            self.speed_boost_time = 300
        elif powerup_type == POWERUP_SLOW_TIME:
            self.slow_time = True
            self.slow_time_time = 300
        elif powerup_type == POWERUP_MAGNET:
            self.magnet = True
            self.magnet_time = 300
        elif powerup_type == POWERUP_SMALL:
            self.current_size = 0.5
            self.width = 20
            self.height = 20
        elif powerup_type == POWERUP_BIG:
            self.current_size = 1.5
            self.width = 60
            self.height = 60
        elif powerup_type == POWERUP_INVINCIBLE:
            self.invincible = True
            self.invincible_time_powerup = 300
            
    def draw(self, surface):
        if self.invincible_time > 0 and self.invincible_time % 10 < 5:
            return
        
        if self.shield:
            pygame.draw.circle(surface, PINK, self.rect.center, 50, 2)
        
        if self.invincible:
            pygame.draw.circle(surface, YELLOW, self.rect.center, self.width // 2 + 10, 3)
        
        surface.blit(self.image, self.rect)

class Level:
    def __init__(self, level_num=1):
        self.level_num = level_num
        self.platforms = pygame.sprite.Group()
        self.enemies = pygame.sprite.Group()
        self.powerups = pygame.sprite.Group()
        self.generate_level()
        
    def generate_level(self):
        self.platforms.add(Platform(SCREEN_WIDTH // 2 - 75, SCREEN_HEIGHT - 80, 150, 30, GREEN))
        
        difficulty = 1 + (self.level_num - 1) * 0.3
        
        num_platforms = int(10 + self.level_num * 2)
        for i in range(num_platforms):
            x = random.randint(50, SCREEN_WIDTH - 100)
            y = SCREEN_HEIGHT - 200 - i * 80
            width = int(random.randint(50, 120) / difficulty)
            
            platform_type = "normal"
            moving = False
            move_range = 0
            color = random.choice([GREEN, BLUE, YELLOW])
            
            rand = random.random()
            
            if rand < 0.25 * difficulty:
                moving = True
                move_range = random.randint(60, 150)
                color = ORANGE
                
            elif rand < 0.45 * difficulty:
                platform_type = "bouncy"
                color = YELLOW
                
            elif rand < 0.6 * difficulty:
                platform_type = "crumbling"
                color = RED
                
            elif rand < 0.75 * difficulty:
                platform_type = "ice"
                color = CYAN
                
            elif rand < 0.9 * difficulty and self.level_num > 3:
                platform_type = "spike"
                color = (200, 0, 0)
                
            self.platforms.add(Platform(x, y, width, 20, color, platform_type, moving, move_range, 60))
            
            if random.random() < 0.2 * difficulty and i > 2:
                ex = random.randint(50, SCREEN_WIDTH - 100)
                ey = y - 100
                enemy_type = random.choice(["walker", "flyer", "jumper"])
                self.enemies.add(Enemy(ex, ey, enemy_type=enemy_type))
            
            if random.random() < 0.1 * (self.level_num / 5):
                px = random.randint(50, SCREEN_WIDTH - 50)
                py = y - 50
                ptype = random.choice([POWERUP_SHIELD, POWERUP_SPEED, POWERUP_SLOW_TIME, POWERUP_MAGNET, POWERUP_SMALL, POWERUP_BIG, POWERUP_INVINCIBLE])
                self.powerups.add(PowerUp(px, py, ptype))
    
    def generate_level_two_player(self):
        self.platforms.add(Platform(250 - 75, SCREEN_HEIGHT - 80, 150, 30, BLUE))
        self.platforms.add(Platform(SCREEN_WIDTH - 250 - 75, SCREEN_HEIGHT - 80, 150, 30, ORANGE))
        
        difficulty = 1 + (self.level_num - 1) * 0.3
        
        num_platforms = int(10 + self.level_num * 2)
        for i in range(num_platforms):
            x = random.randint(50, SCREEN_WIDTH - 100)
            y = SCREEN_HEIGHT - 200 - i * 80
            width = int(random.randint(50, 120) / difficulty)
            
            platform_type = "normal"
            moving = False
            move_range = 0
            color = random.choice([GREEN, BLUE, YELLOW])
            
            rand = random.random()
            
            if rand < 0.25 * difficulty:
                moving = True
                move_range = random.randint(60, 150)
                color = ORANGE
                
            elif rand < 0.45 * difficulty:
                platform_type = "bouncy"
                color = YELLOW
                
            elif rand < 0.6 * difficulty:
                platform_type = "crumbling"
                color = RED
                
            elif rand < 0.75 * difficulty:
                platform_type = "ice"
                color = CYAN
                
            elif rand < 0.9 * difficulty and self.level_num > 3:
                platform_type = "spike"
                color = (200, 0, 0)
                
            self.platforms.add(Platform(x, y, width, 20, color, platform_type, moving, move_range, 60))
            
            if random.random() < 0.2 * difficulty and i > 2:
                ex = random.randint(50, SCREEN_WIDTH - 100)
                ey = y - 100
                enemy_type = random.choice(["walker", "flyer", "jumper"])
                self.enemies.add(Enemy(ex, ey, enemy_type=enemy_type))
            
            if random.random() < 0.1 * (self.level_num / 5):
                px = random.randint(50, SCREEN_WIDTH - 50)
                py = y - 50
                ptype = random.choice([POWERUP_SHIELD, POWERUP_SPEED, POWERUP_SLOW_TIME, POWERUP_MAGNET, POWERUP_SMALL, POWERUP_BIG, POWERUP_INVINCIBLE])
                self.powerups.add(PowerUp(px, py, ptype))
    
    def update(self):
        for platform in self.platforms:
            platform.update()
        for enemy in self.enemies:
            enemy.update(self.platforms)
        for powerup in self.powerups:
            powerup.update()

class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("PLATFORM MASTER - ADVANCED EDITION")
        self.clock = pygame.time.Clock()
        self.running = True
        self.font_large = pygame.font.Font(None, 48)
        self.font_medium = pygame.font.Font(None, 36)
        self.font_small = pygame.font.Font(None, 24)
        
        self.level_num = 1
        self.level = None
        self.player1 = None
        self.player2 = None
        self.num_players = 1
        self.particles = pygame.sprite.Group()
        self.score1 = 0
        self.score2 = 0
        self.game_state = STATE_MENU
        self.highest_y1 = SCREEN_HEIGHT
        self.highest_y2 = SCREEN_HEIGHT
        self.time_elapsed = 0
        self.best_score1 = 0
        self.best_score2 = 0
        
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    if self.game_state == STATE_PLAYING:
                        self.game_state = STATE_PAUSED
                    elif self.game_state == STATE_PAUSED:
                        self.game_state = STATE_PLAYING
                    elif self.game_state in [STATE_MENU, STATE_GAME_OVER, STATE_PLAYER_SELECT]:
                        self.running = False
                        
                if event.key == pygame.K_r:
                    if self.game_state in [STATE_GAME_OVER, STATE_PLAYER_SELECT]:
                        self.game_state = STATE_PLAYER_SELECT
                    elif self.game_state == STATE_LEVEL_COMPLETE:
                        self.next_level()
                        
                if event.key == pygame.K_1:
                    if self.game_state == STATE_PLAYER_SELECT:
                        self.num_players = 1
                        self.reset_game()
                        
                if event.key == pygame.K_2:
                    if self.game_state == STATE_PLAYER_SELECT:
                        self.num_players = 2
                        self.reset_game()
                    
                if event.key == pygame.K_SPACE:
                    if self.game_state == STATE_MENU:
                        self.game_state = STATE_PLAYER_SELECT
                    
    def handle_input(self):
        keys = pygame.key.get_pressed()
        if self.player1:
            self.player1.handle_input(keys, 1)
        if self.player2:
            self.player2.handle_input(keys, 2)
        
    def update(self):
        if self.game_state == STATE_PLAYING:
            self.time_elapsed += 1
            self.level.update()
            
            if self.player1:
                self.player1.update(self.level.platforms, self.level.enemies, self.particles, self.level.powerups)
                
                current_height = SCREEN_HEIGHT - self.player1.rect.y
                if current_height > self.highest_y1:
                    self.highest_y1 = current_height
                    base_score = int(self.highest_y1)
                    self.score1 = int(base_score * self.player1.score_multiplier)
                    if self.score1 > self.best_score1:
                        self.best_score1 = self.score1
                
                if self.player1.rect.y > SCREEN_HEIGHT or self.player1.health <= 0:
                    if self.num_players == 1:
                        self.game_state = STATE_GAME_OVER
                    else:
                        self.player1 = None
            
            if self.player2:
                self.player2.update(self.level.platforms, self.level.enemies, self.particles, self.level.powerups)
                
                current_height = SCREEN_HEIGHT - self.player2.rect.y
                if current_height > self.highest_y2:
                    self.highest_y2 = current_height
                    base_score = int(self.highest_y2)
                    self.score2 = int(base_score * self.player2.score_multiplier)
                    if self.score2 > self.best_score2:
                        self.best_score2 = self.score2
                
                if self.player2.rect.y > SCREEN_HEIGHT or self.player2.health <= 0:
                    self.player2 = None
                
                if self.player1 is None and self.player2 is None:
                    self.game_state = STATE_GAME_OVER
            
            self.particles.update()
            
            if len(self.level.platforms) > 0:
                if self.num_players == 1 and self.player1 and self.player1.rect.y < 100:
                    self.game_state = STATE_LEVEL_COMPLETE
                elif self.num_players == 2 and ((self.player1 and self.player1.rect.y < 100) or (self.player2 and self.player2.rect.y < 100)):
                    self.game_state = STATE_LEVEL_COMPLETE
                
    def draw(self):
        self.screen.fill(BLACK)
        
        for x in range(0, SCREEN_WIDTH, 50):
            pygame.draw.line(self.screen, (30, 30, 30), (x, 0), (x, SCREEN_HEIGHT), 1)
        for y in range(0, SCREEN_HEIGHT, 50):
            pygame.draw.line(self.screen, (30, 30, 30), (0, y), (SCREEN_WIDTH, y), 1)
        
        if self.game_state == STATE_MENU:
            self.draw_menu()
        elif self.game_state == STATE_PLAYER_SELECT:
            self.draw_player_select()
        elif self.game_state == STATE_PLAYING:
            self.draw_game()
        elif self.game_state == STATE_PAUSED:
            self.draw_game()
            self.draw_pause_screen()
        elif self.game_state == STATE_GAME_OVER:
            self.draw_game()
            self.draw_game_over()
        elif self.game_state == STATE_LEVEL_COMPLETE:
            self.draw_game()
            self.draw_level_complete()
        
        pygame.display.flip()
        
    def draw_game(self):
        for platform in self.level.platforms:
            platform.draw(self.screen)
        for enemy in self.level.enemies:
            self.screen.blit(enemy.image, enemy.rect)
        for powerup in self.level.powerups:
            self.screen.blit(powerup.image, powerup.rect)
        
        if self.player1:
            self.player1.draw(self.screen)
        if self.player2:
            self.player2.draw(self.screen)
            
        for particle in self.particles:
            self.screen.blit(particle.image, particle.rect)
        
        if self.num_players == 1:
            score_text = self.font_medium.render(f"SCORE: {self.score1}", True, WHITE)
            self.screen.blit(score_text, (10, 10))
            
            level_text = self.font_medium.render(f"LEVEL: {self.level_num}", True, CYAN)
            self.screen.blit(level_text, (SCREEN_WIDTH - 300, 10))
            
            if self.player1:
                health_text = self.font_medium.render(f"LIVES: {self.player1.health}", True, RED)
                self.screen.blit(health_text, (10, 50))
                
                powerup_y = 90
                if self.player1.shield:
                    shield_text = self.font_small.render(f"SHIELD: {self.player1.shield_time // 60}s", True, PINK)
                    self.screen.blit(shield_text, (10, powerup_y))
                    powerup_y += 30
                if self.player1.speed_boost:
                    speed_text = self.font_small.render(f"SPEED: {self.player1.speed_boost_time // 60}s", True, LIME)
                    self.screen.blit(speed_text, (10, powerup_y))
                    powerup_y += 30
                if self.player1.slow_time:
                    slow_text = self.font_small.render(f"SLOW: {self.player1.slow_time_time // 60}s", True, PURPLE)
                    self.screen.blit(slow_text, (10, powerup_y))
                    powerup_y += 30
                if self.player1.magnet:
                    magnet_text = self.font_small.render(f"MAGNET: {self.player1.magnet_time // 60}s", True, ORANGE)
                    self.screen.blit(magnet_text, (10, powerup_y))
                    powerup_y += 30
                if self.player1.invincible:
                    inv_text = self.font_small.render(f"INVINCIBLE: {self.player1.invincible_time_powerup // 60}s", True, YELLOW)
                    self.screen.blit(inv_text, (10, powerup_y))
                    powerup_y += 30
                if self.player1.current_size == 0.5:
                    small_text = self.font_small.render("SMALL MODE", True, CYAN)
                    self.screen.blit(small_text, (10, powerup_y))
                    powerup_y += 30
                if self.player1.current_size == 1.5:
                    big_text = self.font_small.render("BIG MODE", True, ORANGE)
                    self.screen.blit(big_text, (10, powerup_y))
                
                if self.player1.score_multiplier > 1:
                    mult_text = self.font_small.render(f"MULTIPLIER: {self.player1.score_multiplier:.1f}x", True, YELLOW)
                    self.screen.blit(mult_text, (SCREEN_WIDTH - 350, 50))
        else:
            level_text = self.font_medium.render(f"LEVEL: {self.level_num}", True, CYAN)
            self.screen.blit(level_text, (SCREEN_WIDTH // 2 - 100, 10))
            
            p1_label = self.font_medium.render("P1", True, BLUE)
            self.screen.blit(p1_label, (10, 10))
            
            score_text1 = self.font_medium.render(f"SCORE: {self.score1}", True, BLUE)
            self.screen.blit(score_text1, (10, 50))
            
            if self.player1:
                health_text1 = self.font_medium.render(f"LIVES: {self.player1.health}", True, RED)
                self.screen.blit(health_text1, (10, 90))
            else:
                dead_text1 = self.font_medium.render("DEAD", True, RED)
                self.screen.blit(dead_text1, (10, 90))
            
            p2_label = self.font_medium.render("P2", True, ORANGE)
            self.screen.blit(p2_label, (SCREEN_WIDTH - 100, 10))
            
            score_text2 = self.font_medium.render(f"SCORE: {self.score2}", True, ORANGE)
            self.screen.blit(score_text2, (SCREEN_WIDTH - 350, 50))
            
            if self.player2:
                health_text2 = self.font_medium.render(f"LIVES: {self.player2.health}", True, RED)
                self.screen.blit(health_text2, (SCREEN_WIDTH - 250, 90))
            else:
                dead_text2 = self.font_medium.render("DEAD", True, RED)
                self.screen.blit(dead_text2, (SCREEN_WIDTH - 250, 90))
    
    def draw_menu(self):
        title_text = self.font_large.render("PLATFORM MASTER", True, CYAN)
        subtitle_text = self.font_medium.render("ADVANCED EDITION", True, WHITE)
        start_text = self.font_medium.render("PRESS SPACE TO SELECT MODE", True, LIME)
        controls_text = self.font_small.render("P1: A/D MOVE, W JUMP | P2: ARROW KEYS MOVE/JUMP", True, WHITE)
        
        self.screen.blit(title_text, (SCREEN_WIDTH // 2 - 350, 100))
        self.screen.blit(subtitle_text, (SCREEN_WIDTH // 2 - 120, 180))
        self.screen.blit(start_text, (SCREEN_WIDTH // 2 - 300, 450))
        self.screen.blit(controls_text, (SCREEN_WIDTH // 2 - 450, 600))
    
    def draw_player_select(self):
        title_text = self.font_large.render("SELECT GAME MODE", True, CYAN)
        one_player_text = self.font_medium.render("PRESS 1 FOR SINGLE PLAYER", True, BLUE)
        two_player_text = self.font_medium.render("PRESS 2 FOR TWO PLAYER", True, ORANGE)
        
        self.screen.blit(title_text, (SCREEN_WIDTH // 2 - 280, 150))
        self.screen.blit(one_player_text, (SCREEN_WIDTH // 2 - 300, 350))
        self.screen.blit(two_player_text, (SCREEN_WIDTH // 2 - 300, 500))
        
    def draw_pause_screen(self):
        self.draw_overlay()
        pause_text = self.font_large.render("PAUSED", True, YELLOW)
        resume_text = self.font_medium.render("PRESS ESC TO RESUME", True, WHITE)
        self.screen.blit(pause_text, (SCREEN_WIDTH // 2 - 150, SCREEN_HEIGHT // 2 - 50))
        self.screen.blit(resume_text, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 + 50))
        
    def draw_game_over(self):
        self.draw_overlay()
        game_over_text = self.font_large.render("GAME OVER!", True, RED)
        
        if self.num_players == 1:
            final_score_text = self.font_medium.render(f"FINAL SCORE: {self.score1}", True, WHITE)
            best_score_text = self.font_medium.render(f"BEST SCORE: {self.best_score1}", True, YELLOW)
            self.screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 - 150))
            self.screen.blit(final_score_text, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 - 20))
            self.screen.blit(best_score_text, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 + 40))
        else:
            if self.score1 > self.score2:
                winner_text = self.font_medium.render("PLAYER 1 WINS!", True, BLUE)
            elif self.score2 > self.score1:
                winner_text = self.font_medium.render("PLAYER 2 WINS!", True, ORANGE)
            else:
                winner_text = self.font_medium.render("TIE GAME!", True, YELLOW)
            
            score_text1 = self.font_medium.render(f"P1 SCORE: {self.score1}", True, BLUE)
            score_text2 = self.font_medium.render(f"P2 SCORE: {self.score2}", True, ORANGE)
            
            self.screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 - 200))
            self.screen.blit(winner_text, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 - 80))
            self.screen.blit(score_text1, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 + 20))
            self.screen.blit(score_text2, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 + 70))
        
        restart_text = self.font_medium.render("PRESS R TO RESTART | ESC TO MENU", True, WHITE)
        self.screen.blit(restart_text, (SCREEN_WIDTH // 2 - 350, SCREEN_HEIGHT // 2 + 150))
        
    def draw_level_complete(self):
        self.draw_overlay()
        complete_text = self.font_large.render("LEVEL COMPLETE!", True, YELLOW)
        next_level_text = self.font_medium.render(f"PRESS R FOR LEVEL {self.level_num + 1}", True, WHITE)
        
        if self.num_players == 1:
            score_text = self.font_medium.render(f"SCORE: {self.score1}", True, LIME)
            self.screen.blit(complete_text, (SCREEN_WIDTH // 2 - 250, SCREEN_HEIGHT // 2 - 100))
            self.screen.blit(score_text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2))
        else:
            score_text1 = self.font_medium.render(f"P1 SCORE: {self.score1}", True, BLUE)
            score_text2 = self.font_medium.render(f"P2 SCORE: {self.score2}", True, ORANGE)
            self.screen.blit(complete_text, (SCREEN_WIDTH // 2 - 250, SCREEN_HEIGHT // 2 - 120))
            self.screen.blit(score_text1, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 - 20))
            self.screen.blit(score_text2, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2 + 30))
        
        self.screen.blit(next_level_text, (SCREEN_WIDTH // 2 - 300, SCREEN_HEIGHT // 2 + 120))
        
    def draw_overlay(self):
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
        overlay.set_alpha(200)
        overlay.fill(BLACK)
        self.screen.blit(overlay, (0, 0))
        
    def reset_game(self):
        self.level_num = 1
        self.level = Level(self.level_num)
        
        if self.num_players == 1:
            self.player1 = Player(SCREEN_WIDTH // 2 - 20, SCREEN_HEIGHT - 130, 1)
            self.player2 = None
            self.level.generate_level()
            self.highest_y1 = SCREEN_HEIGHT
        else:
            self.player1 = Player(250 - 20, SCREEN_HEIGHT - 130, 1)
            self.player2 = Player(SCREEN_WIDTH - 250 - 20, SCREEN_HEIGHT - 130, 2)
            self.level.generate_level_two_player()
            self.highest_y1 = SCREEN_HEIGHT
            self.highest_y2 = SCREEN_HEIGHT
        
        self.particles = pygame.sprite.Group()
        self.score1 = 0
        self.score2 = 0
        self.game_state = STATE_PLAYING
        self.time_elapsed = 0
        
    def next_level(self):
        self.level_num += 1
        self.level = Level(self.level_num)
        
        if self.num_players == 1:
            self.player1 = Player(SCREEN_WIDTH // 2 - 20, SCREEN_HEIGHT - 130, 1)
            self.player2 = None
            self.level.generate_level()
            self.highest_y1 = SCREEN_HEIGHT
        else:
            self.player1 = Player(250 - 20, SCREEN_HEIGHT - 130, 1)
            self.player2 = Player(SCREEN_WIDTH - 250 - 20, SCREEN_HEIGHT - 130, 2)
            self.level.generate_level_two_player()
            self.highest_y1 = SCREEN_HEIGHT
            self.highest_y2 = SCREEN_HEIGHT
        
        self.particles = pygame.sprite.Group()
        self.game_state = STATE_PLAYING
        self.time_elapsed = 0
        
    def run(self):
        while self.running:
            self.handle_events()
            if self.game_state == STATE_PLAYING:
                self.handle_input()
            self.update()
            self.draw()
            self.clock.tick(FPS)
            
        pygame.quit()

if __name__ == "__main__":
    game = Game()
    game.run()

i wanna make a flappy bird game or a math app

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top