""" --------------------------------------------------- Project: Shooter Platformer Standard: 91883 (AS1.7) v.1 School: Tauranga Boy's College Author: Kayden Franz-Kwan Date: 30/04/2025 Python: 3.7.4 --------------------------------------------------- """ #Imports import pygame from pygame import mixer import os import random import csv import button #Initialize pygame mixer.init() pygame.init() #Screen setup WIDTH = 800 HEIGHT = int(WIDTH * 0.8) screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Shooter") #Define player action variables moving_left = False moving_right = False shoot = False grenade = False grenade_thrown = False #Define game variables GRAVITY = 0.75 SCROLL_THRESH = 200 ROWS = 16 COLS = 150 TILE_SIZE = HEIGHT // ROWS TILE_TYPES = 22 screen_scroll = 0 bg_scroll = 0 level = 0 start_game = False start_intro = False #Load music and sounds pygame.mixer.music.load("./audio/music2.mp3") pygame.mixer.music.set_volume(0.5) pygame.mixer.music.play(-1, 0.0, 5000) #Load in sound effects jump_fx = pygame.mixer.Sound("./audio/jump.wav") jump_fx.set_volume(0.5) shot_fx = pygame.mixer.Sound("./audio/shot.wav") shot_fx.set_volume(0.5) grenade_fx = pygame.mixer.Sound("./audio/grenade.wav") grenade_fx.set_volume(0.5) #Store tiles in a list img_list = [] for x in range(TILE_TYPES): img = pygame.image.load(f"./img/Tile/{x}.png") img = pygame.transform.scale(img, (TILE_SIZE, TILE_SIZE)) img_list.append(img) #Load images bullet_img = pygame.image.load("./img/icons/bullet.png").convert_alpha() grenade_img = pygame.image.load("./img/icons/grenade.png").convert_alpha() health_box_img = pygame.image.load("./img/icons/health_box.png").convert_alpha() ammo_box_img = pygame.image.load("./img/icons/ammo_box.png").convert_alpha() grenade_box_img = pygame.image.load("./img/icons/grenade_box.png").convert_alpha() item_boxes = { 'Health' : health_box_img, 'Ammo' : ammo_box_img, 'Grenade' : grenade_box_img } pine1_img = pygame.image.load("./img/background/pine1.png").convert_alpha() pine2_img = pygame.image.load("./img/background/pine2.png").convert_alpha() sky_img = pygame.image.load("./img/background/sky_cloud.png").convert_alpha() start_img = pygame.image.load("./img/start_btn.png").convert_alpha() exit_img = pygame.image.load("./img/exit_btn.png").convert_alpha() restart_img = pygame.image.load("./img/restart_btn.png").convert_alpha() #Define colours BG = (144, 201, 120) RED = (255, 0, 0) WHITE = (255, 255, 255) GREEN = (0, 255, 0) BLACK = (0, 0, 0) PINK = (235, 65, 54) #Define font font = pygame.font.SysFont("Futura", 30) def draw_text(text, font, text_col, x, y): img = font.render(text, True, text_col) screen.blit(img, (x, y)) def draw_bg(): screen_width = sky_img.get_width() for x in range(5): screen.blit(sky_img, ((x * screen_width) - bg_scroll * 0.5, 0)) screen.blit(pine1_img, ((x * screen_width) - bg_scroll * 0.7, HEIGHT - pine1_img.get_height() - 150)) screen.blit(pine2_img, ((x * screen_width) - bg_scroll * 0.8, HEIGHT - pine2_img.get_height())) #Set frame rate clock = pygame.time.Clock() FPS = 60 #Function to reset level def reset_level(): enemy_group.empty() bullet_group.empty() grenade_group.empty() explosion_group.empty() item_box_group.empty() decoration_group.empty() water_group.empty() exit_group.empty() blueprint_group.empty() player.goalAchieved = False player.time = 0 #Create empty tile list data = [] for row in range(ROWS): r = [-1] * COLS data.append(r) return data def getHTime(): scores = [] #Load in level data with open('./Scores.csv', newline='') as csvfile: reader = csv.reader(csvfile, delimiter = ',') for row in reader: scores.append(row) hTime = scores[level] player.hTime = int(hTime[0]) def rewriteHTime(): scoresR = [] #Load in level data with open('./Scores.csv', newline='') as csvfile: reader = csv.reader(csvfile, delimiter = ',') for row in reader: scoresR.append(row) hTime = scoresR[level] player.hTime = int(hTime[0]) if player.hTime > player.time: scoresW = [] count = 0 for row in scoresR: if count == level: addedRow = [player.time, 0] scoresW.append(addedRow) else: addedRow = [int(row[0]), 0] scoresW.append(addedRow) count += 1 #Save level data with open('./Scores.csv', 'w', newline='') as csvfile: writer = csv.writer(csvfile, delimiter = ',') for row in scoresW: writer.writerow(row) #Soldier class Soldier(pygame.sprite.Sprite): def __init__(self, char_type, x, y, scale, speed, ammo, grenades): pygame.sprite.Sprite.__init__(self) self.alive = True self.char_type = char_type self.speed = speed self.start_ammo = ammo self.ammo = ammo self.shoot_cooldown = 0 self.grenades = grenades self.health = 100 self.max_health = self.health self.direction = 1 self.vel_y = 0 self.jump = False self.in_air = True self.flip = False self.animation_list = [] self.frame_index = 0 self.action = 0 self.update_time = pygame.time.get_ticks() self.goalAchieved = False self.time = 0 self.hTime = 0 #Create ai specific variables self.move_counter = 0 self.vision = pygame.Rect(0, 0, 150, 20) self.idling = False self.idling_counter = 0 #Load all images for players animation_types = ["Idle", "Run", "Jump", "Death"] for animation in animation_types: #Reset temporary list of images temp_list = [] #Count number of files in folder num_of_frames = len(os.listdir(f"./img/{self.char_type}/{animation}")) for i in range(num_of_frames): img = pygame.image.load(f"./img/{self.char_type}/{animation}/{i}.png").convert_alpha() img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale))) temp_list.append(img) self.animation_list.append(temp_list) self.image = self.animation_list[self.action][self.frame_index] self.rect = self.image.get_rect() self.rect.center = (x, y) self.width = self.image.get_width() self.height = self.image.get_height() def update(self): self.update_animation() self.check_alive() #Update cooldown if self.shoot_cooldown > 0: self.shoot_cooldown -= 1 def move(self, moving_left, moving_right): #Reset movement variables screen_scroll = 0 dx = 0 dy = 0 #assign movement variables if moving left or right if moving_left == True: dx = -self.speed self.flip = True self.direction = -1 if moving_right == True: dx = self.speed self.flip = False self.direction = 1 #Jump if self.jump == True and self.in_air == False: self.vel_y = -15 self.jump = False self.in_air = True #Apply gravity self.vel_y += GRAVITY if self.vel_y > 10: self.vel_y = 10 dy += self.vel_y #Check collision for tile in world.obstacle_list: #Check colllsion in x direction if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height - 1): dx = 0 #If the AI has hit a wall then make it turn around if self.char_type == "enemy": self.direction *= -1 self.move_counter = 0 #Check colllsion in y direction if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height): #Check if below the ground, i.e. jumping if self.vel_y < 0: self.vel_y = 0 dy = tile[1].bottom - self.rect.top #Check if above the ground, i.e. falling elif self.vel_y >= 0: self.vel_y = 0 self.in_air = False dy = tile[1].top - self.rect.bottom #Check for collision with water if pygame.sprite.spritecollide(self, water_group, False): self.health = 0 #Check if fallen off map if self.rect.bottom > HEIGHT: self.health = 0 #Check if going off the edges of the screen if self.char_type == "player": if self.rect.left + dx < 0 or self.rect.right + dx > WIDTH: dx = 0 #Check got collision with exit level_complete = False if pygame.sprite.spritecollide(self, exit_group, False): level_complete = True #Update rectangle position self.rect.x += dx self.rect.y += dy #Update scroll based on player position if self.char_type == "player": if (self.rect.right > WIDTH - SCROLL_THRESH and bg_scroll < (world.level_length * TILE_SIZE) - WIDTH)\ or (self.rect.left < SCROLL_THRESH and bg_scroll > abs(dx)): self.rect.x -= dx screen_scroll = -dx return screen_scroll, level_complete def shoot(self): if self.shoot_cooldown == 0 and self.ammo > 0: bullet = Bullet(self.rect.centerx + (self.rect.size[0] * 0.75 * self.direction), self.rect.centery, self.direction) bullet_group.add(bullet) self.shoot_cooldown = 20 #Reduce ammo self.ammo -= 1 shot_fx.play() def ai(self): if self.alive and player.alive: if self.idling == False and random.randint(1, 200) == 1: self.update_action(0) #0: Idle self.idling = True self.idling_counter = 50 #Check if ai is near the player if self.vision.colliderect(player.rect): #Stop running and face player self.update_action(0) #0: Idle #Shoot self.shoot() else: if self.idling == False: if self.direction == 1: ai_moving_right = True else: ai_moving_right = False ai_moving_left = not ai_moving_right self.move(ai_moving_left, ai_moving_right) self.update_action(1) #1: run self.move_counter += 1 #Update enemy vision as enemy moves self.vision.center = (self.rect.centerx + 75 * self.direction, self.rect.centery) if self.move_counter > TILE_SIZE: self.direction *= -1 self.move_counter *= -1 else: self.idling_counter -= 1 if self.idling_counter <= 0: self.idling = False #Scroll self.rect.x += screen_scroll def update_animation(self): #Update animation ANIMATION_COOLDOWN = 100 #Update image depending on current frame self.image = self.animation_list[self.action][self.frame_index] #Check if enought time has passed since the last update if pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN: self.update_time = pygame.time.get_ticks() self.frame_index += 1 #If the animation has run out, reset back to the start if self.frame_index >= len(self.animation_list[self.action]): if self.action == 3: self.frame_index = len(self.animation_list[self.action]) - 1 else: self.frame_index = 0 def update_action(self, new_action): #Check if the new action is different to the previous one if new_action != self.action: self.action = new_action #Update animation settings self.frame_index = 0 self.update_time = pygame.time.get_ticks() def check_alive(self): if self.health <= 0: self.health = 0 self.speed = 0 self.alive = False self.update_action(3) #3: Death def draw(self): screen.blit(pygame.transform.flip(self.image, self.flip, False), self.rect) #World class World(): def __init__(self): self.obstacle_list = [] def process_data(self, data): self.level_length = len(data[0]) #Iterate through each value in level data file for y, row in enumerate(data): for x, tile in enumerate(row): if tile >= 0: img = img_list[tile] img_rect = img.get_rect() img_rect.x = x * TILE_SIZE img_rect.y = y * TILE_SIZE tile_data = (img, img_rect) if tile >= 0 and tile <= 8: #Save blocks to a list self.obstacle_list.append(tile_data) elif tile >= 9 and tile <= 10: #Draw water water = Water(img, x * TILE_SIZE, y * TILE_SIZE) water_group.add(water) elif tile >= 11 and tile < 14: #Draw decoration decoration = Decoration(img, x * TILE_SIZE, y * TILE_SIZE) decoration_group.add(decoration) elif tile == 15: #Create player player = Soldier("player", x * TILE_SIZE, y * TILE_SIZE, 1.65, 5, 20, 5) health_bar = HealthBar(10, 10, player.health, player.max_health) elif tile == 16: #Create enemies enemy = Soldier("enemy", x * TILE_SIZE, y * TILE_SIZE, 1.65, 2, 20, 0) enemy_group.add(enemy) elif tile == 17: #Create ammo box item_box = ItemBox('Ammo', x * TILE_SIZE, y *TILE_SIZE) item_box_group.add(item_box) elif tile == 18: #Create grenade box item_box = ItemBox('Grenade', x * TILE_SIZE, y *TILE_SIZE) item_box_group.add(item_box) elif tile == 19: #Create health box item_box = ItemBox('Health', x * TILE_SIZE, y *TILE_SIZE) item_box_group.add(item_box) elif tile == 20: #Create exit exit = Exit(img, x * TILE_SIZE, y * TILE_SIZE) exit_group.add(exit) elif tile == 21: #Create blueprint blueprint = Blueprint(img, x * TILE_SIZE, y * TILE_SIZE) blueprint_group.add(blueprint) return player, health_bar def draw(self): for tile in self.obstacle_list: tile[1][0] += screen_scroll screen.blit(tile[0], tile[1]) #Decoration class Decoration(pygame.sprite.Sprite): def __init__(self, img, x, y): pygame.sprite.Sprite.__init__(self) self.image = img self.rect = self.image.get_rect() self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height())) def update(self): #Scroll self.rect.x += screen_scroll #Water class Water(pygame.sprite.Sprite): def __init__(self, img, x, y): pygame.sprite.Sprite.__init__(self) self.image = img self.rect = self.image.get_rect() self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height())) def update(self): #Scroll self.rect.x += screen_scroll #Blueprint class Blueprint(pygame.sprite.Sprite): def __init__(self, img, x, y): pygame.sprite.Sprite.__init__(self) self.image = img self.rect = self.image.get_rect() self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height())) def update(self): #Scroll self.rect.x += screen_scroll #Check if the player has picked up the box if pygame.sprite.collide_rect(self, player): #Allow player to complete level player.goalAchieved = True #Delete the item box self.kill() #Exit class Exit(pygame.sprite.Sprite): def __init__(self, img, x, y): pygame.sprite.Sprite.__init__(self) self.image = img self.rect = self.image.get_rect() self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height())) def update(self): #Scroll self.rect.x += screen_scroll #Item drop class class ItemBox(pygame.sprite.Sprite): def __init__(self, item_type, x, y): pygame.sprite.Sprite.__init__(self) self.item_type = item_type self.image = item_boxes[self.item_type] self.rect = self.image.get_rect() self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height())) def update(self): #Scroll self.rect.x += screen_scroll #Check if the player has picked up the box if pygame.sprite.collide_rect(self, player): #Check what kind of box it was if self.item_type == "Health": player.health += 25 if player.health > player.max_health: player.health = player.max_health elif self.item_type == "Ammo": player.ammo += 15 elif self.item_type == "Grenade": player.grenades += 3 #Delete the item box self.kill() #Create health bar class HealthBar(): def __init__(self, x, y, health, max_health): self.x = x self.y = y self.health = health self.max_health = max_health def draw(self, health): #Update with new health self.health = health ratio = self.health / self.max_health pygame.draw.rect(screen, BLACK, (self.x - 2, self.y - 2, 154, 24)) pygame.draw.rect(screen, RED, (self.x, self.y, 150, 20)) pygame.draw.rect(screen, GREEN, (self.x, self.y, 150 * ratio, 20)) #Bullet class class Bullet(pygame.sprite.Sprite): def __init__(self, x, y, direction): pygame.sprite.Sprite.__init__(self) self.speed = 10 self.image = bullet_img self.rect = self.image.get_rect() self.rect.center = (x, y) self.direction = direction def update(self): #Move bullet self.rect.x += (self.direction * self.speed) + screen_scroll #Check if bullet has gone off screen if self.rect.right < 0 or self.rect.left > WIDTH: self.kill() #Check collision with level for tile in world.obstacle_list: if tile[1].colliderect(self.rect): self.kill() #Check collision with characters if pygame.sprite.spritecollide(player, bullet_group, False): if player.alive: self.kill() player.health -= 5 for enemy in enemy_group: if pygame.sprite.spritecollide(enemy, bullet_group, False): if enemy.alive: self.kill() enemy.health -= 20 #Grenade class class Grenade(pygame.sprite.Sprite): def __init__(self, x, y, direction): pygame.sprite.Sprite.__init__(self) self.timer = 100 self.vel_y = -11 self.speed = 7 self.image = grenade_img self.rect = self.image.get_rect() self.rect.center = (x, y) self.width = self.image.get_width() self.height = self.image.get_height() self.direction = direction def update(self): self.vel_y += GRAVITY dx = self.speed * self.direction dy = self.vel_y #Check collision with level for tile in world.obstacle_list: #Check for collisions with walls if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height): self.direction *= -1 dx = self.speed * self.direction #Check for collisions with ground if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height): #Check if below the ground, i.e. jumping if self.vel_y < 0: self.vel_y = 0 dy = tile[1].bottom - self.rect.top #Check if above the ground, i.e. falling elif self.vel_y >= 0: self.vel_y = 0 self.in_air = False dy = tile[1].top - self.rect.bottom #Update grenade position self.rect.x += dx + screen_scroll self.rect.y += dy #Countdown timer self.timer -= 1 if self.timer <= 0: grenade_fx.play() self.kill() explosion = Explosion(self.rect.x, self.rect.y, 1) explosion_group.add(explosion) #Do damage to anyone that is nearby if abs(self.rect.centerx - player.rect.centerx) < TILE_SIZE * 2 and \ abs(self.rect.centery - player.rect.centery) < TILE_SIZE * 2: player.health -= 50 for enemy in enemy_group: if abs(self.rect.centerx - enemy.rect.centerx) < TILE_SIZE * 2 and \ abs(self.rect.centery - enemy.rect.centery) < TILE_SIZE * 2: enemy.health -= 50 #Create explosions class Explosion(pygame.sprite.Sprite): def __init__(self, x, y, scale): pygame.sprite.Sprite.__init__(self) self.images = [] for num in range(1, 6): img = pygame.image.load(f"./img/explosion/exp{num}.png").convert_alpha() img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale))) self.images.append(img) self.frame_index = 0 self.image = self.images[self.frame_index] self.rect = self.image.get_rect() self.rect.center = (x, y) self.counter = 0 def update(self): #Scroll self.rect.x += screen_scroll EXPLOSION_SPEED = 4 #Update exlposion animation self.counter += 1 if self.counter >= EXPLOSION_SPEED: self.counter = 0 self.frame_index += 1 #If the animation is complete then delete the explosion if self.frame_index >= len(self.images): self.kill() else: self.image = self.images[self.frame_index] #Create Fades class ScreenFade(): def __init__(self, direction, colour, speed): self.direction = direction self.colour = colour self.speed = speed self.fade_counter = 0 def fade(self): fade_complete = False self.fade_counter += self.speed if self.direction == 1: #Whole screen fade pygame.draw.rect(screen, self.colour, (0 - self.fade_counter, 0, WIDTH // 2, HEIGHT)) pygame.draw.rect(screen, self.colour, (WIDTH // 2 + self.fade_counter, 0, WIDTH, HEIGHT)) pygame.draw.rect(screen, self.colour, (0, 0 - self.fade_counter, WIDTH, HEIGHT // 2)) pygame.draw.rect(screen, self.colour, (0, HEIGHT // 2 + self.fade_counter, WIDTH, HEIGHT)) if self.direction == 2: #Vertical screen fade down pygame.draw.rect(screen, self.colour, (0, 0, WIDTH, 0 + self.fade_counter)) if self.fade_counter >= HEIGHT: fade_complete = True return fade_complete #Create screen fades intro_fade = ScreenFade(1, BLACK, 4) death_fade = ScreenFade(2, PINK, 4) #Create buttons start_button = button.Button(WIDTH // 2 - 130, HEIGHT // 2 - 150, start_img, 1) exit_button = button.Button(WIDTH // 2 - 110, HEIGHT // 2 + 50, exit_img, 1) restart_button = button.Button(WIDTH // 2 - 100, HEIGHT // 2 - 50, restart_img, 2) #Create sprite groups enemy_group = pygame.sprite.Group() bullet_group = pygame.sprite.Group() grenade_group = pygame.sprite.Group() explosion_group = pygame.sprite.Group() item_box_group = pygame.sprite.Group() decoration_group = pygame.sprite.Group() blueprint_group = pygame.sprite.Group() water_group = pygame.sprite.Group() exit_group = pygame.sprite.Group() deadEnemy_group = pygame.sprite.Group() #Create empty tile list world_data = [] for row in range(ROWS): r = [-1] * COLS world_data.append(r) #Load in level data and create world with open(f"./level{level}_data.csv", newline="") as csvfile: reader = csv.reader(csvfile, delimiter=",") for x, row in enumerate(reader): for y, tile in enumerate(row): world_data[x][y] = int(tile) world = World() player, health_bar = world.process_data(world_data) #Game loop run = True while run: clock.tick(FPS) player.time += 1 if start_game == False: #Main menu screen.fill(BG) #Show controls draw_text("A, Left", font, WHITE, 10, 25) draw_text("D, Right", font, WHITE, 10, 50) draw_text("W, Up", font, WHITE, 10, 75) draw_text("Q, Grenades", font, WHITE, 10, 100) draw_text("SPACE, Shoot Bullets", font, WHITE, 10, 125 ) #Show level completion prerequisites draw_text("Kill all enemies", font, RED, 10, HEIGHT - 85) draw_text("Get the nazi blueprints", font, RED, 10, HEIGHT - 60) draw_text("Escape", font, RED, 10, HEIGHT - 35) #Add buttons if start_button.draw(screen): start_game = True start_intro = True if exit_button.draw(screen): run = False else: #Update background draw_bg() #Draw world map world.draw() #Add High Scores getHTime() #Show player health health_bar.draw(player.health) #Show ammo count draw_text("AMMO: ", font, WHITE, 10, 35) for x in range(player.ammo): screen.blit(bullet_img, (90 + (x * 10), 40)) #Show grenade count draw_text("GRENADES: ", font, WHITE, 10, 60) for x in range(player.grenades): screen.blit(grenade_img, (135 + (x * 15), 60)) #Show time draw_text("TIME: " + str(round(player.time / 60, 2)), font, WHITE, 10, 85) #Show Best time draw_text("BEST TIME: " + str(round(player.hTime / 60, 2)), font, WHITE, 10, 110) #Update and draw groups decoration_group.update() decoration_group.draw(screen) blueprint_group.update() blueprint_group.draw(screen) water_group.update() water_group.draw(screen) exit_group.update() exit_group.draw(screen) deadEnemy = 0 enemyCount = 0 for enemy in enemy_group: enemy.ai() enemy.update() enemy.draw() if enemy.health == 0: deadEnemy += 1 enemyCount += 1 if deadEnemy == enemyCount: levelClear = True else: levelClear = False bullet_group.update() bullet_group.draw(screen) grenade_group.update() grenade_group.draw(screen) explosion_group.update() explosion_group.draw(screen) item_box_group.update() item_box_group.draw(screen) #Update player player.update() player.draw() #Show intro if start_intro == True: if intro_fade.fade(): start_intro = False intro_fade.fade_counter = 0 #Update player actions if player.alive: #Shoot bullets if shoot: player.shoot() #Throw grenades elif grenade and grenade_thrown == False and player.grenades > 0: grenade = Grenade(player.rect.centerx + (player.rect.size[0] * 0.5 * player.direction),\ player.rect.top, player.direction) grenade_thrown = True player.grenades -= 1 grenade_group.add(grenade) if player.in_air: player.update_action(2) #2: jump elif moving_left or moving_right: player.update_action(1) #1: run else: player.update_action(0) #0: idle screen_scroll, level_complete = player.move(moving_left, moving_right) bg_scroll -= screen_scroll #Death screen else: screen_scroll = 0 if death_fade.fade(): if restart_button.draw(screen): death_fade.fade_counter = 0 start_intro = True bg_scroll = 0 world_data = reset_level() #Load in level data and create world with open(f"./level{level}_data.csv", newline="") as csvfile: reader = csv.reader(csvfile, delimiter=",") for x, row in enumerate(reader): for y, tile in enumerate(row): world_data[x][y] = int(tile) world = World() player, health_bar = world.process_data(world_data) #Move to next level if level_complete and player.goalAchieved and levelClear: start_intro = True bg_scroll = 0 rewriteHTime() world_data = reset_level() level += 1 #Load in level data and create world with open(f"./level{level}_data.csv", newline="") as csvfile: reader = csv.reader(csvfile, delimiter=",") for x, row in enumerate(reader): for y, tile in enumerate(row): world_data[x][y] = int(tile) world = World() player, health_bar = world.process_data(world_data) for Event in pygame.event.get(): if Event.type == pygame.QUIT: run = False #Keyboard presses if Event.type == pygame.KEYDOWN: if Event.key == pygame.K_a: moving_left = True if Event.key == pygame.K_d: moving_right = True if Event.key == pygame.K_w and player.alive: player.jump = True jump_fx.play() if Event.key == pygame.K_ESCAPE: run = False if Event.key == pygame.K_SPACE: shoot = True if Event.key == pygame.K_q: grenade = True #Keyboard button released if Event.type == pygame.KEYUP: if Event.key == pygame.K_a: moving_left = False if Event.key == pygame.K_d: moving_right = False if Event.key == pygame.K_SPACE: shoot = False if Event.key == pygame.K_q: grenade = False grenade_thrown = False pygame.display.update() pygame.QUIT