import pygame, sys #from Folder.ClassName import ClassName from WorldData.World1 import World1 from WorldData.World2 import World2 from WorldData.World3 import World3 from WorldData.World4 import World4 from WorldData.World5 import World5 from WorldData.WorldManager import WorldManager from scoreboard import Scoreboard from timer import Timer pygame.init() clock = pygame.time.Clock() screen_width = 1000 screen_height = 800 tiles = 50 scoreboard = Scoreboard() # Set title for game pygame.display.set_caption('Platformer') screen = pygame.display.set_mode((screen_width, screen_height)) #images and background stuff background = pygame.image.load('img2/background1.png') exit_button_img = pygame.image.load('img2/EXIT.png') play_button_img = pygame.image.load('img2/PLAY.png') background = pygame.transform.scale(background, (1000, 800)) #game variables game_on = 0 game_over = 0 #region: Button Classes class Exit_Button(pygame.sprite.Sprite): def __init__(self, image, x, y): original_image = pygame.image.load super().__init__() self.image = image self.rect = self.image.get_rect() self.rect.topleft = (x, y) class Play_Button(pygame.sprite.Sprite): def __init__(self, image, x, y): original_image = pygame.image.load super().__init__() self.image = image self.rect = self.image.get_rect() self.rect.topleft = (x, y) def update(self): if self.rect.collidepoint(pygame.mouse.get_pos): self.image = pygame.transform.scale(self.image) #endregion: Button Classes #region: World class class World(): def __init__(self,data): self.tile_list = [] #load blocks grass_block = pygame.image.load('img2/grazz.png') stone_block = pygame.image.load('img2/get_stoned.png') door = pygame.image.load('img2/door.png') spikes = pygame.image.load('img2/spikes.png') key = pygame.image.load('img2/key.png') row_count = 0 for row in data: col_count = 0 for tile in row: # Grass Block Tile : 1 if tile == 1: img = pygame.transform.scale(grass_block, (tiles, tiles)) img_rect = img.get_rect() img_rect.x = col_count * tiles img_rect.y = row_count * tiles tile = ImageTile(img, img_rect, 1) self.tile_list.append(tile) # Stone Block Tile : 2 if tile == 2: img = pygame.transform.scale(stone_block, (tiles, tiles)) img_rect = img.get_rect() img_rect.x = col_count * tiles img_rect.y = row_count * tiles tile = ImageTile(img, img_rect, 2) self.tile_list.append(tile) # Spike Block Tile : 3 if tile == 3: img = pygame.transform.scale(spikes, (tiles, tiles)) img_rect = img.get_rect() img_rect.x = col_count * tiles img_rect.y = row_count * tiles tile = ImageTile(img, img_rect, 3) self.tile_list.append(tile) # Door Block Tile : 4 if tile == 4: img = pygame.transform.scale(door, (tiles, tiles)) img_rect = img.get_rect() img_rect.x = col_count * tiles img_rect.y = row_count * tiles tile = ImageTile(img, img_rect, 4) self.tile_list.append(tile) # Key Block Tile : 5 if tile == 5: img = pygame.transform.scale(key, (tiles, tiles)) img_rect = img.get_rect() img_rect.x = col_count * tiles img_rect.y = row_count * tiles tile = ImageTile(img, img_rect, 5) self.tile_list.append(tile) col_count += 1 row_count += 1 # World Draw Function def Draw(self): for tile in self.tile_list: screen.blit(tile.getImage(), tile.getRect()) # Function to remove a key from the world space def RemoveKey(self, keyRect:pygame.Rect): for tile in self.tile_list: if tile.getRect() == keyRect: self.tile_list.remove(tile) #endregion: World class #region: ImageTile class class ImageTile(): def __init__(self, image:pygame.Surface, rect:pygame.Rect, tileType:int): self.image = image self.rect = rect self.tileType = tileType def getImage(self): return self.image def getRect(self): return self.rect #endregion: ImageTile class #region: Player Class class Player(pygame.sprite.Sprite): def __init__(self,x, y, world:World, world_manager:WorldManager): super().__init__() self.standing_img = pygame.image.load('img2/player1.png') # Image when player is moving left self.move_left_img = pygame.image.load('img2/player_left.png') # Image when player is moving right self.move_right_img = pygame.image.load('img2/player_right.png') self.image = self.standing_img self.image = pygame.transform.scale(self.image, (40, 40)) self.rect = self.image.get_rect() self.world = world self.world_manager = world_manager self.on_ground = False self.xvel = 0 self.yvel = 0 self.start_coords() self.is_dead = False def start_coords(self): #Get width and height of the screen screen_w, screen_h = pygame.display.get_surface().get_size() player_h = self.rect.height player_w = self.rect.width ypos = screen_h - player_h xpos = 0 ypos -= screen_h / 16 self.rect.topleft = (xpos, ypos) def get_position(self): return (self.rect.x, self.rect.y) def update(self): has_changed_img = False self.reached_exit = False #get keypresses key = pygame.key.get_pressed() self.xvel = 0 if key[pygame.K_LEFT]: self.image_direction_change("left") has_changed_img = True self.xvel = -5 if key[pygame.K_RIGHT]: self.image_direction_change("right") has_changed_img = True self.xvel = 5 if self.on_ground: if key[pygame.K_SPACE]: self.image_direction_change("up") has_changed_img = True self.yvel = -15 self.on_ground = False else: self.yvel += 1 #Collision Checking #Checks if there is a collison on the left or right side of the player self.rect.left += self.xvel self.checkCollision(self.xvel, 0 ,self.world.tile_list) if self.reached_exit: return self.on_ground = False #Checks if there is a collison on the top or bottom side of the player self.rect.top += self.yvel self.checkCollision(0, self.yvel, self.world.tile_list) self.rect.clamp_ip(pygame.display.get_surface().get_rect()) if has_changed_img == False: if self.on_ground == True: self.image_direction_change("stand") else: self.image_direction_change("falling") if self.rect.bottom > screen_height: self.rect.bottom = screen_height self.on_ground = True # Move the player position based on direction parameter def image_direction_change(self, direction:str): # Get the current pos of the player cur_xpos = self.rect.x cur_ypos = self.rect.y # Set the player's image based on the direction if direction == "stand": self.image = self.standing_img elif direction == "left": self.image = self.move_left_img elif direction == "right": self.image = self.move_right_img #elif direction == "up": #elif direction == "falling": self.image = pygame.transform.scale(self.image, (40, 40)) self.rect = self.image.get_rect() # Set the players poition self.rect.topleft = (cur_xpos, cur_ypos) #Collision function def checkCollision(self, xvel, yvel, tiles:list): for tile in tiles: if self.rect.colliderect(tile.getRect()): if tile.tileType == 3: self.is_dead = True return if tile.tileType == 4: self.world_manager.NextWorld() self.reached_exit = True if xvel > 0: self.rect.right = tile.getRect().left if xvel < 0: self.rect.left = tile.getRect().right if yvel > 0: self.rect.bottom = tile.getRect().top self.on_ground = True self.yvel = 0 if yvel < 0: self.rect.top = tile.getRect().bottom self.yvel = 0 #endregion: Player Class #Key Manager Class for managing keys on a world class KeyManager(): def __init__(self): self.key_locations = [] self.key_count = 0 def AddKey(self, key): self.key_locations.append(key) self.key_count += 1 def GetKey(self, index): return self.key_locations[index] def GetKeys(self): return self.key_locations def RemoveKey(self, index) -> bool: self.key_locations.pop(index) return True def RemoveKey(self, key:pygame.Rect) -> bool: self.key_locations.remove(key) return True def FlushKeys(self): self.key_locations.clear() self.key_count = 0 def KeysRemaining(self): return len(self.key_locations) def AddFromWorld(self, world:World): if len(self.key_locations) > 0: self.FlushKeys() for tile in world.tile_list: if tile.tileType == 5: self.AddKey(tile.getRect()) def GetKeyCount(self): return self.key_count #Get width and height of the screen w, h = pygame.display.get_surface().get_size() play_button = Play_Button(play_button_img,400, 450) exit_button = Exit_Button(exit_button_img,453, 650) # Set the position of the play button to the center of the screen play_rect = play_button.image.get_rect() play_center = play_rect.width/2 play_button.rect.topleft = (w/2 - play_center, h/2 - 150) # Set the position of the exit button to the center of the screen exit_rect = exit_button.image.get_rect() exit_center = exit_rect.width/2 exit_button.rect.topleft = (w/2 - exit_center, h/2 + 50) # Create a sprite group for the buttons button_group = pygame.sprite.Group() button_group.add(exit_button) button_group.add(play_button) #Load World Data world_manager = WorldManager() world_manager.AddWorld(World1.GetData()) world_manager.AddWorld(World2.GetData()) world_manager.AddWorld(World3.GetData()) world_manager.AddWorld(World4.GetData()) world_manager.AddWorld(World5.GetData()) current_world = World(world_manager.GetWorld(0)) key_manager = KeyManager() key_manager.AddFromWorld(current_world) player = Player(200, 100, current_world, world_manager) player_group = pygame.sprite.Group() player_group.add(player) run = True current_shown_world = world_manager.GetWorldNumber() SCORE = 0 timer = Timer() while run == True: screen.blit(background, (0, 0)) #region: Menus if game_on == 0: #region: Game Over if game_over == 1: text = pygame.font.Font(None, 80).render("Game Over", True, (255, 0, 0)) deaths = pygame.font.Font(None, 50).render(scoreboard.tostring() + " | Time: " + timer.elapsed_time(), True, (255, 0, 0)) text_rect = text.get_rect(center=(screen_width/2, (screen_height/2)/4)) deaths_rect = deaths.get_rect(center=(screen_width/2, (screen_height/2)/4 + 85)) screen.blit(text, text_rect) screen.blit(deaths, deaths_rect) key_manager.FlushKeys() #endregion: Game Over #region: Game Win if game_over == 2: text = pygame.font.Font(None, 80).render("You Win!", True, (255, 0, 0)) deaths = pygame.font.Font(None, 50).render(scoreboard.tostring() + " | Time: " + timer.elapsed_time(), True, (255, 0, 0)) text_rect = text.get_rect(center=(screen_width/2, (screen_height/2)/4)) deaths_rect = deaths.get_rect(center=(screen_width/2, (screen_height/2)/4 + 85)) screen.blit(text, text_rect) screen.blit(deaths, deaths_rect) current_world = World(world_manager.SetWorld(0)) key_manager.AddFromWorld(current_world) #endregion: Game Win button_group.draw(screen) #endregion: Menus #region: Playing Game if game_on == 1: timer.start() #region: Player Death if player.is_dead: game_over = 1 game_on = 0 player.is_dead = False scoreboard.AddDeath() timer.stop() #print(timer.elapsed_time()) current_world = World(world_manager.GetWorld(0)) world_manager.SetWorld(0) player = Player(200, 100, current_world, world_manager) player_group.empty() player_group.add(player) continue #endregion: Player Death #region: Player Key Check #Check if player has reached a key player_pos = player.get_position() #print("Player Position:"+(str)(player_pos) + " | Keys Remaining: " + (str)(key_manager.KeysRemaining())) for key in key_manager.GetKeys(): if player.rect.colliderect(pygame.rect.Rect.inflate(key, 30, 30)): key_manager.RemoveKey(key) current_world.RemoveKey(key) #endregion: Player Key Check #region: World Change # Check if the current world has changed if current_shown_world != world_manager.GetWorldNumber(): if(key_manager.KeysRemaining() > 0): world_manager.PreviousWorld() else: if(world_manager.ReachedEnd()): timer.stop() game_on = 0 game_over = 2 scoreboard.file_update() continue current_world = World(world_manager.GetWorld(world_manager.GetWorldNumber())) key_manager.AddFromWorld(current_world) current_shown_world = world_manager.GetWorldNumber() player = Player(200, 100, current_world, world_manager) player_group.empty() player_group.add(player) #endregion: World Change # Text For displaying the scoreboard text = pygame.font.Font(None, 40).render(scoreboard.tostring() + " | Time: " + timer.elapsed_time(), True, (255, 0, 0)) screen.blit(text, (10, 10)) current_world.Draw() player_group.draw(screen) player.update() #endregion: Playing Game #region: Menu + Exit Check for event in pygame.event.get(): if event.type == pygame.MOUSEBUTTONDOWN: if play_button.rect.collidepoint(pygame.mouse.get_pos()): game_on = 1 game_over = 0 if event.type == pygame.QUIT: scoreboard.file_update() run = False if event.type == pygame.MOUSEBUTTONDOWN: if exit_button.rect.collidepoint(pygame.mouse.get_pos()): scoreboard.file_update() run = False #endregion: Menu + Exit Check pygame.display.update() clock.tick(70) pygame.quit() sys.exit()