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()
Exemple #2
0
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()
Exemple #3
0
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)
Exemple #4
0
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)
Exemple #5
0
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()
Exemple #7
0
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)