Exemplo n.º 1
0
    def update(self):

        self.scr.fill(self.bg)

        self.vwsx = self.player.vx
        self.vwsy = self.player.vy

        self.wsx += self.vwsx
        self.wsy += self.vwsy

        self.entitylist = [self.player] + [e for e in self.enemyC.opponentlist]

        if self.main.holdingSpace:
            self.player.shoot({
                "dad": self.player,
                "color": (0, 250, 100),
                "colorindex": (0, 100, 50),
                "angle": self.player.rotation,
                "radius": 2,
                "speed": 16,
                "damage": 1.5,
                "lifetime": 90,
                "pos": self.player.pos,
            })

        self.player.update()
        self.enemyC.update()
        self.effectC.update()
        self.projectile.udpate()

        self.shiftworld()

        Stars.update(self)

        self.s1.update()
Exemplo n.º 2
0
    def update(self):

        self.scr.fill(self.bg)

        self.vwsx = self.player.vx
        self.vwsy = self.player.vy

        self.wsx += self.vwsx
        self.wsy += self.vwsy

        self.entitylist = [self.player] + [e for e in self.enemyC.opponentlist]

        if self.main.holdingSpace:
            self.player.shoot(
                {
                    "dad": self.player,
                    "color": (0, 250, 100),
                    "colorindex": (0, 100, 50),
                    "angle": self.player.rotation,
                    "radius": 2,
                    "speed": 16,
                    "damage": 1.5,
                    "lifetime": 90,
                    "pos": self.player.pos,
                }
            )

        self.player.update()
        self.enemyC.update()
        self.effectC.update()
        self.projectile.udpate()

        self.shiftworld()

        Stars.update(self)

        self.s1.update()
Exemplo n.º 3
0
class SpaceRacer():
    """Represents the game itself"""
    def __init__(self):
        """Creates all game objects needed, loads resources, initializes
        pygame library and sound mixer, sets display mode, etc."""
        self.state = STATE_TITLE
        pygame.mixer.pre_init(buffer=SOUND_BUFFER)
        pygame.init()
        self.clock = Clock()
        self.scr = pygame.display.set_mode(SCREEN_SIZE, VID_MODE_FLAGS)
        pygame.display.set_caption(WINDOW_CAPTION)
        pygame.mouse.set_visible(False)
        LoadingScreen(self.scr).draw()
        sound_box.init()

        self.level = GameLevel()
        self.stats = GameStats(self.scr)
        self.view_pt = ViewPoint(self.scr)
        self.stars = Stars(self.scr, self.view_pt)
        self.track = Track(self.scr, self.view_pt)
        self.explosions = Explosions(self.scr, self.view_pt)
        self.ship = Ship(self.scr, self.view_pt, self.explosions)
        self.asteroids = Asteroids(self.scr, self.view_pt, self.explosions,
                                   self.track)
        self.title_screen = TitleScreen(self.scr, self.view_pt, self.stars)
        self.level_start_screen = LevelStartScreen(self.scr)
        self.level_complete_effect = LevelCompleteEffect(self.scr)
        self.game_over_effect = GameOverEffect(self.scr)
        self.pause_screen = PauseScreen(self.scr)
        self.ending_screen = EndingScreen(self.scr)

        self._init_title()

    def run(self):
        """The only public method just runs the game. It starts infinite
        loop where game objects are updated, drawn and interacts with
        each other. Also system events are processed."""
        while True:
            self.clock.tick(FRAMERATE)
            # print(f"FPS: {round(self.clock.get_fps(), 2)}")
            self._process_events()
            self._update_objects()
            self._interact_objects()
            self._draw_objects()

    def _init_title(self):
        self.state = STATE_TITLE
        self.stats.reset()
        self.level.restart()
        self.title_screen.restart()
        self.title_screen.play_music()

    def _init_level_starting(self):
        self.state = STATE_LEVEL_STARTING
        self.level_start_screen.set_level_number(self.level.get_level())
        self.level_start_screen.set_subtitle_text(self.level.get_description())
        self.level_start_screen.restart()

    def _init_level_playing(self):
        self.state = STATE_LEVEL_PLAYING
        self.level.play_music()
        self.view_pt.reset()
        self.stars.respawn()
        self.track.set_tile_map(self.level.get_map())

        top_limit = (self.track.get_track_height() -
                     self.scr.get_rect().height / 2)
        bottom_limit = self.scr.get_rect().height / 2
        self.view_pt.set_limits(top=top_limit, bottom=bottom_limit)

        self.explosions.items.empty()
        self.asteroids.set_spawn_density(self.level.get_asteroids_density())
        self.asteroids.respawn(self.level.get_asteroid_spawns())

        self.ship.set_speed(self.level.get_ship_speed())
        self.ship.set_acceleration(self.level.get_ship_acceleration())
        self.ship.restore((0, 0), reset_control=True)

    def _init_level_finishing(self):
        self.state = STATE_LEVEL_FINISHING
        self.stats.increase_score(LEVEL_COMPLETE_PTS)
        self.level_complete_effect.restart()
        self.ship.set_autopilot()
        pygame.mixer.music.fadeout(MUSIC_FADEOUT)

    def _init_game_over(self):
        self.state = STATE_GAME_OVER
        self.game_over_effect.restart()
        pygame.mixer.music.fadeout(MUSIC_FADEOUT)

    def _init_ending(self):
        self.state = STATE_ENDING
        self.ending_screen.set_score(self.stats.score)
        self.ending_screen.restart()
        self.ending_screen.play_music()

    def _init_pause(self):
        self.state = STATE_PAUSE
        self.pause_screen.refresh_background()
        pygame.mixer.music.pause()

    def _ship_control(self, key, control_status):
        """Returns True if the key was a ship direction control key."""
        key_processed = True

        if key == pygame.K_UP:
            self.ship.moving_up = control_status
        elif key == pygame.K_DOWN:
            self.ship.moving_down = control_status
        elif key == pygame.K_LEFT:
            self.ship.moving_left = control_status
        elif key == pygame.K_RIGHT:
            self.ship.moving_right = control_status
        elif key == pygame.K_SPACE:
            self.ship.shooting = control_status
        else:
            key_processed = False

        return key_processed

    def _process_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

            if self.state == STATE_TITLE:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        sys.exit()
                    elif event.key == pygame.K_RETURN:
                        pygame.mixer.music.fadeout(MUSIC_FADEOUT)
                        self._init_level_starting()

            elif self.state == STATE_PAUSE:
                if event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_ESCAPE, pygame.K_PAUSE):
                        self.state = STATE_LEVEL_PLAYING
                        pygame.mixer.music.unpause()
                    elif event.key == pygame.K_RETURN:
                        sys.exit()

            elif self.state == STATE_LEVEL_PLAYING:
                if event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_ESCAPE, pygame.K_PAUSE):
                        self._init_pause()
                    else:
                        self._ship_control(event.key, control_status=True)
                elif event.type == pygame.KEYUP:
                    self._ship_control(event.key, control_status=False)

            if self.state == STATE_ENDING:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        sys.exit()
                    elif event.key == pygame.K_RETURN:
                        self._init_title()

    def _update_objects(self):
        if self.state == STATE_TITLE:
            self.title_screen.update()

        if self.state == STATE_LEVEL_STARTING:
            self.level_start_screen.update()

        if self.state in (STATE_LEVEL_PLAYING, STATE_LEVEL_FINISHING,
                          STATE_GAME_OVER):
            self.view_pt.update()
            self.stars.update()
            self.track.update()
            self.asteroids.update()
            self.ship.update()
            self.explosions.update()

        if self.state == STATE_LEVEL_FINISHING:
            self.level_complete_effect.update()

        if self.state == STATE_GAME_OVER:
            self.game_over_effect.update()

        if self.state == STATE_ENDING:
            self.ending_screen.update()

    def _crossed_finish_line(self):
        finish_line_y = (self.track.get_track_height() -
                         self.scr.get_rect().height / 2)
        return self.ship.y > finish_line_y

    def _interact_objects(self):
        if self.state == STATE_LEVEL_STARTING:
            if self.level_start_screen.finished():
                self._init_level_playing()

        elif self.state == STATE_LEVEL_PLAYING:
            if self.stats.game_over():
                self._init_game_over()
            elif self._crossed_finish_line():
                self._init_level_finishing()
            elif self.ship.status == SHIP_STATUS_NORMAL:
                self._check_collisions()
            elif self.ship.status == SHIP_STATUS_INACTIVE:
                self._ship_restore()

        elif self.state == STATE_LEVEL_FINISHING:
            if self.level_complete_effect.finished():
                if self.level.last_level():
                    self._init_ending()
                else:
                    self.level.next_level()
                    self._init_level_starting()

        elif self.state == STATE_GAME_OVER:
            if self.game_over_effect.finished():
                self._init_title()

    def _draw_objects(self):
        if self.state == STATE_TITLE:
            self.title_screen.draw()

        if self.state == STATE_PAUSE:
            self.pause_screen.draw()

        if self.state == STATE_LEVEL_STARTING:
            self.level_start_screen.draw()

        if self.state in (STATE_LEVEL_PLAYING, STATE_LEVEL_FINISHING,
                          STATE_GAME_OVER):

            self.scr.blit(self.level.get_background(), (0, 0))
            self.stars.draw()
            self.track.draw()
            self.asteroids.draw()
            self.ship.draw()
            self.explosions.draw()
            self.stats.draw()

        if self.state == STATE_LEVEL_FINISHING:
            self.level_complete_effect.draw()

        if self.state == STATE_GAME_OVER:
            self.game_over_effect.draw()

        if self.state == STATE_ENDING:
            self.ending_screen.draw()

        pygame.display.flip()

    def _ship_explode(self, collide_point=None):
        """collide_point is a tuple of absolute coordinates: (x, y)"""
        self.stats.lost_life()
        self.ship.explode(collide_point)

    def _ship_restore(self):
        restore_x, restore_y = self.ship.get_center()
        borders = self.track.get_track_borders(restore_y)
        if borders:
            restore_x = mean(borders)
        if self.ship.restore((restore_x, restore_y)):
            self.asteroids.explode_nearest(self.ship.get_center())

    def _check_ship_penalty(self):
        borders = self.track.get_track_borders(self.ship.get_center()[1])
        if borders:
            left = self.ship.x
            right = left + self.ship.rect.width
            if right < borders[0] or left > borders[1]:
                self._ship_explode()
                return True
        return False

    def _check_collisions(self):
        collide_point = self.track.collidemask(self.ship.mask, self.ship.rect)
        if collide_point:
            self._ship_explode(collide_point)
            return True

        collide_point = self.asteroids.collidemask(self.ship.mask,
                                                   self.ship.rect,
                                                   explode=True)
        if collide_point:
            self._ship_explode(collide_point)
            return True

        if self.ship.laser.shooting():
            if self.asteroids.collidemask(self.ship.laser.mask,
                                          self.ship.laser.rect,
                                          explode=True):
                self.stats.increase_score(ASTEROID_HIT_PTS)

        return self._check_ship_penalty()
Exemplo n.º 4
0
class Game:
    size = None
    screen = None
    star_background = None
    game_field = None
    game_speed = 1
    game_thread = None
    player = None
    fps = 60
    running = True
    gameover = False
    waiting = True
    font = None
    padding = 20
    score = 0
    random_color = [255, 0, 0]
    milestone = 2000
    hit = 0
    highscore = 0
    fpsClock = pygame.time.Clock()

    def __init__(self, size):
        self.size = size
        pygame.font.init()
        self.score = 0
        self.star_background = Stars(self.size)
        self.font = pygame.font.Font("res/font.ttf", 28)
        self.screen = pygame.display.set_mode(size)
        if not self.gameover:
            self.new_game()
        self.loop()

    def new_game(self):
        self.running = True
        self.waiting = True
        self.gameover = False
        self.milestone = 100
        self.game_speed = 1
        self.lives = 4
        self.game_field = GameField(self.size)
        self.player = Player(
            [self.size[0] / 2 - Player.size[0] / 2, self.size[1] - 80],
            [255, 255, 255])

    def draw_score(self):
        fps = self.font.render("x" + str(round(self.game_speed, 2)), False,
                               (255, 255, 255))
        self.screen.blit(fps, (self.padding, self.padding))
        lives = self.font.render(
            str(self.lives) + " Lives", False, (255, 255, 255))
        self.screen.blit(
            lives,
            (self.size[0] - lives.get_width() - self.padding, self.padding))
        score = self.font.render(str(int(self.score)), False, (255, 255, 100))
        self.screen.blit(
            score, ((self.size[0] / 2) - score.get_width() / 2, self.padding))
        if self.waiting:
            start = self.font.render("Press any key to start", False,
                                     self.random_color)
            self.screen.blit(
                start,
                ((self.size[0] / 2) - start.get_width() / 2,
                 (self.size[1] - start.get_height()) - self.padding - 140))
        if self.gameover or self.waiting:
            highscore = self.font.render(
                "Highscore: " + str(int(self.highscore)), False,
                (255, 255, 255))
            self.screen.blit(highscore,
                             ((self.size[0] / 2) - highscore.get_width() / 2,
                              self.padding + self.size[1] / 2))

    def render_game(self):
        self.star_background.render(self.screen)
        self.game_field.render(self.screen)
        self.player.render(self.screen)
        self.draw_score()

    def update_score(self):
        if not self.gameover:
            self.score += self.game_speed * 0.1
        if self.score > self.highscore:
            self.highscore = self.score

    def game_over_animation(self):
        if self.game_speed > 0.5:
            self.game_speed -= 0.01
        if self.player.pos[1] < self.size[1]:
            self.player.pos[1] += 0.5
        else:
            new = True
            for obj in self.game_field.objects:
                if obj.pos[1] < self.size[1]:
                    new = False
            if new:
                self.new_game()

    def update_game(self):
        self.star_background.update(2 * self.game_speed)

        if self.score > self.milestone and not self.waiting:
            self.milestone += 250 * self.game_speed * self.game_speed
            print(self.milestone)
            self.game_speed += 0.5

        if not self.waiting:
            self.game_field.update(4 * self.game_speed, self.gameover)
            self.update_score()
            if self.lives <= 0:
                self.gameover = True

            if self.game_field.is_colliding(self.player):
                if not self.lives <= 0:
                    self.lives -= 1
                    self.hit = 10
            self.player.update(4 * self.game_speed, self.size[0])

    def event_handling(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            if not self.waiting and not self.gameover:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        self.player.move_left = True
                    if event.key == pygame.K_RIGHT:
                        self.player.move_right = True
                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_LEFT:
                        self.player.move_left = False
                    if event.key == pygame.K_RIGHT:
                        self.player.move_right = False
            if self.waiting:
                if event.type == pygame.KEYDOWN:
                    self.score = 0
                    self.game_speed = 1
                    self.waiting = False

    def animation_handling(self):
        if self.gameover:
            self.game_over_animation()

        if self.hit > 0:
            self.hit -= 1

    def calc_colors(self):
        j = 0
        while j < len(self.random_color):
            self.random_color[j] += (j + 1) * 10
            if self.random_color[j] > 255:
                self.random_color[j] = 0
            j += 1

    def loop(self):
        while self.running:
            if self.hit == 0:
                self.screen.fill((0, 0, 0))
            else:
                self.screen.fill(self.random_color)

            self.animation_handling()
            self.calc_colors()
            self.event_handling()
            self.update_game()

            self.render_game()
            pygame.display.flip()
            self.fpsClock.tick(self.fps)