class Game: def __init__(self, window, keys): """ Initialise the game params: window: <pyglet.window.Window> The window in which the game is being run keys: <pyglet.window.key.KeyStateHandler> Holds a dictionary of currently pressed and released keys """ self.window = window self.keys = keys self.mouse_position = Vector2D() self.keybinds = KeybindHandler(DEFAULT_KEYBINDS) self.player = Player(window, keys) self.world = World() self.controls = ControlsHandler(self.keys, self.player, self.keybinds) def save_game(self, game_folder_path: str): if not game_folder_path.endswith("/"): game_folder_path += "/" if not exists(game_folder_path): mkdir(game_folder_path) self.world.save_map(game_folder_path + "map") self.player.save_game(game_folder_path + "player") # self.keybinds.save_to_folder(game_folder_path) meta_data = "" with open(game_folder_path + "meta", "w") as meta_file: meta_file.write(meta_data) def load_game(self, game_folder_path: str): if not game_folder_path.endswith("/"): game_folder_path += "/" if not exists(game_folder_path): raise FileExistsError( f"Game save file {game_folder_path} not found") self.world.load_map(game_folder_path + "map") self.player.load_game(game_folder_path + "player") # self.keybinds.load_from_folder(game_folder_path) def on_mouse_motion(self, x, y, dx, dy): self.mouse_position = Vector2D(x, y) self.player.pos = self.mouse_position def on_mouse_press(self, x, y, button, mod): self.load_game("./saves/example") def mainloop(self, delta): self.window.clear() self.player.draw() self.player.update() self.controls.work()
class Game: # Game parameters. RESOLUTION = WIDTH, HEIGHT FPS = 60 GAME_SPEED = 4 # Background BG = pygame.image.load(os.path.join("..", "images", "bg.png")) pygame.init() pygame.display.set_caption('Flappy Bird') # Sounds JUMP_SOUND = pygame.mixer.Sound(os.path.join("..", "sounds", "jump.wav")) def __init__(self): self.run = True self.player = Player() self.board = Board(os.path.join("..", "worlds", "world.txt")) self.screen = pygame.display.set_mode(Game.RESOLUTION) self.clock = pygame.time.Clock() self.execute() def execute(self): while self.run: self.handle_events() self.ticking() self.draw() def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.run = False if event.type == pygame.KEYDOWN and (event.key == pygame.K_w or event.key == pygame.K_UP): self.player.begin_jump() Game.JUMP_SOUND.play() def ticking(self): self.clock.tick(Game.FPS) self.board.move(Game.GAME_SPEED) self.player.move() if self.player.is_off_board(): self.run = False if self.board.is_collision(self.player.get_position()): self.run = False def draw(self): self.screen.blit(Game.BG, (0, 0)) self.board.draw(self.screen) self.player.draw(self.screen) pygame.display.update()
class Game: def __init__(self): pygame.init() self.running = True self.screen = pygame.display.set_mode([1028, 720]) self.background = pygame.Surface(self.screen.get_size()) self.background.fill((255, 255, 255)) self.background = self.background.convert() self.asteroid = Asteroid() self.player = Player() self.play_time = 0 def main(self): while self.running: self.on_update() self.on_draw() def on_draw(self): self.screen.blit(self.background, (0, 0)) self.asteroid.draw(self.screen) self.player.draw(self.screen) pygame.display.flip() def on_update(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.running = False time = pygame.time.get_ticks() delta_t = (time - self.play_time) / 100 self.play_time = pygame.time.get_ticks() self.asteroid.update(delta_t) self.player.update(delta_t)
class Tilemap(): """Represents a collection of tile (sprites) that represent a map""" def __init__(self, settings, screen, map_indicies, images, block_image, exit_images, player_images, blob_images): """Initialize the map and all of its owned objects""" self.settings = settings self.screen = screen self.images = images self.indicies = map_indicies self.screen_rect = screen.get_rect() self.player_bounds_rect = pygame.Rect((0, 0), (0, 0)) self.block_image = block_image self.block_group = Group() self.x_offset = 0 self.drainrect = pygame.Rect((0, 0), (0, 0)) self.blob_exit = None self.exit_images = exit_images self.player = None self.player_images = player_images self.blob_images = blob_images self.enemies = Group() self.new_enemy_counter = 0 self.level_info = LevelInfo(self.settings, self.screen) self.level_timer = LevelTimer(self.settings, self.screen) self.bonuses = [] def reset(self): """Resets the game to the starting state""" self.player.reset() self.enemies.empty() gf.generate_new_random_blob(self.settings, self.screen, self.settings.image_res.enemy_blob_images, self) self.generate_platforms() self.blob_exit.stop_gibbing() self.level_info = LevelInfo(self.settings, self.screen) self.settings.enemy_generation_rate = self.settings.enemy_generation_base_rate self.level_timer.reset() def generate_basic_map(self, number_of_floors, number_of_subfloor_rows=0): """Builds a basic tiled map - this depends on the index ordering of the tiles image""" # Every 'floor' that is not the bottom or below contains 3 tile rows of the same pattern # So just make number_of_floors - 1 entries for those, then generate the bottom 'floor' # which just has a different 3rd row of indices. If tiles below that are needed for # looks then they all use the same pattern empty_row = [ -1, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 8, -1 ] pipe_row = [ -1, 6, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 8, -1 ] bottom_row = [-1, 6, 9, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 10, 8, -1] sub_row = [-1, 6, 7, 7, 7, 7, 8, -1, 6, 7, 7, 7, 7, 7, 8, -1] drain_col = 7 row_index = 0 new_indices = [] while row_index < (number_of_floors - 1): new_indices.extend(empty_row) new_indices.extend(pipe_row) new_indices.extend(empty_row) row_index += 1 # bottom floor - no enemy generator new_indices.extend(empty_row) new_indices.extend(empty_row) new_indices.extend(bottom_row) # optional sub-bottom floor row row_index = 0 while row_index < number_of_subfloor_rows: new_indices.extend(sub_row) row_index += 1 # Out with the old, in with the new self.indicies.clear() self.indicies.extend(new_indices) # Add the block platforms self.generate_platforms() # Calculate the rect that bounds outer movment of the player (and enemies in most cases) self.x_offset = ( self.screen_rect.width - (self.settings.map_width * self.settings.tile_width)) // 2 x_offset2 = self.x_offset + self.settings.tile_width * ( (self.settings.map_width - self.settings.map_playable_width) / 2) self.player_bounds_rect.top = 0 self.player_bounds_rect.left = x_offset2 self.player_bounds_rect.width = self.settings.map_playable_width * self.settings.tile_width self.player_bounds_rect.height = self.screen_rect.height - ( (number_of_subfloor_rows + 1) * self.settings.tile_height) # Drain collision rect self.drainrect.width = self.settings.tile_width self.drainrect.height = self.settings.tile_height self.drainrect.top = self.player_bounds_rect.bottom self.drainrect.left = self.settings.tile_width * drain_col + self.x_offset self.drainrect.inflate_ip(self.settings.tile_width * -0.99, self.settings.tile_height * -0.75) self.drainrect.move_ip(0, self.settings.tile_height * -0.5) # Create the 'exit' self.blob_exit = BlobExit(self.settings, self.screen, self.exit_images, self) # Create the player self.player = Player(self.settings, self.screen, self.player_images, self.player_bounds_rect, self) # Position the timer self.level_timer.position_frame( self.screen_rect.centery, self.player_bounds_rect.right + self.settings.tile_width * 2) def generate_block(self, x, y): """Create a new Block object at the given x,y and return it""" new_block = Block(self.settings, self.screen, self.block_image) new_block.rect.top = y new_block.rect.left = x return new_block def generate_blocks(self, bounding_rect, group, bottom_left=False, bottom_right=False): """Generates one of 4 possible block combinations""" # Always add the top 2 quadrants image_rect = self.block_image.get_rect() block_top_left = self.generate_block(bounding_rect.left, bounding_rect.top) block_top_right = self.generate_block( bounding_rect.left + image_rect.width, bounding_rect.top) group.add(block_top_left) group.add(block_top_right) # The bottom 2 are optional and random # Note these offsets work because the blocks are 1/4 the size of the tile by design if bottom_left: block_bottom_left = self.generate_block( bounding_rect.left, bounding_rect.top + image_rect.height) group.add(block_bottom_left) if bottom_right: block_bottom_right = self.generate_block( bounding_rect.left + image_rect.width, bounding_rect.top + image_rect.height) group.add(block_bottom_right) def generate_platforms(self): """Make groups of sprites that contain the blocks for the player to stand on""" # Every block is contained within the self.player_bounds_rect # Find each "row" of tiles that can contain blocks and add some # Eligible rows are every 3rd row starting from the 2nd to top, except the very bottom floor row_rect = pygame.Rect( (self.player_bounds_rect.left, self.player_bounds_rect.top + (self.settings.tile_height * 2)), (self.player_bounds_rect.width, self.settings.tile_width)) self.block_group.empty() for row in range(0, (self.settings.map_number_floors - 1)): new_group = Group() # Each column in the eligble row has 4 valid placements for a block # Note - there are more permutations, these are just the ones allowed # OO OO OO OO # XX OX OX OO for col in range(0, self.settings.map_playable_width): bounding_rect = pygame.Rect(0, 0, 0, 0) bounding_rect.top = row_rect.top bounding_rect.left = row_rect.left + col * self.settings.tile_width self.generate_blocks(bounding_rect, new_group, random.choice([True, False]), random.choice([True, False])) # Each row is its own group. This could limit collision checks later self.block_group.add(new_group.sprites()) # Shif the bounding rect down one floor row_rect = row_rect.move(0, self.settings.tile_height * 3) def update(self): """Update all owned objects (blocks, player, enemies, etc)""" if self.player.at_top: self.level_timer.stop() # Check for a reset flag set on the player object if self.player.won_level: self.player.reset() self.enemies.empty() gf.generate_new_random_blob( self.settings, self.screen, self.settings.image_res.enemy_blob_images, self) self.generate_platforms() self.blob_exit.stop_gibbing() self.level_info.increase_level() self.settings.enemy_generation_rate -= self.settings.enemy_generation_level_rate self.level_timer.reset() # Update the player self.player.update(self, self.enemies) # Check if it's time to add a new enemy to the map self.new_enemy_counter += 1 if self.new_enemy_counter >= self.settings.enemy_generation_rate: self.new_enemy_counter = 0 gf.generate_new_random_blob( self.settings, self.screen, self.settings.image_res.enemy_blob_images, self) # Update enemies that exist for enemy in self.enemies: enemy.update(self) # Update the 'exit' sprite self.blob_exit.update(self.enemies) # Update the level info self.level_info.update() # Update the level timer self.level_timer.update() # bonuses for bonus in self.bonuses: bonus.update() if not bonus.alive(): self.bonuses.remove(bonus) def draw_tiles(self, draw_grid_overlay=False): """Draws just the tile portion of the map""" # Make the bottom of the map align with the bottom of the screen number_of_rows = len(self.indicies) / self.settings.map_width map_height = number_of_rows * self.settings.tile_height y_offset = self.screen_rect.height - map_height rect = pygame.Rect( (self.x_offset, y_offset), (self.settings.tile_width, self.settings.tile_height)) tiles_draw_per_row = 0 # Loop through each row and render it, simple for now, map fits on the screen for index in self.indicies: if index >= 0: self.screen.blit(self.images[index], rect) if draw_grid_overlay: color_red = (255, 0, 0) pygame.draw.rect(self.screen, color_red, rect, 1) tiles_draw_per_row += 1 rect.left += self.settings.tile_width # Every row worth of tiles, drop down one level and reset the x coord if tiles_draw_per_row == self.settings.map_width: rect.top += self.settings.tile_height rect.left = self.x_offset tiles_draw_per_row = 0 # Draw the blocks # This works because each block has 'image' member defined self.block_group.draw(self.screen) def draw(self, draw_grid_overlay=False): """Draws the tilemap.""" # Draw the enemies - can't use the Gorup method because of our animation logic for enemy in self.enemies: enemy.draw() self.draw_tiles(draw_grid_overlay) # Draw the player self.player.draw() # Draw the exit self.blob_exit.draw() # Draw the level info self.level_info.draw() # Draw the level timer self.level_timer.draw() # Draw bonuses for bonus in self.bonuses: bonus.draw(self.screen)
class Game(object): WORLD_PATH = '../worlds/world1-1.txt' JUMP_SOUND_PATH = '../sounds/jump.wav' COIN_SOUND_PATH = '../sounds/coin.wav' MAIN_THEME_PATH = '../sounds/main-theme.mp3' VELOCITY_SCALE = 50 def __init__(self): pygame.init() pygame.display.set_caption('Mario') pygame.mixer.music.load(Game.MAIN_THEME_PATH) pygame.mixer.music.play(-1) self.screen = pygame.display.set_mode(RESOLUTION) self.tps_clock = pygame.time.Clock() self.tps_delta = 0.0 self.run = True self.player = Player() self.board = Board(Game.WORLD_PATH) self.position = Position((0, 0)) self.jumpSound = pygame.mixer.Sound(Game.JUMP_SOUND_PATH) self.coinSound = pygame.mixer.Sound(Game.COIN_SOUND_PATH) self.execute() def execute(self): while self.run: self.handle_events() self.ticking() self.draw() def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.run = False if event.type == pygame.KEYDOWN and event.key == pygame.K_UP and not self.player.get_is_jump(): self.player.begin_jump() self.jumpSound.play() def make_move(self, keys): if keys[pygame.K_RIGHT]: self.player.set_key(pygame.K_RIGHT) self.player.increase_velocity() elif keys[pygame.K_LEFT]: self.player.set_key(pygame.K_LEFT) self.player.increase_left_velocity() else: self.player.decrease_velocity() self.player.decrease_left_velocity() if self.player.get_key() == pygame.K_RIGHT: rescale_velocity = self.get_rescale_velocity() while not self.check_right(rescale_velocity): rescale_velocity -= 1 if self.player.is_start_position(): self.position.change_position(rescale_velocity, 0) else: difference = self.player.get_positions_difference() self.player.change_player_position((min(rescale_velocity, difference[0]), 0)) if rescale_velocity - difference[0] > 0: self.position.change_position(rescale_velocity - difference[0], 0) else: rescale_left_velocity = self.get_rescale_left_velocity() while not self.check_left(rescale_left_velocity): rescale_left_velocity -= 1 self.player.change_player_position((-rescale_left_velocity, 0)) self.player.increase_walk_count() def get_rescale_velocity(self): return self.player.get_velocity() // Game.VELOCITY_SCALE def get_rescale_left_velocity(self): return self.player.get_left_velocity() // Game.VELOCITY_SCALE def ticking(self): self.tps_delta += self.tps_clock.tick() / 1000.0 while self.tps_delta > 1 / TPS_MAX: keys = pygame.key.get_pressed() if not self.player.get_is_jump(): if self.check_down(): self.player.begin_jump() self.player.gain_top_jump() self.player.fall() else: self.set_player_height() self.make_move(keys) self.tps_delta -= 1 / TPS_MAX def set_player_height(self): if self.player.get_top_jump() and self.check_down(): self.player.fall() if not self.player.get_top_jump() and not self.player.is_max_jump_count(): self.player.jump() if not self.player.get_top_jump() and (self.player.is_max_jump_count() or not self.check_up()): self.player.gain_top_jump() if not self.check_up() and self.is_question_mark(): if not self.board.is_in_changed_blocks(self.get_position_question_mark()): self.coinSound.play() self.board.add_changed_block(self.get_position_question_mark()) if self.player.get_top_jump() and not self.check_down(): self.player.end_fall() def is_question_mark(self): p1 = self.player.get_top_left_corner() p2 = self.player.get_top_right_corner() return self.get_char((p1[0], p1[1] - 1)) == '?' or self.get_char((p2[0], p2[1] - 1)) == '?' def get_position_question_mark(self): p1 = self.player.get_top_left_corner() p2 = self.player.get_top_right_corner() if self.get_char((p1[0], p1[1] - 1)) == '?': return self.get_position_char((p1[0], p1[1] - 1)) else: return self.get_position_char((p2[0], p2[1] - 1)) def get_char(self, p): point = Position((p[0], p[1])) point.change_position(self.position.get_x(), self.position.get_y()) point.scale_position(ELEMENT_SIZE) return self.board.get_block(point.get_x(), point.get_y()) def get_position_char(self, p): point = Position((p[0], p[1])) point.change_position(self.position.get_x(), self.position.get_y()) point.scale_position(ELEMENT_SIZE) return point.get_x(), point.get_y() def check_up(self): p1 = self.player.get_top_right_corner() p2 = self.player.get_top_left_corner() return self.is_legal_point(p1[0], p1[1] - 1) and self.is_legal_point(p2[0], p2[1] - 1) def check_down(self): p1 = self.player.get_bottom_right_corner() p2 = self.player.get_bottom_left_corner() return self.is_legal_point(p1[0], p1[1] + 1) and self.is_legal_point(p2[0], p2[1] + 1) def check_right(self, distance): p1 = self.player.get_top_right_corner() p2 = self.player.get_bottom_right_corner() return self.is_legal_point(p1[0] + distance, p1[1]) and self.is_legal_point(p2[0] + distance, p2[1]) def check_left(self, distance): p1 = self.player.get_top_left_corner() p2 = self.player.get_bottom_left_corner() return self.is_legal_point(p1[0] - distance, p1[1]) and self.is_legal_point(p2[0] - distance, p2[1]) def is_legal_point(self, x, y): point = Position((x, y)) point.change_position(self.position.get_x(), self.position.get_y()) point.scale_position(ELEMENT_SIZE) return is_legal_block(self.board.get_block(point.get_x(), point.get_y())) def draw(self): self.screen.fill(SKY_COLOR) self.board.draw(self.screen, self.position) self.player.draw(self.screen) pygame.display.flip()
class Game(object): def __init__(self, screen, tutorialMenu, fakeNewsMenu, saveFile=None): self.isRunning = False if saveFile is None: self.map = Map("assets/maps/default.json") self.player = Player() else: self.load(saveFile) self.openMenu = "[Esc] Open Menu" self.openMenu = screen.fonts["25"].render(self.openMenu, 1, (255, 255, 255)) self.closeMenu = "[Esc] Close Menu" self.closeMenu = screen.fonts["25"].render(self.closeMenu, 1, (255, 255, 255)) self.ennemyController = EnnemyController(5) button_help = Button((700, 300), (300, 60), "How to Build Walls", tutorialMenu.run, screen=screen) button_help.build(screen) button_fakeNewsMenu = Button((1100, 300), (300, 60), "Fake News", fakeNewsMenu.run, screen=screen) button_fakeNewsMenu.build(screen) button_quit = Button((1500, 300), (300, 60), "Quit", self.stop) button_quit.build(screen) self.pauseMenu = Menu(None, [button_help, button_fakeNewsMenu, button_quit], True) self.winMenu = Menu(pygame.image.load("assets/img/youWon.jpg"), [], True) button_continue = Button((10, 1000), (300, 60), "4 Years Later >>", self.winMenu.stop) button_continue.build(screen) self.winMenu.buttons.append(button_continue) button_quit = Button((10, 1000), (300, 60), "Quit Because I'm Bad", exit) button_quit.build(screen) self.loseMenu = Menu(pygame.image.load("assets/img/youLose.jpg"), [button_quit], True) button_continue = Button((400, 1000), (300, 60), "Continue & Sue Bedin", self.loseMenu.stop) button_continue.build(screen) self.loseMenu.buttons.append(button_continue) self.invocations = [] self.twats = [] button_resume = Button((300, 300), (300, 60), "Resume", self.pauseMenu.stop) button_resume.build(screen) self.pauseMenu.buttons.append(button_resume) self.gameEndTime = cst.GAME_TIME self.ballots = { "republican": Ballot((1800, 20), "assets/img/republican.png"), "democrat": Ballot((1800, 140), "assets/img/democrat.png"), } def load(self, saveFile): """ Loads the game from a save file, creates an empty game if the save is None """ save = json.load(open(saveFile, "r")) self.map = Map(save['map']) self.player = Player(save['player']) def update(self, screen): self.gameEndTime = int(self.gameEndTime - screen.timeElapsed) if self.gameEndTime <= 0: if self.ballots["republican"].votes > self.ballots[ "democrat"].votes: self.winMenu.run(screen) else: button_info = Button((100, 800), ( 700, 60 ), f'You : {self.ballots["republican"].votes} - Bedin : {self.ballots["democrat"].votes}', exit) button_info.build(screen) button_info.clickable = False self.loseMenu.buttons.append(button_info) self.loseMenu.run(screen) self.stop() if self.player.popularity < 20: button_info = Button( (100, 800), (500, 60), f"Your popularity went below 20% ... You Bad Boy", exit) button_info.build(screen) button_info.clickable = False self.loseMenu.buttons.append(button_info) self.loseMenu.run(screen) self.stop() for event in screen.events(): action = self.player.eventUpdate(event) if action == "HIT": self.ennemyController.hit(self.player.hitbox, self.player.damage) elif action == "KAMEHAMEHA": self.ennemyController.hit(self.player.hitbox, 50) elif action == "BUILDWALL": self.invocations.append( Wall([ self.player.position[0] + 205, self.player.position[1] ])) if event.type == pygame.locals.KEYDOWN: if event.key == pygame.locals.K_ESCAPE: self.pauseMenu.run(screen, self) for inv in self.invocations[:]: result = inv.update(self.ennemyController) if result == "DEAD": del self.invocations[self.invocations.index(inv)] self.player.update(screen, self.ennemyController, self.invocations, self.twats) for twat in self.twats[:]: result = twat.update(screen) if result == "DEAD": del self.twats[self.twats.index(twat)] deaths, baddeaths, democrat_votes, republican_votes = self.ennemyController.update( screen, self.player.popularity) self.player.addSpecialAttack(deaths * 5) for baddeath in range(baddeaths): twat = Twat(screen, [random.randint(200, 1400), random.randint(30, 600)]) self.twats.append(twat) self.player.popularity -= twat.rt * 0.1 self.player.updatePopularity(screen) self.player.popularity += deaths * 0.2 self.player.updatePopularity(screen) for key, ballot in self.ballots.items(): if key == "democrat": ballot.add_votes(democrat_votes) elif key == "republican": ballot.add_votes(republican_votes) ballot.update(screen) def draw(self, screen): self.map.draw(screen, self.player) self.ennemyController.draw(screen) for inv in self.invocations: inv.draw(screen) self.player.draw(screen) for twat in self.twats: twat.draw(screen) for key, ballot in self.ballots.items(): ballot.draw(screen) def stop(self): self.isRunning = False self.pauseMenu.stop() def getTimeDisplay(self): return str(datetime.timedelta(seconds=self.gameEndTime)) def run(self, screen): self.isRunning = True while self.isRunning: self.update(screen) self.draw(screen) screen.blit(self.openMenu, (10, 10)) self.gameEndTimeDisplay = screen.fonts["75"].render( self.getTimeDisplay(), 0, (255, 255, 255)) screen.blit(self.gameEndTimeDisplay, (10, 30)) screen.flip()
class Tilemap(): """Representa uma coleção de blocos (sprites) que representam um mapa""" def __init__(self, settings, screen, map_indicies, images, block_image, box_image, exit_images, player_images, blob_images): """Inicialize o mapa e todos os seus objetos de propriedade""" self.settings = settings self.screen = screen self.images = images self.indicies = map_indicies self.screen_rect = screen.get_rect() self.player_bounds_rect = pygame.Rect((0, 0), (0, 0)) self.block_image = block_image self.block_group = Group() self.box_image = box_image self.x_offset = 0 self.drainrect = pygame.Rect((0, 0), (0, 0)) # self.blob_exit - > Vilões do jogo, todos métodos relacionados estão comentados # self.blob_exit = None self.exit_images = exit_images self.player = None self.player_images = player_images # self.blob_images = blob_images self.enemies = Group() self.new_enemy_counter = 0 self.level_info = LevelInfo(self.settings, self.screen) self.level_timer = LevelTimer(self.settings, self.screen) self.bonuses = [] def reset(self): """Reinicia o jogo ao estado inicial""" self.player.reset() self.enemies.empty() # gf.generate_new_random_blob(self.settings, self.screen, self.settings.image_res.enemy_blob_images, self) self.generate_platforms() # self.blob_exit.stop_gibbing() self.level_info = LevelInfo(self.settings, self.screen) self.settings.enemy_generation_rate = self.settings.enemy_generation_base_rate # self.level_timer.reset() def generate_basic_map(self, number_of_floors, number_of_subfloor_rows=0): """Constrói um mapa de blocos básico - isso depende da ordem do índice da imagem dos blocos""" # Cada 'piso' que não seja o fundo ou abaixo contém 3 filas de ladrilhos do mesmo padrão # Portanto, basta fazer number_of_floors - 1 entradas para aqueles, em seguida, gerar o 'andar' inferior # que tem apenas uma 3ª linha de índices diferente. Se os blocos abaixo deles forem necessários para # parece que todos usam o mesmo padrão #region ALTERADO Cada código se refere a uma posição da imagem e cada coluna referencia a coluna no layout do jogo empty_row = [ -1, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 8, -1 ] pipe_row = [-1, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 8, -1] bottom_row = [-1, 6, 9, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 10, 8, -1] sub_row = [-1, 6, 9, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 10, 8, -1] drain_col = 8 #endregion row_index = 0 new_indices = [] while row_index < (number_of_floors - 1): new_indices.extend(empty_row) new_indices.extend(pipe_row) new_indices.extend(empty_row) row_index += 1 #piso inferior - sem gerador inimigo new_indices.extend(empty_row) new_indices.extend(empty_row) new_indices.extend(bottom_row) # linha opcional do piso inferior row_index = 0 while row_index < number_of_subfloor_rows: new_indices.extend(sub_row) row_index += 1 # Fora com o velho, com o novo self.indicies.clear() self.indicies.extend(new_indices) # Adicione as plataformas de bloco # self.generate_platforms() #Calcule o retângulo que limita o movimento externo do jogador (e inimigos na maioria dos casos) self.x_offset = ( self.screen_rect.width - (self.settings.map_width * self.settings.tile_width)) // 2 x_offset2 = self.x_offset + self.settings.tile_width * ( (self.settings.map_width - self.settings.map_playable_width) / 2) self.player_bounds_rect.top = 0 self.player_bounds_rect.left = x_offset2 self.player_bounds_rect.width = self.settings.map_playable_width * self.settings.tile_width self.player_bounds_rect.height = self.screen_rect.height - ( (number_of_subfloor_rows + 1) * self.settings.tile_height) # Drenar colisão rect self.drainrect.width = self.settings.tile_width self.drainrect.height = self.settings.tile_height self.drainrect.top = self.player_bounds_rect.bottom self.drainrect.left = self.settings.tile_width * drain_col + self.x_offset self.drainrect.inflate_ip(self.settings.tile_width * -0.99, self.settings.tile_height * -0.75) self.drainrect.move_ip(0, self.settings.tile_height * -0.5) # Crie a 'saída' # self.blob_exit = BlobExit(self.settings, self.screen, self.exit_images, self) # Crie o jogador self.player = Player(self.settings, self.screen, self.player_images, self.player_bounds_rect, self) # Position the timer self.level_timer.position_frame( self.screen_rect.centery, self.player_bounds_rect.right + self.settings.tile_width * 2) def generate_block(self, x, y): """Crie um novo objeto Bloco no x, y fornecido e retorne-o""" new_block = Block(self.settings, self.screen, self.block_image) new_block.rect.top = y new_block.rect.left = x return new_block def generate_blocks(self, bounding_rect, group, bottom_left=False, bottom_right=False): """Gera uma de 4 combinações de blocos possíveis""" # Always add all the 4 quadrants image_rect = self.block_image.get_rect() block_top_left = self.generate_block(bounding_rect.left, bounding_rect.top) block_top_right = self.generate_block( bounding_rect.left + image_rect.width, bounding_rect.top) block_bottom_left = self.generate_block( bounding_rect.left, bounding_rect.top + image_rect.height) block_bottom_right = self.generate_block( bounding_rect.left + image_rect.width, bounding_rect.top + image_rect.height) group.add(block_top_left) group.add(block_top_right) group.add(block_bottom_left) group.add(block_bottom_right) def generate_box(self, x, y): """Crie um novo objeto de caixa no dado x, y e retorne-o""" new_box = Box(self.settings, self.screen, self.box_image) new_box.rect.top = y new_box.rect.left = x return new_box def generate_boxes(self, bounding_rect, group, bottom_left=False, bottom_right=False): """Gera uma das 8 combinações de caixa possíveis""" # Always add all the 4 quadrants image_rect = self.box_image.get_rect() box_top_left = self.generate_box(bounding_rect.left, bounding_rect.top) group.add(box_top_left) def generate_platforms(self): """Faça grupos de sprites que contenham os blocos para o jogador se apoiar""" # Cada bloco está contido no self.player_bounds_rect # Encontre cada "linha" de ladrilhos que pode conter blocos e adicione alguns # As linhas elegíveis são a cada 3ª linha, começando da 2ª ao topo, exceto o piso inferior row_rect = pygame.Rect( (self.player_bounds_rect.left, self.player_bounds_rect.top + (self.settings.tile_height * 2)), (self.player_bounds_rect.width, self.settings.tile_width)) self.block_group.empty() for row in range(0, (self.settings.map_number_floors - 1)): new_group = Group() # Cada coluna na linha elegível tem 4 canais válidos para um bloco # Nota - existem mais permutações, estas são apenas as permitidas # OO OO OO OO # XX OX OX OO for col in range( 1, 9 ): # ALTERADO O DE range(0, self.settings.map_playable_width) bounding_rect = pygame.Rect(0, 0, 0, 0) bounding_rect.top = row_rect.top bounding_rect.left = row_rect.left + col * self.settings.tile_width self.generate_blocks(bounding_rect, new_group, random.choice([True, False]), random.choice([True, False])) # Método criado para colocar as caixas na tela for col in range(0, 6, 5): bounding_rect = pygame.Rect(0, 0, 0, 0) bounding_rect.top = row_rect.top - 24 # -24 pois são dois blocos à frente bounding_rect.left = (row_rect.left + col * self.settings.tile_width ) + 48 # +48 pois são dois blocos acima self.generate_boxes(bounding_rect, new_group, random.choice([True, False]), random.choice([True, False])) #Cada linha é seu próprio grupo. Isso pode limitar as verificações de colisão mais tarde self.block_group.add(new_group.sprites()) #Desloque o retângulo de limite para baixo row_rect = row_rect.move(0, self.settings.tile_height * 6) # ALTERADA A tile_height DE 3 PARA 6 def update(self): """Atualize todos os objetos de sua propriedade (blocos, jogador, inimigos, etc)""" # if self.player.at_top: # self.level_timer.stop() #Verifique se há um sinalizador de reinicialização definido no objeto do jogador if self.player.won_level: self.player.reset() self.enemies.empty() # gf.generate_new_random_blob(self.settings, self.screen, self.settings.image_res.enemy_blob_images, self) self.generate_platforms() # self.blob_exit.stop_gibbing() self.level_info.increase_level() self.settings.enemy_generation_rate -= self.settings.enemy_generation_level_rate # self.level_timer.reset() # Atualize o jogador self.player.update(self, self.enemies) # Verifique se é hora de adicionar um novo inimigo ao mapa if self.settings.rodada > 2: self.new_enemy_counter += self.settings.rodada elif (self.settings.rodada > 1): self.new_enemy_counter = self.settings.rodada if self.new_enemy_counter >= self.settings.enemy_generation_rate: self.new_enemy_counter = 0 gf.generate_new_random_blob( self.settings, self.screen, self.settings.image_res.enemy_blob_images, self) # Atualize os inimigos existentes for enemy in self.enemies: enemy.update(self) # Atualize o sprite de 'saída' # self.blob_exit.update (self.enemies) # Atualize as informações do nível self.level_info.update() # Atualize o cronômetro de nível # self.level_timer.update () # bonuses for bonus in self.bonuses: bonus.update() if not bonus.alive(): self.bonuses.remove(bonus) def draw_tiles(self, draw_grid_overlay=False): """Desenha apenas a parte do bloco do mapa""" # Alinhe a parte inferior do mapa com a parte inferior da tela number_of_rows = len(self.indicies) / self.settings.map_width map_height = number_of_rows * self.settings.tile_height y_offset = self.screen_rect.height - map_height rect = pygame.Rect( (self.x_offset, y_offset), (self.settings.tile_width, self.settings.tile_height)) tiles_draw_per_row = 0 #Loop através de cada linha e renderizá-lo, simples por enquanto, o mapa se encaixa na tela for index in self.indicies: if index >= 0: self.screen.blit(self.images[index], rect) if draw_grid_overlay: color_red = (255, 0, 0) pygame.draw.rect(self.screen, color_red, rect, 1) tiles_draw_per_row += 1 rect.left += self.settings.tile_width # Cada linha de ladrilhos, desça um nível e redefina a coordenação x if tiles_draw_per_row == self.settings.map_width: rect.top += self.settings.tile_height rect.left = self.x_offset tiles_draw_per_row = 0 #Desenhe os blocos # Isso funciona porque cada bloco tem um membro 'imagem' definido self.block_group.draw(self.screen) def draw(self, draw_grid_overlay=False): "" "Desenha o mapa de blocos." "" # Desenhe os inimigos - não posso usar o método Gorup por causa de nossa lógica de animação for enemy in self.enemies: enemy.draw() self.draw_tiles(draw_grid_overlay) #Desenhe o jogador self.player.draw() # Desenhe a saída # self.blob_exit.draw () # Desenhe as informações do nível self.level_info.draw() # Draw the level timer # self.level_timer.draw() # Sorteio de bônus for bonus in self.bonuses: bonus.draw(self.screen)