import pygame import math import random from pygame.locals import * import pickle from os import path pygame.init() # Load background sound pygame.mixer.music.load('sounds/soundtrack.mp3') pygame.mixer.music.play(-1) # -1 plays the music indefinitely # Load gunshot sound gunshot_sound = pygame.mixer.Sound('sounds/gunshot.mp3') screen_width = 1000 screen_height = 800 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption('Platformer') tile_size = 50 # Load background image background_img = pygame.image.load('img/eyes.jpg') background_img = pygame.transform.scale(background_img, (screen_width, screen_height)) def main_menu(): while True: screen.blit(background_img, (0, 0)) # Set background image keys = pygame.key.get_pressed() # Get the pressed keys # Draw title title_font = pygame.font.SysFont(None, 80) title_text = title_font.render("APOCALYPSE RISING", True, (255, 0, 0)) title_rect = title_text.get_rect(center=(screen_width // 2, 100)) screen.blit(title_text, title_rect) # Draw main menu options menu_font = pygame.font.SysFont(None, 60) start_text = menu_font.render("Start (S)", True, (255, 255, 255)) exit_text = menu_font.render("Exit (ESC)", True, (255, 255, 255)) level2_text = menu_font.render("Level 2", True, (255, 255, 255)) level3_text = menu_font.render("Level 3", True, (255, 255, 255)) start_rect = start_text.get_rect(center=(screen_width // 2, screen_height // 2 - 50)) exit_rect = exit_text.get_rect(center=(screen_width // 2, screen_height // 2 + 50)) level2_rect = level2_text.get_rect(center=(screen_width // 2, screen_height // 2 + 150)) level3_rect = level3_text.get_rect(center=(screen_width // 2, screen_height // 2 + 250)) screen.blit(start_text, start_rect) screen.blit(exit_text, exit_rect) screen.blit(level2_text, level2_rect) screen.blit(level3_text, level3_rect) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_s: return elif event.key == pygame.K_ESCAPE: pygame.quit() quit() elif event.type == pygame.MOUSEBUTTONDOWN: if level2_rect.collidepoint(event.pos): return "level2" elif level3_rect.collidepoint(event.pos): return "level3" # Load grass and wall images grass_img = pygame.image.load('img/grass.jpg') grass_img = pygame.transform.scale(grass_img, (screen_width, screen_height)) wall_img = pygame.image.load('img/wall.jpg') wall_img = pygame.transform.scale(wall_img, (tile_size, tile_size)) # Load player images for different directions player_img_right = pygame.image.load('img/guy2_right.png') player_img_left = pygame.image.load('img/guy2_left.png') player_img_up = pygame.image.load('img/guy2_up.png') player_img_down = pygame.image.load('img/guy2_down.png') # Increase player size player_width = 40 player_height = 80 player_img_right = pygame.transform.scale(player_img_right, (player_width, player_height)) player_img_left = pygame.transform.scale(player_img_left, (player_width, player_height)) player_img_up = pygame.transform.scale(player_img_up, (player_width, player_height)) player_img_down = pygame.transform.scale(player_img_down, (player_width, player_height)) # Load bullet image bullet_img = pygame.image.load('img/bullet.png') bullet_img = pygame.transform.scale(bullet_img, (20, 20)) # Load reload image reload_img = pygame.image.load('img/reload.png') reload_img = pygame.transform.scale(reload_img, (30, 30)) # Load NPC image npc_img = pygame.image.load('img/zombie.gif') npc_img = pygame.transform.scale(npc_img, (tile_size, tile_size)) # Load blood image blood_img = pygame.image.load('img/blood.png') blood_img = pygame.transform.scale(blood_img, (tile_size, tile_size)) # Load key image key_img = pygame.image.load('img/key.png') key_img = pygame.transform.scale(key_img, (50, 50)) # Load gate images gate_closed_img = pygame.image.load('img/gateclosed.png') gate_closed_img = pygame.transform.scale(gate_closed_img, (2 * tile_size, tile_size)) gate_open_img = pygame.image.load('img/gateopen.png') gate_open_img = pygame.transform.scale(gate_open_img, (2 * tile_size, tile_size)) class World(): def __init__(self, data): self.tile_list = [] self.create_world(data) def create_world(self, data): for row_idx, row in enumerate(data): for col_idx, tile in enumerate(row): if tile == 1 or self.is_border(row_idx, col_idx, data): tile_rect = pygame.Rect(col_idx * tile_size, row_idx * tile_size, tile_size, tile_size) self.tile_list.append(tile_rect) def is_border(self, row_idx, col_idx, data): return row_idx == 0 or row_idx == len(data) - 1 or col_idx == 0 or col_idx == len(data[0]) - 1 def draw(self): for tile in self.tile_list: screen.blit(wall_img, tile) class Player(): def __init__(self, x, y): self.x = x self.y = y self.width = player_width self.height = player_height self.vel = 5 self.angle = 0 self.projectiles = [] self.shot_count = 0 # Number of shots fired self.max_shots = 20 # Maximum number of shots before reloading self.reloading = False # Flag to indicate if reloading self.reload_time = 60 # Reload time in frames self.reload_timer = 0 # Timer for reload self.has_key = False # Flag to indicate whether the player has picked up the key def draw(self): mouse_x, mouse_y = pygame.mouse.get_pos() self.angle = math.degrees(math.atan2(mouse_y - (self.y + self.height // 2), mouse_x - (self.x + self.width // 2))) rotated_image = pygame.transform.rotate(player_img_right, -self.angle) rotated_rect = rotated_image.get_rect(center=(self.x + self.width // 2, self.y + self.height // 2)) screen.blit(rotated_image, rotated_rect.topleft) for projectile in self.projectiles: projectile.draw(screen) # Display bullet counter bullet_counter_text = pygame.font.SysFont(None, 30).render(str(self.max_shots - self.shot_count), True, (255, 255, 255)) screen.blit(bullet_counter_text, (screen_width - 50, screen_height - 30)) screen.blit(reload_img, (screen_width - 90, screen_height - 30)) if self.has_key: # Display text indicating the player has the key key_text = pygame.font.SysFont(None, 30).render("Key: Yes", True, (255, 255, 255)) screen.blit(key_text, (screen_width - 120, screen_height - 70)) def move(self, keys, world, key, gate): new_x = self.x new_y = self.y if keys[pygame.K_LEFT]: new_x -= self.vel if keys[pygame.K_RIGHT]: new_x += self.vel if keys[pygame.K_UP]: new_y -= self.vel if keys[pygame.K_DOWN]: new_y += self.vel player_rect = pygame.Rect(new_x, new_y, self.width, self.height) current_rect = pygame.Rect(self.x, self.y, self.width, self.height) for tile in world.tile_list: if player_rect.colliderect(tile): if keys[pygame.K_LEFT] and not player_rect.colliderect(tile.move(-self.vel, 0)): new_x = max(tile.right, new_x) elif keys[pygame.K_RIGHT] and not player_rect.colliderect(tile.move(self.vel, 0)): new_x = min(tile.left - self.width, new_x) elif keys[pygame.K_UP] and not player_rect.colliderect(tile.move(0, -self.vel)): new_y = max(tile.bottom, new_y) elif keys[pygame.K_DOWN] and not player_rect.colliderect(tile.move(0, self.vel)): new_y = min(tile.top - self.height, new_y) if player_rect.colliderect(key.rect): self.has_key = True key.rect.x = -100 # Move the key out of sight if not gate.open: gate.open_gate() # Open the gate if it's closed if not gate.open and player_rect.colliderect(gate.rect): # Check collision with closed gate if not self.has_key: # If player does not have the key, prevent movement through the gate if keys[pygame.K_LEFT]: new_x = max(gate.rect.right, new_x) elif keys[pygame.K_RIGHT]: new_x = min(gate.rect.left - self.width, new_x) elif keys[pygame.K_UP]: new_y = max(gate.rect.bottom, new_y) elif keys[pygame.K_DOWN]: new_y = min(gate.rect.top - self.height, new_y) self.x = new_x self.y = new_y def shoot(self): if not self.reloading and self.shot_count < self.max_shots: # Play gunshot sound gunshot_sound.play() mouse_x, mouse_y = pygame.mouse.get_pos() start_x = self.x - 10 start_y = self.y + self.height // 2 new_projectile = Projectile(start_x, start_y, mouse_x, mouse_y) self.projectiles.append(new_projectile) self.shot_count += 1 def reload(self): if self.shot_count == self.max_shots: self.reloading = True self.reload_timer = 0 def update(self): if self.reloading: self.reload_timer += 1 if self.reload_timer >= self.reload_time: self.reloading = False self.reload_timer = 0 self.shot_count = 0 class Projectile(): def __init__(self, x, y, target_x, target_y): self.x = x self.y = y self.target_x = target_x self.target_y = target_y self.speed = 50 self.angle = math.atan2(target_y - y, target_x - x) self.vel_x = math.cos(self.angle) * self.speed self.vel_y = math.sin(self.angle) * self.speed self.radius = 5 self.bullet_image = bullet_img self.active = True def move(self): self.x += self.vel_x self.y += self.vel_y def check_collision(self, world, npc): for tile in world.tile_list: if pygame.Rect(self.x - self.radius, self.y - self.radius, 2 * self.radius, 2 * self.radius).colliderect( tile): self.active = False npc_rect = pygame.Rect(npc.x, npc.y, npc.width, npc.height) if pygame.Rect(self.x - self.radius, self.y - self.radius, 2 * self.radius, 2 * self.radius).colliderect( npc_rect): self.active = False npc.hit = True def draw(self, screen): if self.active: screen.blit(pygame.transform.rotate(self.bullet_image, math.degrees(self.angle)), (self.x, self.y)) class NPC: def __init__(self, x, y): self.x = x self.y = y self.width = tile_size self.height = tile_size self.vel = 2 self.direction = random.choice(["LEFT", "RIGHT"]) self.image = npc_img self.angle = 0 self.hit = False def draw(self): if not self.hit: if self.direction == "LEFT": rotated_image = pygame.transform.rotate(self.image, 180) else: rotated_image = self.image screen.blit(rotated_image, (self.x, self.y)) else: screen.blit(blood_img, (self.x, self.y)) def move(self, world): if not self.hit: new_x = self.x if self.direction == "LEFT": new_x -= self.vel elif self.direction == "RIGHT": new_x += self.vel npc_rect = pygame.Rect(new_x, self.y, self.width, self.height) for tile in world.tile_list: if npc_rect.colliderect(tile): if self.direction == "LEFT": self.direction = "RIGHT" elif self.direction == "RIGHT": self.direction = "LEFT" break if self.direction == "LEFT": self.x -= self.vel elif self.direction == "RIGHT": self.x += self.vel if self.x <= 0: self.x = 0 self.direction = "RIGHT" elif self.x >= screen_width - self.width: self.x = screen_width - self.width self.direction = "LEFT" class Key: def __init__(self): self.image = key_img self.rect = self.image.get_rect() self.rect.bottomright = (screen_width - 55, screen_height - 55) def draw(self, surface): surface.blit(self.image, self.rect) class Gate: def __init__(self): self.image_closed = gate_closed_img self.image_open = gate_open_img self.rect = self.image_closed.get_rect() self.rect.topright = (850, 150) self.open = False def draw(self, surface): if self.open: surface.blit(self.image_open, self.rect) else: surface.blit(self.image_closed, self.rect) def open_gate(self): self.open = True def main(): selected_level = main_menu() # Call the main menu function to select a level if selected_level == "level2": world_data = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], ] elif selected_level == "level3": world_data = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], ] else: world_data = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], ] world = World(world_data) player = Player(50, 50) npc = NPC(600, 300) key = Key() gate = Gate() clock = pygame.time.Clock() run = True while run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: player.shoot() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_r: player.reload() keys = pygame.key.get_pressed() player.move(keys, world, key, gate) npc.move(world) for projectile in player.projectiles[:]: projectile.move() projectile.check_collision(world, npc) if not projectile.active or not (0 <= projectile.x <= screen_width and 0 <= projectile.y <= screen_height): player.projectiles.remove(projectile) player.update() screen.blit(grass_img, (0, 0)) world.draw() player.draw() npc.draw() key.draw(screen) gate.draw(screen) pygame.display.update() clock.tick(60) pygame.quit() if __name__ == "__main__": main()