Beispiel #1
0
class Game:

    SPLASH = 0
    START = 1
    PLAYING = 2
    PAUSED = 3
    LEVEL_COMPLETED = 4
    GAME_OVER = 5
    VICTORY = 6

    def __init__(self):
        self.window = pygame.display.set_mode(
            [constants.WIDTH, constants.HEIGHT])
        pygame.display.set_caption(constants.TITLE)
        self.clock = pygame.time.Clock()
        self.done = False

        self.reset()

    def start(self):
        self.level = Level(constants.LEVELS[self.current_level])
        self.level.reset()
        self.hero.respawn(self.level)

    def advance(self):
        self.current_level += 1
        self.start()
        self.stage = Game.START

    def reset(self):
        self.hero = Character(hero_images)
        self.current_level = 0
        self.start()
        self.stage = Game.SPLASH

    def display_splash(self, surface):
        line1 = FONT_LG.render(constants.TITLE, True, DARK_BLUE)
        line2 = FONT_SM.render("Press any key to start.", True, WHITE)

        x1 = constants.WIDTH / 2 - line1.get_width() / 2
        y1 = constants.HEIGHT / 3 - line1.get_height() / 2

        x2 = constants.WIDTH / 2 - line2.get_width() / 2
        y2 = y1 + line1.get_height() + 16

        surface.blit(line1, (x1, y1))
        surface.blit(line2, (x2, y2))

    def display_message(self, surface, primary_text, secondary_text):
        line1 = FONT_MD.render(primary_text, 1, WHITE)
        line2 = FONT_SM.render(secondary_text, 1, WHITE)

        x1 = constants.WIDTH / 2 - line1.get_width() / 2
        y1 = constants.HEIGHT / 3 - line1.get_height() / 2

        x2 = constants.WIDTH / 2 - line2.get_width() / 2
        y2 = y1 + line1.get_height() + 16

        surface.blit(line1, (x1, y1))
        surface.blit(line2, (x2, y2))

    def display_stats(self, surface):
        hearts_text = FONT_SM.render("Hearts: " + str(self.hero.hearts), True,
                                     WHITE)
        lives_text = FONT_SM.render("Lives: " + str(self.hero.lives), True,
                                    WHITE)
        score_text = FONT_SM.render("Score: " + str(self.hero.score), True,
                                    WHITE)

        surface.blit(score_text,
                     (constants.WIDTH - score_text.get_width() - 32, 32))
        surface.blit(hearts_text, (32, 32))
        surface.blit(lives_text, (32, 64))

    def process_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.done = True

            elif event.type == pygame.KEYDOWN:
                if self.stage == Game.SPLASH or self.stage == Game.START:
                    self.stage = Game.PLAYING
                    play_music()

                elif self.stage == Game.PLAYING:
                    if event.key == JUMP:
                        self.hero.jump(self.level.blocks)

                elif self.stage == Game.PAUSED:
                    pass

                elif self.stage == Game.LEVEL_COMPLETED:
                    self.advance()

                elif self.stage == Game.VICTORY or self.stage == Game.GAME_OVER:
                    if event.key == pygame.K_r:
                        self.reset()

        pressed = pygame.key.get_pressed()

        if self.stage == Game.PLAYING:
            if pressed[LEFT]:
                self.hero.move_left()
            elif pressed[RIGHT]:
                self.hero.move_right()
            else:
                self.hero.stop()

    def update(self):
        if self.stage == Game.PLAYING:
            self.hero.update(self.level)
            self.level.enemies.update(self.level, self.hero)

        if self.level.completed:
            if self.current_level < len(constants.LEVELS) - 1:
                self.stage = Game.LEVEL_COMPLETED
            else:
                self.stage = Game.VICTORY
            pygame.mixer.music.stop()

        elif self.hero.lives == 0:
            self.stage = Game.GAME_OVER
            pygame.mixer.music.stop()

        elif self.hero.hearts == 0:
            self.level.reset()
            self.hero.respawn(self.level)

    def calculate_offset(self):
        x = -1 * self.hero.rect.centerx + constants.WIDTH / 2

        if self.hero.rect.centerx < constants.WIDTH / 2:
            x = 0
        elif self.hero.rect.centerx > self.level.width - constants.WIDTH / 2:
            x = -1 * self.level.width + constants.WIDTH

        return x, 0

    def draw(self):
        offset_x, offset_y = self.calculate_offset()

        self.level.active_layer.fill(TRANSPARENT)
        self.level.active_sprites.draw(self.level.active_layer)

        if self.hero.invincibility % 3 < 2:
            self.level.active_layer.blit(self.hero.image,
                                         [self.hero.rect.x, self.hero.rect.y])

        self.window.blit(self.level.background_layer, [offset_x / 3, offset_y])
        self.window.blit(self.level.scenery_layer, [offset_x / 2, offset_y])
        self.window.blit(self.level.inactive_layer, [offset_x, offset_y])
        self.window.blit(self.level.active_layer, [offset_x, offset_y])

        self.display_stats(self.window)

        if self.stage == Game.SPLASH:
            self.display_splash(self.window)
        elif self.stage == Game.START:
            self.display_message(self.window, "Ready?!!!",
                                 "Press any key to start.")
        elif self.stage == Game.PAUSED:
            pass
        elif self.stage == Game.LEVEL_COMPLETED:
            self.display_message(self.window, "Level Complete",
                                 "Press any key to continue.")
        elif self.stage == Game.VICTORY:
            self.display_message(self.window, "You Win!",
                                 "Press 'R' to restart.")
        elif self.stage == Game.GAME_OVER:
            self.display_message(self.window, "Game Over",
                                 "Press 'R' to restart.")

        pygame.display.flip()

    def loop(self):
        while not self.done:
            self.process_events()
            self.update()
            self.draw()
            self.clock.tick(constants.FPS)
Beispiel #2
0
class Game:
    def __init__(self):
        self.canvas = pygame.display.set_mode((960, 580))
        self.initial_position = pygame.Vector2(0, 0)
        self.hero = None
        self.current_level = 0
        self.clock = None
        self.blocks = None
        self.enemies = None
        self.running = False

        self.tiles_groups = {}
        self.tiles_images = {}

    def load_hero(self):
        # Load Character
        hero_scale = SCALE_REFERENCE["character.png"]
        idle_imgs = load_image_folder(os.path.join(CHARACTER_PATH, 'idle'),
                                      scale=hero_scale)
        base_imgs = load_image(os.path.join(CHARACTER_PATH, 'idle', '0.png'),
                               scale=hero_scale)
        attack_imgs = [
            load_image_folder(os.path.join(CHARACTER_PATH, 'attack', '1'),
                              scale=hero_scale),
            load_image_folder(os.path.join(CHARACTER_PATH, 'attack', '2'),
                              scale=hero_scale),
            load_image_folder(os.path.join(CHARACTER_PATH, 'attack', '3'),
                              scale=hero_scale)
        ]
        run_imgs = load_image_folder(os.path.join(CHARACTER_PATH, 'run'),
                                     scale=hero_scale)
        jump_imgs = load_image_folder(os.path.join(CHARACTER_PATH, 'jump'),
                                      scale=hero_scale)
        fall_imgs = load_image_folder(os.path.join(CHARACTER_PATH, 'fall'),
                                      scale=hero_scale)

        hero_images = {
            'idle': idle_imgs,
            'base': base_imgs,
            'attack': attack_imgs,
            'run': run_imgs,
            'jump': jump_imgs,
            'fall': fall_imgs
        }

        self.hero = Character(self.initial_position, hero_images)

    def load_level(self):
        # Load Map TODO will change when the levels are ready
        tiles_list = [
            p for p in os.listdir(TILES_PATH) if p != "character.png"
        ]
        self.tiles_images = {
            tile: load_image(os.path.join(TILES_PATH, tile),
                             scale=SCALE_REFERENCE[tile])
            for tile in tiles_list
        }
        self.tiles_groups = {
            tile: pygame.sprite.Group()
            for tile in tiles_list
        }
        with open(os.path.join(LEVELS_PATH, f"{self.current_level}.json"),
                  "r") as json_file:
            level_data = json.load(json_file)

        for pos in level_data:
            for tile in level_data[pos]["tiles"]:
                if tile["tile"] == "character.png":
                    self.initial_position = pygame.Vector2(
                        level_data[pos]["x"] * 64, level_data[pos]["y"] * 64)
                    continue
                pos_vec = pygame.Vector2(level_data[pos]["x"] * 64,
                                         level_data[pos]["y"] * 64)
                self.tiles_groups[tile["tile"]].add(
                    OBJECT_REFERENCE[tile["tile"]](
                        pos_vec, self.tiles_images[tile["tile"]]))

    def start(self):
        pygame.init()
        # clock - FPS
        self.clock = pygame.time.Clock()
        # mainloop
        self.running = True
        # load main menu
        self.load_level()
        self.load_hero()

    def update(self):
        while self.running:
            for event in pygame.event.get():
                if event.type == QUIT:
                    self.running = False
                elif event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        self.running = False
                    elif event.key == K_x:
                        self.hero.attack()
                    elif event.key == K_UP:
                        self.hero.jump()

            pressed = pygame.key.get_pressed()
            if pressed[K_LEFT]:
                self.hero.move(left=True)
            elif pressed[K_RIGHT]:
                self.hero.move()
            else:
                self.hero.stop_moving()

            self.canvas.fill((0, 0, 0))

            for name, group in self.tiles_groups.items():
                group.draw(self.canvas)
                for b_sprite in group.sprites():
                    b_sprite.draw_line_limit(self.canvas, color=(255, 0, 0))
                self.hero.update(self.canvas, group)
            pygame.display.flip()

            self.clock.tick(15)

        pygame.quit()

    def main(self):
        self.start()
        self.update()
Beispiel #3
0
# mainloop
running = True

while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False
            elif event.key == pygame.K_x:
                char.attack()
            elif event.key == pygame.K_z:
                char.jump()

    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_LEFT]:
        char.move(left=True)
    elif pressed[pygame.K_RIGHT]:
        char.move()
    else:
        char.stop()

    screen.fill((0, 0, 0))
    char.update(screen)
    pygame.display.flip()

    clock.tick(15)