Exemple #1
0
class ScoreTest(unittest.TestCase):

    def setUp(self):
        self.score = Score(0)

    def testAddingWorks(self):
        self.score.add_from([5, 5, 4])
        self.assertEqual(self.score.total, 29)
        self.score.add(3)
        self.assertEqual(self.score.total, 87)

    def testKeepsTrackOfScoreString(self):
        self.score.add_from([1, 2, 3, 4, 5])
        self.assertEqual(self.score.string, [0, 1, 2, 3, 4, 5])
Exemple #2
0
def main():
    parser = argparse.ArgumentParser(description='assign rides to cars')
    parser.add_argument('file_in',
                        type=str,
                        nargs='+',
                        help='<file basename>.in file input')
    parser.add_argument('--solver',
                        type=str,
                        default='ride',
                        choices=('ride', 'flow', 'car'),
                        help='solver')
    parser.add_argument('--debug',
                        action='store_true',
                        help='for debug purpose')
    parser.add_argument('--wait',
                        action='store_true',
                        help='display wait time')
    parser.add_argument('--rides',
                        action='store_true',
                        help='display rides taken and left')
    parser.add_argument('--score',
                        action='store_true',
                        help='display raw score and bonus score')
    parser.add_argument('--progress',
                        action='store_true',
                        help='display progress bar')
    args = parser.parse_args()
    set_log_level(args)
    solver = get_solver(args.solver)
    score_total = Score()
    batch = len(args.file_in) > 1  # several input files
    for file_in in args.file_in:
        (rides_list, rows, columns, vehicles, rides, bonus,
         steps) = parse_input(file_in)
        solution, score = solver.get_solution(rides_list, rows, columns,
                                              vehicles, rides, bonus, steps,
                                              args)
        print_score(score, args)
        score_total.add(score)
        file_out = get_file_out_name(file_in)
        dump_rides(solution, file_out)
    if batch:
        print_score(score_total, args)
from score import Score

score = Score()
print(score)

score.add(5)
print(score)

score.decrease(10)
print(score)
Exemple #4
0
class Game:
    sky = None
    
    
    
        

    def __init__(self, screen, endless = False):
        self.screen = screen

        self.sharks = []
        self.shark_sprites = pygame.sprite.Group()

        self.player = Steamboat()
        self.player_sprite = pygame.sprite.Group()
        self.player_sprite.add(self.player)

        self.health = Health()
        self.health_sprite = pygame.sprite.Group()
        self.health_sprite.add(self.health)

        self.damage_count = 0

        self.t = 0

        self.water = Water.global_water
        #Water.global_water = self.water
        self.water_sprite = pygame.sprite.Group()
        self.water_sprite.add(self.water)

        if not Game.sky:
            Game.sky = util.load_image("taivas")
            Game.sky = pygame.transform.scale(self.sky, (SCREEN_WIDTH, SCREEN_HEIGHT))

        self.cannonballs = []
        self.cannonball_sprites = pygame.sprite.Group()

        self.pirates = []
        self.pirate_sprites = pygame.sprite.Group()

        self.titanic = None
        self.titanic_sprite = pygame.sprite.Group()

        self.seagulls = []
        self.seagull_sprites = pygame.sprite.Group()

        self.particles = Particles()
        self.particle_sprite = pygame.sprite.Group()
        self.particle_sprite.add(self.particles)

        self.mines = []
        self.mine_sprites = pygame.sprite.Group()

        self.score = Score()
        self.score_sprite = pygame.sprite.Group()
        self.score_sprite.add(self.score)

        self.powerups = []
        self.powerup_sprites = pygame.sprite.Group()

        self.level = Level(endless)

        self.lastshot = MIN_FIRE_DELAY + 1

        self.gameover = False
        self.gameover_image = None
        self.gameover_rect = None
        self.done = False

        self.pause = False
        self.pause_image = util.bigfont.render("Pause", Variables.alpha, (0,0,0))
        self.pause_rect = self.pause_image.get_rect()
        self.pause_rect.center = self.screen.get_rect().center

        self.spacepressed = None

    def run(self):
        while not self.done:
            if not self.pause:
                if not self.gameover:
                    self.spawn_enemies()

                self.update_enemies()
                self.player.update()
                self.health.update()
                cloud.update()
                for cb in self.cannonballs:
                    if not cb.underwater:
                        #~ particle_point=cb.rect.left, cb.rect.top
                        particle_point = cb.tail_point()
                        self.particles.add_trace_particle(particle_point)
                        particle_point = [particle_point[i] + cb.vect[i]/2 for i in (0,1)]
                        self.particles.add_trace_particle(particle_point)
                    if cb.special and (not cb.underwater or rr()>0.6) :
                        particle_point = cb.tail_point()
                        self.particles.add_explosion_particle(particle_point)
                    und_old=cb.underwater
                    cb.update()
                    if cb.underwater and not und_old:
                        for i in range(5):
                            particle_point=cb.rect.right-4.0+rr()*8.0, cb.rect.top+rr()*2.0
                            self.particles.add_water_particle(particle_point)
                    if (cb.rect.right < 0 and cb.vect[0] < 0) or (cb.rect.left > SCREEN_WIDTH and cb.vect[0] > 0) or (cb.rect.top > SCREEN_HEIGHT):
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                self.score.update()

                # Add steam particles
                if Variables.particles:
                    particle_point = self.player.get_point((5.0 + rr() * 9.0, 0))
                    particle_point[0] += self.player.rect.centerx
                    particle_point[1] += self.player.rect.centery
                    if self.spacepressed and self.t > self.spacepressed + FPS * 3:
                        pass
                        #~ self.particles.add_fire_steam_particle(particle_point)
                    else:
                        self.particles.add_steam_particle(particle_point)

                    particle_point = self.player.get_point((19.0 + rr() * 7.0, 5.0))
                    particle_point[0] += self.player.rect.centerx
                    particle_point[1] += self.player.rect.centery
                    if self.spacepressed and self.t > self.spacepressed + FPS * 3:
                        pass
                        #~ self.particles.add_fire_steam_particle(particle_point)
                    else:
                        self.particles.add_steam_particle(particle_point)

                    if self.titanic:
                        for j in range(4):
                            particle_point = self.titanic.get_point((49 + rr() * 9.0 + 28 * j, 25))
                            particle_point[0] += self.titanic.rect.centerx
                            particle_point[1] += self.titanic.rect.centery
                            self.particles.add_steam_particle(particle_point)

                    self.particles.update()

                self.water.update()

                if self.player.splash:
                    if Variables.particles:
                        for i in range(10):
                            r = rr()
                            x = int(r * self.player.rect.left + (1.0-r) * self.player.rect.right)
                            point = (x, self.water.get_water_level(x))
                            self.particles.add_water_particle(point)
    
                for powerup in self.powerups:
                    powerup.update()
                    if powerup.picked:
                        self.powerups.remove(powerup)
                        self.powerup_sprites.remove(powerup)

                if not self.gameover:
                    self.check_collisions()

                if self.health.hearts_left == 0 and not self.player.dying:
                    self.player.die()

                if self.player.dying and not self.player.dead:
                    if Variables.particles:
                        self.particles.add_explosion_particle((self.player.rect.centerx, self.player.rect.centery))
                        self.particles.add_debris_particle((self.player.rect.centerx, self.player.rect.centery))

                if self.player.dead:
                    #self.done = True
                    self.set_gameover()

                if self.damage_count > 0:
                    self.damage_count -= 1
                self.lastshot += 1
                self.t += 1

            self.draw()

            self.handle_events()

        return self.score.get_score()

    def damage_player(self):
        self.health.damage()
        for i in range(10):
            particle_point = self.player.get_point((rr() * 26.0, rr() * 10.0))
            particle_point[0] += self.player.rect.centerx
            particle_point[1] += self.player.rect.centery
            self.particles.add_debris_particle(particle_point)
        self.player.blinks+=12


    def set_gameover(self, message = "Game Over"):
        self.gameover = True
        images = []
        height = 0
        width = 0
        for text in message.split("\n"):
            images.append(util.bigfont.render(text, Variables.alpha, (0,0,0)))
            height += images[-1].get_height()
            if images[-1].get_width() > width:
                width = images[-1].get_width()
        self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32)
        self.gameover_image.fill((0,0,0,0))
        for i in range(len(images)):
            rect = images[i].get_rect()
            rect.top = i * images[i].get_height()
            rect.centerx = width / 2
            self.gameover_image.blit(images[i], rect)

        self.gameover_rect = self.gameover_image.get_rect()
        self.gameover_rect.center = self.screen.get_rect().center

    def take_screenshot(self):
        i = 1
        filename = "sshot.tga"
        while os.path.exists(filename):
            i += 1
            filename = "sshot" + str(i) + ".tga"
        
        pygame.image.save(self.screen, filename)
        print("Screenshot saved as " + filename)

    def handle_events(self):
        nextframe = False
        framecount = 0
        while not nextframe:
          # wait until there's at least one event in the queue
          #nextframe = True
          pygame.event.post(pygame.event.wait())
          for event in pygame.event.get():
            #event = pygame.event.wait()
            if event.type == QUIT or \
               event.type == KEYDOWN and event.key == K_ESCAPE:
                self.done = True
                nextframe = True
            elif event.type == NEXTFRAME:
                framecount += 1
                nextframe = True
            elif self.gameover:
                if event.type == JOYBUTTONDOWN:
                    self.done = True
                    nextframe = True
                elif event.type == KEYDOWN:
                    self.done = True
                    nextframe = True
                continue
            elif event.type == JOYAXISMOTION:
                if event.axis == 0:
                    if event.value < -0.5:
                        self.player.move_left(True)
                    elif event.value > 0.5:
                        self.player.move_right(True)
                    else:
                        self.player.move_left(False)
                        self.player.move_right(False)
            elif event.type == JOYBUTTONDOWN:
                if event.button == 0:
                    if not self.pause:
                        self.player.jump()
                elif event.button == 1:
                    if not self.pause:
                        if self.lastshot > MIN_FIRE_DELAY and not self.player.dying:
                            cb = Cannonball(self.player.rect, self.player.angle)
                            self.cannonballs.append(cb)
                            self.cannonball_sprites.add(cb)
                            particle_point = self.player.get_point((42.0,10.0))
                            particle_point[0] += self.player.rect.centerx
                            particle_point[1] += self.player.rect.centery
                            for i in range(4):
                                self.particles.add_fire_steam_particle(particle_point)
                            self.lastshot = 0
                            self.spacepressed = self.t
                elif event.button == 5:
                    self.take_screenshot()
                elif event.button == 8:
                    self.set_pause()
            elif event.type == KEYDOWN:
                if event.key == K_LEFT:
                    self.player.move_left(True)
                elif event.key == K_RIGHT:
                    self.player.move_right(True)
                elif event.key == K_SPACE:
                    if not self.pause:
                    # Only 3 cannonballs at once
                    # Maximum firing rate set at the top
                        if self.lastshot > MIN_FIRE_DELAY and not self.player.dying:
                            cb = Cannonball(self.player.rect, self.player.angle)
                            self.cannonballs.append(cb)
                            self.cannonball_sprites.add(cb)
                            particle_point = self.player.get_point((42.0,10.0))
                            particle_point[0] += self.player.rect.centerx
                            particle_point[1] += self.player.rect.centery
                            for i in range(4):
                                self.particles.add_fire_steam_particle(particle_point)
                            self.lastshot = 0
                            self.spacepressed = self.t
                elif event.key == K_UP:
                    if not self.pause:
                        self.player.jump()
                elif event.key == K_s:
                    self.take_screenshot()
                elif event.key == K_p:
                    self.set_pause()
            elif event.type == KEYUP:
                if event.key == K_LEFT:
                    self.player.move_left(False)
                elif event.key == K_RIGHT:
                    self.player.move_right(False)
                elif event.key == K_SPACE:
                    if not self.pause:
                        if self.spacepressed and self.t > self.spacepressed + FPS * 3 and not self.player.dying:
                            cb = Cannonball(self.player.rect, self.player.angle, special=True)
                            self.cannonballs.append(cb)
                            self.cannonball_sprites.add(cb)
                            particle_point = self.player.get_point((42.0,10.0))
                            particle_point[0] += self.player.rect.centerx
                            particle_point[1] += self.player.rect.centery
                            for i in range(30):
                                self.particles.add_fire_steam_particle((particle_point[0]+rrr(-4,4),particle_point[1]+rrr(-3,3)))
                            self.lastshot = 0
                        self.spacepressed = None
            elif event.type == JOYBUTTONUP:
                if event.button == 1:
                    if not self.pause:
                        if self.spacepressed and self.t > self.spacepressed + FPS * 3 and not self.player.dying:
                            cb = Cannonball(self.player.rect, self.player.angle, special=True)
                            self.cannonballs.append(cb)
                            self.cannonball_sprites.add(cb)
                            particle_point = self.player.get_point((42.0,10.0))
                            particle_point[0] += self.player.rect.centerx
                            particle_point[1] += self.player.rect.centery
                            for i in range(30):
                                self.particles.add_fire_steam_particle((particle_point[0]+rrr(-4,4),particle_point[1]+rrr(-3,3)))
                            self.lastshot = 0
                        self.spacepressed = None

        #if framecount > 1:
        #    print str(self.t) + ": missed " + str(framecount - 1) + " frames!"

    def set_pause(self):
        self.pause = not self.pause

        #if framecount > 1:
        #    print str(self.t) + ": missed " + str(framecount - 1) + " frames!"

    def set_pause(self):
        self.pause = not self.pause

    def draw(self):
        self.screen.blit(Game.sky, self.screen.get_rect())
        self.health_sprite.draw(self.screen)
        self.score_sprite.draw(self.screen)
        self.player_sprite.draw(self.screen)
        self.powerup_sprites.draw(self.screen)
        self.pirate_sprites.draw(self.screen)
        if self.titanic:
            self.titanic_sprite.draw(self.screen)
        self.seagull_sprites.draw(self.screen)
        cloud.draw(self.screen)
        self.shark_sprites.draw(self.screen)
        self.mine_sprites.draw(self.screen)
        self.cannonball_sprites.draw(self.screen)
        self.water_sprite.draw(self.screen)
        if Variables.particles:
            self.particle_sprite.draw(self.screen)

        if self.pause:
            self.screen.blit(self.pause_image, self.pause_rect)

        if self.gameover:
            self.screen.blit(self.gameover_image, self.gameover_rect)

        if self.level.t < 120:
            image = None
            i = 0
            if self.level.phase < len(self.level.phase_messages):
              for text in self.level.phase_messages[self.level.phase].split("\n"):
                image = util.smallfont.render(text, Variables.alpha, (0,0,0))
                rect = image.get_rect()
                rect.centerx = self.screen.get_rect().centerx
                rect.top = 100 + rect.height * i
                blit_image = pygame.Surface((image.get_width(), image.get_height()))
                blit_image.fill((166,183,250))
                blit_image.set_colorkey((166,183,250))
                blit_image.blit(image, image.get_rect())
                if self.level.t > 60:
                    blit_image.set_alpha(255 - (self.level.t - 60) * 255 / 60)
                self.screen.blit(blit_image, rect)
                i += 1

        pygame.display.flip()



    def check_collisions(self):
        collisions = PixelPerfect.spritecollide_pp(self.player, self.powerup_sprites, 0)
        for powerup in collisions:
            if not powerup.fading:
                if not self.player.dying:
                    self.health.add()
                    powerup.pickup()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.mine_sprites, 0)

        for mine in collisions:
            if not mine.exploding:
                if not self.player.dying:
                    self.damage_player()
                    mine.explode()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.shark_sprites, 0)

        for shark in collisions:
            if not shark.dying:
                if not self.player.dying:
                    self.damage_player()
                    shark.die()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.cannonball_sprites, 0)

        for cb in collisions:
            if not self.player.dying:
                self.damage_player()
                self.cannonballs.remove(cb)
                self.cannonball_sprites.remove(cb)
                if (Variables.sound):
                   Mine.sound.play() # Umm... the mine has a nice explosion sound.

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.shark_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for shark in collisions[cb]:
                # The test on cb.vect is a rude hack preventing cannonballs from pirate ships from killing sharks.
                if not shark.dying and cb.vect[0] > 0:
                    self.score.add(15)
                    shark.die()
                    # give her a part of ball's momentum:
                    shark.dx+=cb.vect[0]*0.6
                    shark.dy+=cb.vect[1]*0.4
                    if not cb.special:
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                    break

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.seagull_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for seagull in collisions[cb]:
                # cb.vect test is a rude hack preventing pirates from killing seagulls
                if not seagull.dying and cb.vect[0] > 0:
                    self.score.add(75)
                    seagull.die()
                    # give her a part of ball's momentum:
                    seagull.vect[0]+=cb.vect[0]*0.4
                    seagull.vect[1]+=cb.vect[1]*0.4
                    if not cb.special:
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                    break

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.pirate_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for pirate in collisions[cb]:
                # cb.vect hack for preventing pirates from killing each other
                if not pirate.dying and cb.vect[0] > 0:
                    if (Variables.sound):
                       Mine.sound.play() # Umm... the mine has a nice sound.
                    self.score.add(25)
                    pirate.damage()
                    for i in range(6):
                        self.particles.add_wood_particle((pirate.rect.centerx+rrr(-0,15), pirate.rect.centery+rrr(-10,20)))
                    if not cb.special:
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                    break

        if self.titanic:
            collisions = PixelPerfect.spritecollide_pp(self.titanic, self.cannonball_sprites, 0)
            for cb in collisions:
                if not self.titanic.dying and cb.vect[0] > 0:
                    if (Variables.sound):
                       Mine.sound.play()
                    if cb.special: 
                        #special round is hard to fire, so lets reward our crafty player
                        self.titanic.damage(12)
                        self.score.add(100)
                    else:
                        self.score.add(7)
                        self.titanic.damage()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

    def update_enemies(self):
        self.mine_sprites.update()
        for mine in self.mines:
            if mine.exploding:
                if mine.explode_frames == 0:
                    self.mines.remove(mine)
                    self.mine_sprites.remove(mine)
                # this should really be done in the Mine class, but oh well, here's some explosion effects:
                if Variables.particles:
                    self.particles.add_explosion_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx))
                    self.particles.add_debris_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx))
            if mine.rect.right < self.screen.get_rect().left:
                self.mines.remove(mine)
                self.mine_sprites.remove(mine)

        self.shark_sprites.update()
        for shark in self.sharks:
            if shark.dying:
                if Variables.particles:
                    self.particles.add_blood_particle(shark.rect.center)
            if shark.rect.right < self.screen.get_rect().left or shark.dead:
                self.sharks.remove(shark)
                self.shark_sprites.remove(shark)

        self.pirate_sprites.update()
        for pirate in self.pirates:
            if pirate.t % 50 == 0 and not pirate.dying:
                # Pirate shoots, this should probably be handled by the Pirateboat class
                cb = Cannonball(pirate.rect, pirate.angle, left = True)
                self.cannonballs.append(cb)
                self.cannonball_sprites.add(cb)
                particle_point = pirate.get_point((0.0,10.0))
                particle_point[0] += pirate.rect.centerx
                particle_point[1] += pirate.rect.centery
                for i in range(4):
                    self.particles.add_fire_steam_particle(particle_point)
                
            if pirate.rect.right < self.screen.get_rect().left or pirate.dead:
                self.pirates.remove(pirate)
                self.pirate_sprites.remove(pirate)
            elif pirate.dying:
                if Variables.particles:
                    self.particles.add_explosion_particle((pirate.rect.centerx, pirate.rect.centery))
                    self.particles.add_wood_particle((pirate.rect.centerx, pirate.rect.centery))

        if self.titanic:
            self.titanic.update()
            if self.titanic.t % 100 == 0 and not self.titanic.dying:
                for i in range(3):
                    cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 50, left = True)
                    self.cannonballs.append(cb)
                    self.cannonball_sprites.add(cb)
            elif self.titanic.t % 100 == 50 and not self.titanic.dying:
                for i in range(3):
                    cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 52.5, left = True)
                    self.cannonballs.append(cb)
                    self.cannonball_sprites.add(cb)
            if self.titanic.dead:
                self.set_gameover("Congratulations!\nYou sunk Titanic!")
                self.titanic = None

        self.seagull_sprites.update()
        for seagull in self.seagulls:
            if seagull.rect.right < 0 or seagull.dead:
                self.seagulls.remove(seagull)
                self.seagull_sprites.remove(seagull)

    def spawn_enemies(self):
        spawns = self.level.get_spawns()
        if spawns[Level.SHARKS]:
            # Make a new shark
            self.sharks.append(Shark())
            self.shark_sprites.add(self.sharks[-1])

        if spawns[Level.PIRATES]:
            # Make a new pirate ship
            self.pirates.append(Pirateboat())
            self.pirate_sprites.add(self.pirates[-1])

        if spawns[Level.MINES]:
            self.mines.append(Mine())
            self.mine_sprites.add(self.mines[-1])

        if spawns[Level.SEAGULLS]:
            self.seagulls.append(Seagull())
            self.seagull_sprites.add(self.seagulls[-1])

        if spawns[Level.TITANIC]:
            self.titanic = Titanic()
            self.titanic_sprite.add(self.titanic)

        if spawns[Level.POWERUPS]:
            self.powerups.append(Powerup())
            self.powerup_sprites.add(self.powerups[-1])
Exemple #5
0
class Game(object):

    def __init__(self, screen_height, screen_width):
        pygame.init()
        self.screen_height = screen_height
        self.screen_width = screen_width
        self.level_maps = ("./data/level1.map", "./data/level2.map", "./data/level3.map")
        self.current_level_map_index = 0
        self.pause = False
        self.won_grow_rate = 10
        height_width = (self.screen_height, self.screen_width)
        self.screen = pygame.display.set_mode(height_width)
        pygame.display.set_caption("PySnake")
        self.score = Score((0, 500))
        self.reload_game = False
        self.speed = 5

    def init_resources(self):
        self.level = Level(self.level_maps[self.current_level_map_index])
        self.snake = Snake((64, 64))
        self.move_direction = Direction.RIGHT
        self.food = None

    def start(self):
        clock = pygame.time.Clock()
        game_over = False
        won = True
        first_load = True

        while not game_over:
            clock.tick(self.speed)
            for event in pygame.event.get():
                self.event_handler(event)

            if self.reload_game:
                break

            if not self.pause:
                background = self.level.render()
                self.snake.render(background)
                if self.food == None:
                    position = self.generate_free_position()
                    self.food = Food(position, 1)

                background.blit(self.food.image, self.food.rect)
                self.screen.fill((0, 0, 0))
                self.screen.blit(background, (0, 0))
                self.screen.blit(self.score.image, self.score.rect)

                pygame.display.flip()
                if first_load:
                    first_load = False
                    self.pause = True
                    continue

                not_collide = self.snake.update(self.move_direction)
                if not not_collide or self.level.collide(self.snake.position):
                    game_over = True
                    won = False

                if self.food.rect.colliderect(self.snake.head.rect):
                    self.snake.grow(self.food.grow_rate)
                    self.score.add(100)
                    self.food = None

                if self.snake.length() == self.won_grow_rate:
                    game_over = True

        if self.reload_game:
            self.load_game()
        elif won and game_over:
            self.load_next_level()
        elif game_over:
            print("Game over")

    def event_handler(self, event):
        if event.type == QUIT:
            sys.exit(0)
        elif event.type == KEYDOWN:
            key = pygame.key.get_pressed()
            new_direction = self.move_direction
            if key[pygame.K_LEFT]:
                new_direction = Direction.LEFT
            elif key[pygame.K_RIGHT]:
                new_direction = Direction.RIGHT
            elif key[pygame.K_UP]:
                new_direction = Direction.UP
            elif key[pygame.K_DOWN]:
                new_direction = Direction.DOWN
            elif key[pygame.K_p]:
                self.pause = not self.pause
            elif key[pygame.K_s]:
                self.pause = True
                level = self.current_level_map_index
                snake = self.snake.get_snake_coords()
                food = self.food.get_food_position()
                direction = self.move_direction
                SaveGame.save(level, snake, food, direction)
            elif key[pygame.K_l]:
                self.reload_game = True

            oposide_direction = self.opposite_direction(self.move_direction)
            if not oposide_direction == new_direction:
                self.move_direction = new_direction

    def opposite_direction(self, direction):
        if direction == Direction.UP:
            return Direction.DOWN
        elif direction == Direction.DOWN:
            return Direction.UP
        elif direction == Direction.LEFT:
            return Direction.RIGHT
        elif direction == Direction.RIGHT:
            return Direction.LEFT

    def generate_free_position(self):
        x, y = None, None

        while x is None or self.level.collide((x, y)) or self.snake.collide((x, y)):
            x = random.randrange(0, self.level.width - 32, 2)
            y = random.randrange(0, self.level.height - 32, 2)
        return (x, y)

    def load_next_level(self):
        if len(self.level_maps) - 1 == self.current_level_map_index:
            print("Game over, you win")
            return
        self.current_level_map_index += 1
        self.init_resources()
        self.start()

    def get_current_level_map(self):
        return self.level_maps[self.current_level_map_index]

    def load_game(self):
        loaded_dict = LoadGame.load()
        self.current_level_map_index = loaded_dict["level"]
        self.init_resources()
        self.snake.load_snake_from_coord(loaded_dict["snake"])
        self.food = Food(loaded_dict["food"], 1)
        self.move_direction = loaded_dict["direction"]
        self.reload_game = False
        self.start()
Exemple #6
0
class Game:
    sky = None
    
    
    
        

    def __init__(self, screen, endless = False):
        self.screen = screen

        self.sharks = []
        self.shark_sprites = pygame.sprite.Group()

        self.player = Steamboat()
        self.player_sprite = pygame.sprite.Group()
        self.player_sprite.add(self.player)

        self.health = Health()
        self.health_sprite = pygame.sprite.Group()
        self.health_sprite.add(self.health)

        self.damage_count = 0

        self.t = 0

        self.water = Water.global_water
        #Water.global_water = self.water
        self.water_sprite = pygame.sprite.Group()
        self.water_sprite.add(self.water)

        if not Game.sky:
            Game.sky = util.load_image("taivas")
            Game.sky = pygame.transform.scale(self.sky, (SCREEN_WIDTH, SCREEN_HEIGHT))

        self.cannonballs = []
        self.cannonball_sprites = pygame.sprite.Group()

        self.pirates = []
        self.pirate_sprites = pygame.sprite.Group()

        self.titanic = None
        self.titanic_sprite = pygame.sprite.Group()

        self.seagulls = []
        self.seagull_sprites = pygame.sprite.Group()

        self.particles = Particles()
        self.particle_sprite = pygame.sprite.Group()
        self.particle_sprite.add(self.particles)

        self.mines = []
        self.mine_sprites = pygame.sprite.Group()

        self.score = Score()
        self.score_sprite = pygame.sprite.Group()
        self.score_sprite.add(self.score)

        self.powerups = []
        self.powerup_sprites = pygame.sprite.Group()

        self.level = Level(endless)

        self.lastshot = MIN_FIRE_DELAY + 1

        self.gameover = False
        self.gameover_image = None
        self.gameover_rect = None
        self.done = False

        self.pause = False
        self.pause_image = util.bigfont.render("Pause", Variables.alpha, (0,0,0))
        self.pause_rect = self.pause_image.get_rect()
        self.pause_rect.center = self.screen.get_rect().center

        self.spacepressed = None

    def run(self):
        while not self.done:
            if not self.pause:
                if not self.gameover:
                    self.spawn_enemies()

                self.update_enemies()
                self.player.update()
                self.health.update()
                cloud.update()
                for cb in self.cannonballs:
                    if not cb.underwater:
                        #~ particle_point=cb.rect.left, cb.rect.top
                        particle_point = cb.tail_point()
                        self.particles.add_trace_particle(particle_point)
                        particle_point = [particle_point[i] + cb.vect[i]/2 for i in (0,1)]
                        self.particles.add_trace_particle(particle_point)
                    if cb.special and (not cb.underwater or rr()>0.6) :
                        particle_point = cb.tail_point()
                        self.particles.add_explosion_particle(particle_point)
                    und_old=cb.underwater
                    cb.update()
                    if cb.underwater and not und_old:
                        for i in xrange(5):
                            particle_point=cb.rect.right-4.0+rr()*8.0, cb.rect.top+rr()*2.0
                            self.particles.add_water_particle(particle_point)
                    if (cb.rect.right < 0 and cb.vect[0] < 0) or (cb.rect.left > SCREEN_WIDTH and cb.vect[0] > 0) or (cb.rect.top > SCREEN_HEIGHT):
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                self.score.update()

                # Add steam particles
                if Variables.particles:
                    particle_point = self.player.get_point((5.0 + rr() * 9.0, 0))
                    particle_point[0] += self.player.rect.centerx
                    particle_point[1] += self.player.rect.centery
                    if self.spacepressed and self.t > self.spacepressed + FPS * 3:
                        pass
                        #~ self.particles.add_fire_steam_particle(particle_point)
                    else:
                        self.particles.add_steam_particle(particle_point)

                    particle_point = self.player.get_point((19.0 + rr() * 7.0, 5.0))
                    particle_point[0] += self.player.rect.centerx
                    particle_point[1] += self.player.rect.centery
                    if self.spacepressed and self.t > self.spacepressed + FPS * 3:
                        pass
                        #~ self.particles.add_fire_steam_particle(particle_point)
                    else:
                        self.particles.add_steam_particle(particle_point)

                    if self.titanic:
                        for j in xrange(4):
                            particle_point = self.titanic.get_point((49 + rr() * 9.0 + 28 * j, 25))
                            particle_point[0] += self.titanic.rect.centerx
                            particle_point[1] += self.titanic.rect.centery
                            self.particles.add_steam_particle(particle_point)

                    self.particles.update()

                self.water.update()

                if self.player.splash:
                    if Variables.particles:
                        for i in xrange(10):
                            r = rr()
                            x = int(r * self.player.rect.left + (1.0-r) * self.player.rect.right)
                            point = (x, self.water.get_water_level(x))
                            self.particles.add_water_particle(point)
    
                for powerup in self.powerups:
                    powerup.update()
                    if powerup.picked:
                        self.powerups.remove(powerup)
                        self.powerup_sprites.remove(powerup)

                if not self.gameover:
                    self.check_collisions()

                if self.health.hearts_left == 0 and not self.player.dying:
                    self.player.die()

                if self.player.dying and not self.player.dead:
                    if Variables.particles:
                        self.particles.add_explosion_particle((self.player.rect.centerx, self.player.rect.centery))
                        self.particles.add_debris_particle((self.player.rect.centerx, self.player.rect.centery))

                if self.player.dead:
                    #self.done = True
                    self.set_gameover()

                if self.damage_count > 0:
                    self.damage_count -= 1
                self.lastshot += 1
                self.t += 1

            self.draw()

            self.handle_events()

        return self.score.get_score()

    def damage_player(self):
        self.health.damage()
        for i in xrange(10):
            particle_point = self.player.get_point((rr() * 26.0, rr() * 10.0))
            particle_point[0] += self.player.rect.centerx
            particle_point[1] += self.player.rect.centery
            self.particles.add_debris_particle(particle_point)
        self.player.blinks+=12


    def set_gameover(self, message = "Game Over"):
        self.gameover = True
        images = []
        height = 0
        width = 0
        for text in message.split("\n"):
            images.append(util.bigfont.render(text, Variables.alpha, (0,0,0)))
            height += images[-1].get_height()
            if images[-1].get_width() > width:
                width = images[-1].get_width()
        self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32)
        self.gameover_image.fill((0,0,0,0))
        for i in xrange(len(images)):
            rect = images[i].get_rect()
            rect.top = i * images[i].get_height()
            rect.centerx = width / 2
            self.gameover_image.blit(images[i], rect)

        self.gameover_rect = self.gameover_image.get_rect()
        self.gameover_rect.center = self.screen.get_rect().center

    def take_screenshot(self):
        i = 1
        filename = "sshot.tga"
        while os.path.exists(filename):
            i += 1
            filename = "sshot" + str(i) + ".tga"
        
        pygame.image.save(self.screen, filename)
        print "Screenshot saved as " + filename

    def handle_events(self):
        nextframe = False
        framecount = 0
        while not nextframe:
          # wait until there's at least one event in the queue
          #nextframe = True
          pygame.event.post(pygame.event.wait())
          for event in pygame.event.get():
            #event = pygame.event.wait()
            if event.type == QUIT or \
               event.type == KEYDOWN and event.key == K_ESCAPE:
                self.done = True
                nextframe = True
            elif event.type == NEXTFRAME:
                framecount += 1
                nextframe = True
            elif self.gameover:
                if event.type == JOYBUTTONDOWN:
                    self.done = True
                    nextframe = True
                elif event.type == KEYDOWN:
                    self.done = True
                    nextframe = True
                continue
            elif event.type == JOYAXISMOTION:
                if event.axis == 0:
                    if event.value < -0.5:
                        self.player.move_left(True)
                    elif event.value > 0.5:
                        self.player.move_right(True)
                    else:
                        self.player.move_left(False)
                        self.player.move_right(False)
            elif event.type == JOYBUTTONDOWN:
                if event.button == 0:
                    if not self.pause:
                        self.player.jump()
                elif event.button == 1:
                    if not self.pause:
                        if self.lastshot > MIN_FIRE_DELAY and not self.player.dying:
                            cb = Cannonball(self.player.rect, self.player.angle)
                            self.cannonballs.append(cb)
                            self.cannonball_sprites.add(cb)
                            particle_point = self.player.get_point((42.0,10.0))
                            particle_point[0] += self.player.rect.centerx
                            particle_point[1] += self.player.rect.centery
                            for i in xrange(4):
                                self.particles.add_fire_steam_particle(particle_point)
                            self.lastshot = 0
                            self.spacepressed = self.t
                elif event.button == 5:
                    self.take_screenshot()
                elif event.button == 8:
                    self.set_pause()
            elif event.type == KEYDOWN:
                if event.key == K_LEFT:
                    self.player.move_left(True)
                elif event.key == K_RIGHT:
                    self.player.move_right(True)
                elif event.key == K_SPACE:
                    if not self.pause:
                    # Only 3 cannonballs at once
                    # Maximum firing rate set at the top
                        if self.lastshot > MIN_FIRE_DELAY and not self.player.dying:
                            cb = Cannonball(self.player.rect, self.player.angle)
                            self.cannonballs.append(cb)
                            self.cannonball_sprites.add(cb)
                            particle_point = self.player.get_point((42.0,10.0))
                            particle_point[0] += self.player.rect.centerx
                            particle_point[1] += self.player.rect.centery
                            for i in xrange(4):
                                self.particles.add_fire_steam_particle(particle_point)
                            self.lastshot = 0
                            self.spacepressed = self.t
                elif event.key == K_UP:
                    if not self.pause:
                        self.player.jump()
                elif event.key == K_s:
                    self.take_screenshot()
                elif event.key == K_p:
                    self.set_pause()
            elif event.type == KEYUP:
                if event.key == K_LEFT:
                    self.player.move_left(False)
                elif event.key == K_RIGHT:
                    self.player.move_right(False)
                elif event.key == K_SPACE:
                    if not self.pause:
                        if self.spacepressed and self.t > self.spacepressed + FPS * 3 and not self.player.dying:
                            cb = Cannonball(self.player.rect, self.player.angle, special=True)
                            self.cannonballs.append(cb)
                            self.cannonball_sprites.add(cb)
                            particle_point = self.player.get_point((42.0,10.0))
                            particle_point[0] += self.player.rect.centerx
                            particle_point[1] += self.player.rect.centery
                            for i in xrange(30):
                                self.particles.add_fire_steam_particle((particle_point[0]+rrr(-4,4),particle_point[1]+rrr(-3,3)))
                            self.lastshot = 0
                        self.spacepressed = None
            elif event.type == JOYBUTTONUP:
                if event.button == 1:
                    if not self.pause:
                        if self.spacepressed and self.t > self.spacepressed + FPS * 3 and not self.player.dying:
                            cb = Cannonball(self.player.rect, self.player.angle, special=True)
                            self.cannonballs.append(cb)
                            self.cannonball_sprites.add(cb)
                            particle_point = self.player.get_point((42.0,10.0))
                            particle_point[0] += self.player.rect.centerx
                            particle_point[1] += self.player.rect.centery
                            for i in xrange(30):
                                self.particles.add_fire_steam_particle((particle_point[0]+rrr(-4,4),particle_point[1]+rrr(-3,3)))
                            self.lastshot = 0
                        self.spacepressed = None

        #if framecount > 1:
        #    print str(self.t) + ": missed " + str(framecount - 1) + " frames!"

    def set_pause(self):
        self.pause = not self.pause

        #if framecount > 1:
        #    print str(self.t) + ": missed " + str(framecount - 1) + " frames!"

    def set_pause(self):
        self.pause = not self.pause

    def draw(self):
        self.screen.blit(Game.sky, self.screen.get_rect())
        self.health_sprite.draw(self.screen)
        self.score_sprite.draw(self.screen)
        self.player_sprite.draw(self.screen)
        self.powerup_sprites.draw(self.screen)
        self.pirate_sprites.draw(self.screen)
        if self.titanic:
            self.titanic_sprite.draw(self.screen)
        self.seagull_sprites.draw(self.screen)
        cloud.draw(self.screen)
        self.shark_sprites.draw(self.screen)
        self.mine_sprites.draw(self.screen)
        self.cannonball_sprites.draw(self.screen)
        self.water_sprite.draw(self.screen)
        if Variables.particles:
            self.particle_sprite.draw(self.screen)

        if self.pause:
            self.screen.blit(self.pause_image, self.pause_rect)

        if self.gameover:
            self.screen.blit(self.gameover_image, self.gameover_rect)

        if self.level.t < 120:
            image = None
            i = 0
            if self.level.phase < len(self.level.phase_messages):
              for text in self.level.phase_messages[self.level.phase].split("\n"):
                image = util.smallfont.render(text, Variables.alpha, (0,0,0))
                rect = image.get_rect()
                rect.centerx = self.screen.get_rect().centerx
                rect.top = 100 + rect.height * i
                blit_image = pygame.Surface((image.get_width(), image.get_height()))
                blit_image.fill((166,183,250))
                blit_image.set_colorkey((166,183,250))
                blit_image.blit(image, image.get_rect())
                if self.level.t > 60:
                    blit_image.set_alpha(255 - (self.level.t - 60) * 255 / 60)
                self.screen.blit(blit_image, rect)
                i += 1

        pygame.display.flip()



    def check_collisions(self):
        collisions = PixelPerfect.spritecollide_pp(self.player, self.powerup_sprites, 0)
        for powerup in collisions:
            if not powerup.fading:
                if not self.player.dying:
                    self.health.add()
                    powerup.pickup()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.mine_sprites, 0)

        for mine in collisions:
            if not mine.exploding:
                if not self.player.dying:
                    self.damage_player()
                    mine.explode()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.shark_sprites, 0)

        for shark in collisions:
            if not shark.dying:
                if not self.player.dying:
                    self.damage_player()
                    shark.die()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.cannonball_sprites, 0)

        for cb in collisions:
            if not self.player.dying:
                self.damage_player()
                self.cannonballs.remove(cb)
                self.cannonball_sprites.remove(cb)
                if (Variables.sound):
                   Mine.sound.play() # Umm... the mine has a nice explosion sound.

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.shark_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for shark in collisions[cb]:
                # The test on cb.vect is a rude hack preventing cannonballs from pirate ships from killing sharks.
                if not shark.dying and cb.vect[0] > 0:
                    self.score.add(15)
                    shark.die()
                    # give her a part of ball's momentum:
                    shark.dx+=cb.vect[0]*0.6
                    shark.dy+=cb.vect[1]*0.4
                    if not cb.special:
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                    break

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.seagull_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for seagull in collisions[cb]:
                # cb.vect test is a rude hack preventing pirates from killing seagulls
                if not seagull.dying and cb.vect[0] > 0:
                    self.score.add(75)
                    seagull.die()
                    # give her a part of ball's momentum:
                    seagull.vect[0]+=cb.vect[0]*0.4
                    seagull.vect[1]+=cb.vect[1]*0.4
                    if not cb.special:
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                    break

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.pirate_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for pirate in collisions[cb]:
                # cb.vect hack for preventing pirates from killing each other
                if not pirate.dying and cb.vect[0] > 0:
                    if (Variables.sound):
                       Mine.sound.play() # Umm... the mine has a nice sound.
                    self.score.add(25)
                    pirate.damage()
                    for i in range(6):
                        self.particles.add_wood_particle((pirate.rect.centerx+rrr(-0,15), pirate.rect.centery+rrr(-10,20)))
                    if not cb.special:
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                    break

        if self.titanic:
            collisions = PixelPerfect.spritecollide_pp(self.titanic, self.cannonball_sprites, 0)
            for cb in collisions:
                if not self.titanic.dying and cb.vect[0] > 0:
                    if (Variables.sound):
                       Mine.sound.play()
                    if cb.special: 
                        #special round is hard to fire, so lets reward our crafty player
                        self.titanic.damage(12)
                        self.score.add(100)
                    else:
                        self.score.add(7)
                        self.titanic.damage()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

    def update_enemies(self):
        self.mine_sprites.update()
        for mine in self.mines:
            if mine.exploding:
                if mine.explode_frames == 0:
                    self.mines.remove(mine)
                    self.mine_sprites.remove(mine)
                # this should really be done in the Mine class, but oh well, here's some explosion effects:
                if Variables.particles:
                    self.particles.add_explosion_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx))
                    self.particles.add_debris_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx))
            if mine.rect.right < self.screen.get_rect().left:
                self.mines.remove(mine)
                self.mine_sprites.remove(mine)

        self.shark_sprites.update()
        for shark in self.sharks:
            if shark.dying:
                if Variables.particles:
                    self.particles.add_blood_particle(shark.rect.center)
            if shark.rect.right < self.screen.get_rect().left or shark.dead:
                self.sharks.remove(shark)
                self.shark_sprites.remove(shark)

        self.pirate_sprites.update()
        for pirate in self.pirates:
            if pirate.t % 50 == 0 and not pirate.dying:
                # Pirate shoots, this should probably be handled by the Pirateboat class
                cb = Cannonball(pirate.rect, pirate.angle, left = True)
                self.cannonballs.append(cb)
                self.cannonball_sprites.add(cb)
                particle_point = pirate.get_point((0.0,10.0))
                particle_point[0] += pirate.rect.centerx
                particle_point[1] += pirate.rect.centery
                for i in xrange(4):
                    self.particles.add_fire_steam_particle(particle_point)
                
            if pirate.rect.right < self.screen.get_rect().left or pirate.dead:
                self.pirates.remove(pirate)
                self.pirate_sprites.remove(pirate)
            elif pirate.dying:
                if Variables.particles:
                    self.particles.add_explosion_particle((pirate.rect.centerx, pirate.rect.centery))
                    self.particles.add_wood_particle((pirate.rect.centerx, pirate.rect.centery))

        if self.titanic:
            self.titanic.update()
            if self.titanic.t % 100 == 0 and not self.titanic.dying:
                for i in xrange(3):
                    cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 50, left = True)
                    self.cannonballs.append(cb)
                    self.cannonball_sprites.add(cb)
            elif self.titanic.t % 100 == 50 and not self.titanic.dying:
                for i in xrange(3):
                    cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 52.5, left = True)
                    self.cannonballs.append(cb)
                    self.cannonball_sprites.add(cb)
            if self.titanic.dead:
                self.set_gameover("Congratulations!\nYou sunk Titanic!")
                self.titanic = None

        self.seagull_sprites.update()
        for seagull in self.seagulls:
            if seagull.rect.right < 0 or seagull.dead:
                self.seagulls.remove(seagull)
                self.seagull_sprites.remove(seagull)

    def spawn_enemies(self):
        spawns = self.level.get_spawns()
        if spawns[Level.SHARKS]:
            # Make a new shark
            self.sharks.append(Shark())
            self.shark_sprites.add(self.sharks[-1])

        if spawns[Level.PIRATES]:
            # Make a new pirate ship
            self.pirates.append(Pirateboat())
            self.pirate_sprites.add(self.pirates[-1])

        if spawns[Level.MINES]:
            self.mines.append(Mine())
            self.mine_sprites.add(self.mines[-1])

        if spawns[Level.SEAGULLS]:
            self.seagulls.append(Seagull())
            self.seagull_sprites.add(self.seagulls[-1])

        if spawns[Level.TITANIC]:
            self.titanic = Titanic()
            self.titanic_sprite.add(self.titanic)

        if spawns[Level.POWERUPS]:
            self.powerups.append(Powerup())
            self.powerup_sprites.add(self.powerups[-1])
Exemple #7
0
class Game:
    def __init__(self, screen, usealpha = True, noparticles = False, endless = False):
        self.screen = screen
        self.usealpha = usealpha
        self.noparticles = noparticles

        self.sharks = []
        self.shark_sprites = pygame.sprite.Group()

        self.player = Steamboat()
        self.player_sprite = pygame.sprite.Group()
        self.player_sprite.add(self.player)

        self.health = Health()
        self.health_sprite = pygame.sprite.Group()
        self.health_sprite.add(self.health)

        self.damage_count = 0

        self.t = 0

        self.water = Water.global_water #Water(self.usealpha)
        #Water.global_water = self.water
        self.water_sprite = pygame.sprite.Group()
        self.water_sprite.add(self.water)

        self.sky = util.load_image("taivas")
        self.sky = pygame.transform.scale(self.sky, (SCREEN_WIDTH, SCREEN_HEIGHT))

        self.pause_icon = util.load_image("pause")
        
        self.cannonballs = []
        self.cannonball_sprites = pygame.sprite.Group()

        self.pirates = []
        self.pirate_sprites = pygame.sprite.Group()

        self.titanic = None
        self.titanic_sprite = pygame.sprite.Group()

        self.seagulls = []
        self.seagull_sprites = pygame.sprite.Group()

        self.particles = Particles(self.usealpha)
        self.particle_sprite = pygame.sprite.Group()
        self.particle_sprite.add(self.particles)

        self.mines = []
        self.mine_sprites = pygame.sprite.Group()

        self.score = Score()
        self.score_sprite = pygame.sprite.Group()
        self.score_sprite.add(self.score)

        self.powerups = []
        self.powerup_sprites = pygame.sprite.Group()

        self.level = Level(endless)
        self.cheat_current = 0
        
        self.lastshot = MIN_FIRE_DELAY + 1

        self.gameover = False
        self.gameover_image = None
        self.gameover_rect = None
        self.done = False

        self.pause = False
        font = util.load_font("Cosmetica", 40) #pygame.font.Font(pygame.font.get_default_font(), 36)
        self.pause_image = font.render("Pause", True, (0,0,0))
        self.pause_rect = self.pause_image.get_rect()
        self.pause_rect.center = self.screen.get_rect().center

    def run(self):
        while not self.done:
            util.android_check_pause()
            if not self.pause:
                if not self.gameover:
                    self.spawn_enemies()

                self.update_enemies()
                self.player.update()
                self.health.update()
                cloud.update()
                for cb in self.cannonballs:
                    cb.update()
                    if (cb.rect.right < 0 and cb.vect[0] < 0) or (cb.rect.left > SCREEN_WIDTH and cb.vect[0] > 0):
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                self.score.update()

                # Add steam particles
                if not self.noparticles:
                    for i in range(STEAM_3):
                        particle_point = self.player.get_point((5.0 + random.random() * 9.0, 0))
                        particle_point[0] += self.player.rect.centerx
                        particle_point[1] += self.player.rect.centery
                        self.particles.add_steam_particle(particle_point)

                    for i in range(STEAM_3):
                        particle_point = self.player.get_point((19.0 + random.random() * 7.0, 5.0))
                        particle_point[0] += self.player.rect.centerx
                        particle_point[1] += self.player.rect.centery
                        self.particles.add_steam_particle(particle_point)

                    if self.titanic:
                        for j in range(4):
                            for i in range(STEAM_3):
                                particle_point = self.titanic.get_point((49 + random.random() * 9.0 + 28 * j, 25))
                                particle_point[0] += self.titanic.rect.centerx
                                particle_point[1] += self.titanic.rect.centery
                                self.particles.add_steam_particle(particle_point)

                    self.particles.update()

                self.water.update()

                if self.player.splash:
                    if not self.noparticles:
                        for i in range(SPLASH_30):
                            r = random.random()
                            x = int(r * self.player.rect.left + (1.0-r) * self.player.rect.right)
                            point = (x, self.water.get_water_level(x))
                            self.particles.add_water_particle(point)
    
                for powerup in self.powerups:
                    powerup.update()
                    if powerup.picked:
                        self.powerups.remove(powerup)
                        self.powerup_sprites.remove(powerup)

                if not self.gameover:
                    self.check_collisions()

                if self.health.hearts_left == 0 and not self.player.dying:
                    self.player.die()

                if self.player.dying and not self.player.dead:
                    if not self.noparticles:
                        for i in range(BLOOD_3):
                            self.particles.add_explosion_particle((self.player.rect.centerx, self.player.rect.centery))
                            self.particles.add_debris_particle((self.player.rect.centerx, self.player.rect.centery))

                if self.player.dead:
                    #self.done = True
                    self.set_gameover()

                if self.damage_count > 0:
                    self.damage_count -= 1
                self.lastshot += 1
                self.t += 1

            self.draw()

            self.handle_events()


        return self.score.get_score()

    def set_gameover(self, message = "Game Over"):
        self.gameover = True
        images = []
        font = util.load_font("Cosmetica", 40) #pygame.font.Font(pygame.font.get_default_font(), 36)
        height = 0
        width = 0
        for text in message.split("\n"):
            images.append(font.render(text, True, (0,0,0)))
            height += images[-1].get_height()
            if images[-1].get_width() > width:
                width = images[-1].get_width()
        self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32)
        self.gameover_image.fill((0,0,0,0))
        for i in range(len(images)):
            rect = images[i].get_rect()
            rect.top = i * images[i].get_height()
            rect.centerx = width / 2
            self.gameover_image.blit(images[i], rect)

        self.gameover_rect = self.gameover_image.get_rect()
        self.gameover_rect.center = self.screen.get_rect().center
    
    def translate_mouse_event(self, event):
     if event.type in (MOUSEBUTTONDOWN, ):
       if event.pos[0] > SCREEN_WIDTH - 32 and event.pos[1] < 32:
          key = K_p
       else:
          rx = event.pos[0] / float(SCREEN_WIDTH)
          ry = event.pos[1] / float(SCREEN_HEIGHT)
          if rx < 0.0:
             key = K_LEFT
          elif rx > 1.0:
             key = K_RIGHT
          elif ry > 0.5:
             key = K_SPACE
          else:
             key = K_UP
       event = pygame.event.Event(KEYUP if event.type == MOUSEBUTTONUP else KEYDOWN, key=key)
     
     if util.android:
        self.player.move_left(False)
        self.player.move_right(False)
     return event
    
    def handle_events(self):
        nextframe = False
        framecount = 0
        while not nextframe:
          # wait until there's at least one event in the queue
          pygame.event.post(pygame.event.wait())
          for event in pygame.event.get():
            #event = pygame.event.wait()
            event = self.translate_mouse_event(event)
            if event.type == QUIT or \
               event.type == KEYDOWN and event.key == K_ESCAPE:
                self.done = True
                nextframe = True
            elif event.type == NEXTFRAME:
                nextframe = True
                framecount += 1
            elif self.gameover:
                if event.type == JOYBUTTONDOWN:
                    self.done = True
                    nextframe = True
                elif event.type == KEYDOWN:
                    self.done = True
                    nextframe = True
            elif event.type == MOUSEBUTTONDOWN:
                self.done = True
                nextframe = True
                continue
            elif event.type == JOYAXISMOTION:
                if event.axis == 0:
                    if event.value < -0.5:
                        self.player.move_left(True)
                    elif event.value > 0.5:
                        self.player.move_right(True)
                    else:
                        self.player.move_left(False)
                        self.player.move_right(False)
            elif event.type == JOYBUTTONDOWN:
                if event.button == 0:
                  if not self.pause:
                    self.player.jump()
                elif event.button == 1:
                  if not self.pause:
                    if self.lastshot > MIN_FIRE_DELAY and not self.player.dying:
                        cb = Cannonball(self.player.rect, self.player.angle)
                        self.cannonballs.append(cb)
                        self.cannonball_sprites.add(cb)
                        self.lastshot = 0
                elif event.button == 5:
                    pygame.image.save(self.screen, "sshot.tga")
                    print "Screenshot saved as sshot.tga"
                elif event.button == 8:
                    self.set_pause()
            elif event.type == KEYDOWN:
                if event.key == K_LEFT:
                    self.player.move_left(True)
                elif event.key == K_RIGHT:
                    self.player.move_right(True)
                elif event.key == K_SPACE:
                  if not self.pause:
                    # Only 3 cannonballs at once
                    # Maximum firing rate set at the top
                    if self.lastshot > MIN_FIRE_DELAY and not self.player.dying:
                        cb = Cannonball(self.player.rect, self.player.angle)
                        self.cannonballs.append(cb)
                        self.cannonball_sprites.add(cb)
                        self.lastshot = 0
                elif event.key == K_UP:
                    if not self.pause:
                        self.player.jump()
                elif event.key == K_s:
                    pygame.image.save(self.screen, "sshot.tga")
                    print "Screenshot saved as sshot.tga"
                elif event.key == K_p:
                    self.set_pause()
                elif event.key == cheat_seq[self.cheat_current]:
                    self.cheat_current += 1
                    print self.cheat_current
                    if len(cheat_seq) == self.cheat_current:
                        print 'Cheater!'
                        self.cheat_current = 0
                        self.level.phase = 5
                        self.level.t = 0
                        self.spawn_enemies()
            elif event.type == KEYUP:
                if event.key == K_LEFT:
                    self.player.move_left(False)
                elif event.key == K_RIGHT:
                    self.player.move_right(False)
        
        tiling = util.get_tiling()
        if tiling == -1:
            self.player.move_left(True)
        elif tiling == 1:
            self.player.move_right(True)
        #if framecount > 1:
        #    print "Missed " + str(framecount - 1) + " frames!"

    def set_pause(self):
        self.pause = not self.pause

    def draw(self):
        self.screen.blit(self.sky, self.screen.get_rect())
        self.screen.blit(self.pause_icon, (SCREEN_WIDTH - 32, 0))
        self.health_sprite.draw(self.screen)
        self.score_sprite.draw(self.screen)
        self.player_sprite.draw(self.screen)
        self.powerup_sprites.draw(self.screen)
        self.pirate_sprites.draw(self.screen)
        if self.titanic:
            self.titanic_sprite.draw(self.screen)
        self.seagull_sprites.draw(self.screen)
        cloud.draw(self.screen)
        self.shark_sprites.draw(self.screen)
        self.mine_sprites.draw(self.screen)
        self.cannonball_sprites.draw(self.screen)
        self.water_sprite.draw(self.screen)
        if not self.noparticles:
            self.particle_sprite.draw(self.screen)

        if self.pause:
            self.screen.blit(self.pause_image, self.pause_rect)

        if self.gameover:
            self.screen.blit(self.gameover_image, self.gameover_rect)

        if self.level.t < 120:
            font = util.load_font("Cosmetica", 16)
            image = None
            i = 0
            if self.level.phase < len(self.level.phase_messages):
              for text in self.level.phase_messages[self.level.phase].split("\n"):
                image = font.render(text, True, (0,0,0))
                rect = image.get_rect()
                rect.centerx = self.screen.get_rect().centerx
                rect.top = 100 + rect.height * i
                blit_image = pygame.Surface((image.get_width(), image.get_height()))
                blit_image.fill((166,183,250))
                blit_image.set_colorkey((166,183,250))
                blit_image.blit(image, image.get_rect())
                if self.level.t > 60:
                    blit_image.set_alpha(255 - (self.level.t - 60) * 255 / 60)
                self.screen.blit(blit_image, rect)
                i += 1

        pygame.display.flip()



    def check_collisions(self):
        collisions = PixelPerfect.spritecollide_pp(self.player, self.powerup_sprites, 0)
        for powerup in collisions:
            if not powerup.fading:
                if not self.player.dying:
                    self.health.add()
                    powerup.pickup()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.mine_sprites, 0)

        for mine in collisions:
            if not mine.exploding:
                if not self.player.dying:
                    self.health.damage()
                    mine.explode()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.shark_sprites, 0)

        for shark in collisions:
            if not shark.dying:
                if not self.player.dying:
                    self.health.damage()
                    shark.die()

        collisions = PixelPerfect.spritecollide_pp(self.player, self.cannonball_sprites, 0)

        for cb in collisions:
            if not self.player.dying:
                self.health.damage()
                self.cannonballs.remove(cb)
                self.cannonball_sprites.remove(cb)
                Mine.sound.play() # Umm... the mine has a nice explosion sound.

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.shark_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for shark in collisions[cb]:
                # The test on cb.vect is a rude hack preventing cannonballs from pirate ships from killing sharks.
                if not shark.dying and cb.vect[0] > 0:
                    self.score.add(15)
                    shark.die()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.seagull_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for seagull in collisions[cb]:
                # cb.vect test is a rude hack preventing pirates from killing seagulls
                if not seagull.dying and cb.vect[0] > 0:
                    self.score.add(75)
                    seagull.die()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites, self.pirate_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for pirate in collisions[cb]:
                # cb.vect hack for preventing pirates from killing each other
                if not pirate.dying and cb.vect[0] > 0:
                    Mine.sound.play() # Umm... the mine has a nice sound.
                    self.score.add(25)
                    pirate.damage()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

        if self.titanic:
            collisions = PixelPerfect.spritecollide_pp(self.titanic, self.cannonball_sprites, 0)
            for cb in collisions:
                if not self.titanic.dying and cb.vect[0] > 0:
                    Mine.sound.play()
                    self.score.add(7)
                    self.titanic.damage()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

    def update_enemies(self):
        for mine in self.mines:
            mine.update()
            if mine.exploding:
                if mine.explode_frames == 0:
                    self.mines.remove(mine)
                    self.mine_sprites.remove(mine)
                # this should really be done in the Mine class, but oh well, here's some explosion effects:
                if not self.noparticles:
                    for i in range(3):
                        self.particles.add_explosion_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx))
                        self.particles.add_debris_particle((mine.rect.centerx, mine.rect.top + mine.image.get_rect().centerx))
            if mine.rect.right < self.screen.get_rect().left:
                self.mines.remove(mine)
                self.mine_sprites.remove(mine)

        for shark in self.sharks:
            shark.update()
            if shark.dying:
                if not self.noparticles:
                    self.particles.add_blood_particle(shark.rect.center)
            if shark.rect.right < self.screen.get_rect().left or shark.dead:
                self.sharks.remove(shark)
                self.shark_sprites.remove(shark)

        for pirate in self.pirates:
            pirate.update()
            if pirate.t % 50 == 0 and not pirate.dying:
                # Pirate shoots, this should probably be handled by the Pirateboat class
                cb = Cannonball(pirate.rect, pirate.angle, left = True)
                self.cannonballs.append(cb)
                self.cannonball_sprites.add(cb)
            if pirate.rect.right < self.screen.get_rect().left or pirate.dead:
                self.pirates.remove(pirate)
                self.pirate_sprites.remove(pirate)
            elif pirate.dying:
                if not self.noparticles:
                    for i in range(3):
                        self.particles.add_explosion_particle((pirate.rect.centerx, pirate.rect.centery))
                        self.particles.add_wood_particle((pirate.rect.centerx, pirate.rect.centery))

        if self.titanic:
            self.titanic.update()
            if self.titanic.t % 100 == 0 and not self.titanic.dying:
                for i in range(3):
                    cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 50, left = True)
                    self.cannonballs.append(cb)
                    self.cannonball_sprites.add(cb)
            elif self.titanic.t % 100 == 50 and not self.titanic.dying:
                for i in range(3):
                    cb = Cannonball(self.titanic.rect, self.titanic.angle + (i-1)*10 - 60, left = True)
                    self.cannonballs.append(cb)
                    self.cannonball_sprites.add(cb)
            if self.titanic.dead:
                self.set_gameover("Congratulations!\nYou sunk Titanic!")
                self.titanic = None

        for seagull in self.seagulls:
            seagull.update()
            if seagull.rect.right < 0 or seagull.dead:
                self.seagulls.remove(seagull)
                self.seagull_sprites.remove(seagull)

    def spawn_enemies(self):
        spawns = self.level.get_spawns()
        if spawns[Level.SHARKS]:
            # Make a new shark
            self.sharks.append(Shark())
            self.shark_sprites.add(self.sharks[-1])

        if spawns[Level.PIRATES]:
            # Make a new pirate ship
            self.pirates.append(Pirateboat())
            self.pirate_sprites.add(self.pirates[-1])

        if spawns[Level.MINES]:
            self.mines.append(Mine())
            self.mine_sprites.add(self.mines[-1])

        if spawns[Level.SEAGULLS]:
            self.seagulls.append(Seagull())
            self.seagull_sprites.add(self.seagulls[-1])

        if spawns[Level.TITANIC]:
            self.titanic = Titanic()
            self.titanic_sprite.add(self.titanic)

        if spawns[Level.POWERUPS]:
            self.powerups.append(Powerup())
            self.powerup_sprites.add(self.powerups[-1])
Exemple #8
0
class Game(object):
    bgColor = [208, 229, 246]
    textColor = (236, 247, 255)

    def __init__(self, screen, timer, custom=False):
        self.screen = screen
        self.timer = timer

        '''Game Mode'''
        if custom != False:  # 0, if no platforms are drawn
            self.custom = True
            if isinstance(custom, list):
                self.customPlatTypes = custom
                self.customNumPlatforms = None
            else:
                self.customNumPlatforms = custom
                self.customPlatTypes = None
        else:
            self.custom = False

        '''Game Mechanics'''
        self.totalGameTime = 1000
        self.gameover = False
        self.gameover_image = None
        self.gameover_rect = None
        self.pause = False
        self.done = False
        font = load.load_font("OpenSans-Semibold", 40)
        self.pause_image = font.render("Paused", True, (236, 247, 255))
        self.pause_rect = self.pause_image.get_rect()
        self.pause_rect.center = self.screen.get_rect().center
        self.exit = True
        self.showFPS = False
        self.noCrashes = False

        '''Background'''
        self.bg = Surface((32, 32))
        self.bgTime = 0
        self.bgColor = Game.bgColor
        self.sundownTime = 0
        self.rainStart = random.randint(0, self.totalGameTime)
        self.rainEnd = self.rainStart + random.randint(150, 500)
        self.rainEndColor = None
        self.darkenTime = (self.rainEnd - self.rainStart) / 3
        self.lightenTime = 2 * (self.rainEnd - self.rainStart) / 3
        self.raining = self.darkening = self.lightening = False
        self.snowing = False
        self.snow = Snow()

        '''Game entities'''
        self.entities = pygame.sprite.Group()
        self.rocks = pygame.sprite.Group()
        self.trees = pygame.sprite.Group()
        self.birds = pygame.sprite.Group()
        self.coins = pygame.sprite.Group()
        self.ice = pygame.sprite.Group()
        self.player = Player()
        self.entities.add(self.player)
        self.coinCount = 0
        self.flyingBirds = []
        self.collectedCoins = []
        self.clouds = None

        '''Score'''
        self.score = Score()
        self.scoreSprite = pygame.sprite.Group()
        self.scoreSprite.add(self.score)

        '''Platforms'''
        self.platforms = []
        self.numPlatforms = 30
        self.generatePlatforms()
        self.createPlatforms()

        '''Camera'''
        self.totalWidth = 1024 * len(self.platformTypes)
        self.totalHeight = 800
        self.camera = Camera(complex_camera, self.totalWidth, self.totalHeight)

        '''Generating obstacles'''
        self.iceCoords = makeIce(self.platforms)
        rockInfo = makeRock(self.platforms)
        self.treeDict = makeTrees(self.platforms)
        self.birdDict = generateBirds(self.platforms)
        self.coinDict = makeCoins(self.platforms)
        (self.rockRects, self.rockCoords, self.rockAngles) = \
            (rockInfo[0], rockInfo[1], rockInfo[2])

        # ROCKS
        offset = 1024
        for item in range(1, len(self.rockRects)):
            currentPlatform = self.platforms[item]
            x = self.rockRects[currentPlatform][0] + offset
            y = self.rockRects[currentPlatform][1]
            angle = self.rockAngles[currentPlatform]
            obstacle = random.choice("001")
            rock = Rock(x, y, angle) if obstacle == "0" else Penguin(
                x, y, angle)
            self.rocks.add(rock)
            offset += 1024

        # ICE
        iceOffset = 0
        for item in range(self.numPlatforms):
            currentPlatform = self.platforms[item]
            x = iceOffset
            ice = Ice(x, 299, currentPlatform, self.iceCoords)
            self.ice.add(ice)
            iceOffset += 1024

        # TREES
        offset = 0
        for item in range(len(self.treeDict)):
            currentPlatform = self.platforms[item]
            treeCoords = self.treeDict[currentPlatform]
            for tree in treeCoords:
                x = offset + tree[0]
                yOffset = random.randint(5, 20)
                y = tree[1] + 300 + yOffset
                tree = Tree(x, y)
                self.trees.add(tree)
            offset += 1024

        # BIRBS & COINS
        offset = 0
        for item in range(self.numPlatforms):
            currentPlatform = self.platforms[item]
            coords = self.birdDict[currentPlatform]
            coinCoords = self.coinDict[currentPlatform]
            if coords != None:
                for point in coords:
                    x = offset + point[0]
                    y = point[1]
                    bird = Bird(x, y, 0)
                    self.birds.add(bird)
            if coinCoords != None:
                for coin in coinCoords:
                    x = offset + coin[0]
                    y = coin[1]
                    coin = Coin(x, y)
                    self.coins.add(coin)
            offset += 1024

    def run(self):
        while not self.done:
            if not self.pause:
                # update all game entities
                self.camera.update(self.player)
                self.groundSpeed = \
                    self.player.update(
                        self.platforms, self.iceCoords, self.rocks)
                clouds.update(self.bgTime, self.totalGameTime, self.raining)

                for bird in self.birds:
                    if pixelPerfectCollision(self.player, bird) != None:
                        birds.update(bird)
                        self.flyingBirds.append(bird)

                if self.flyingBirds != []:  # bird animation
                    for bird in self.flyingBirds:
                        if bird.rect.top >= 0:
                            birds.update(bird)
                        else:
                            self.flyingBirds.remove(bird)
                            self.birds.remove(bird)

                for c in self.coins:
                    if pixelPerfectCollision(self.player, c) != None:
                        self.bgTime -= 1
                        coin.update(c)
                        self.collectedCoins.append([c, 0])

                if self.collectedCoins != []:  # coin animation
                    existCoins = False
                    for i in range(len(self.collectedCoins)):
                        c, num = self.collectedCoins[i]
                        if c != None and num != None:
                            existCoins = True
                            if num <= 20:
                                coin.update(c)
                                num += 1
                                self.collectedCoins[i] = [c, num]
                            else:
                                self.collectedCoins[i] = [None, None]
                                self.coins.remove(c)
                    if not existCoins:
                        self.collectedCoins = []  # no coins to update

                if self.raining:
                    self.rain.update()
                if self.snowing:
                    self.snow.update()

                particles.update(self.player.rect.centerx,
                                 self.player.rect.centery, self.player.angle,
                                 self.groundSpeed)
                if self.player.crashed and not self.noCrashes:
                    self.exit = False
                    self.setGameOver("You crashed! Press ENTER to exit.")
                elif self.player.crashed and self.noCrashes:
                    self.player.crashed = False
                elif self.player.tooSteep and self.custom:
                    self.exit = False
                    self.setGameOver(
                        "The slopes are too steep! Press ENTER to exit.")
                self.score.add(self.player.getScore())
            self.draw()
            self.handleEvents()
        return self.score.getScore()

    def draw(self):
        self.bg.convert()
        if not self.pause:
            self.bgTime += 1
        if self.bgTime + 1 == self.totalGameTime:
            print(self.player.rect.right // 1024)
            self.exit = False
            self.bgTime += 1  # avoid an endless loop
            self.setGameOver("Time's Up! Press ENTER to exit.")

        if self.bgTime % 5 == 0:
            if self.darkening or self.lightening or self.raining:
                self.bgColor = self.rainSky()
            else:
                self.bgColor = self.getTimeColor()

        color = (self.bgColor[0], self.bgColor[1], self.bgColor[2])
        try:
            self.bg.fill(color)
        except:
            self.bg.fill((59, 82, 119))

        # blit the background
        for y in range(32):
            for x in range(32):
                self.screen.blit(self.bg, (x * 32, y * 32))

        # draw the sun based on "time of day"
        sun = pygame.transform.scale(load.load_image("sun"), (150, 150))
        if 50 + (SCREEN_HEIGHT) * (self.bgTime / self.totalGameTime) <= 400:
            self.screen.blit(sun, (SCREEN_WIDTH - 150 - 50 *
                            (self.bgTime / self.totalGameTime),
                     50 + (SCREEN_HEIGHT) * (self.bgTime / self.totalGameTime)))

        if abs((50 + (SCREEN_HEIGHT) * (self.bgTime / self.totalGameTime))
                - 250) <= 2:
            self.sundownTime = self.bgTime

        # draw game entities
        for tree in self.trees:
            self.screen.blit(tree.image, self.camera.apply(tree))
        for e in self.entities:
            self.screen.blit(e.image, self.camera.apply(e))
        for ice in self.ice:
            self.screen.blit(ice.image, self.camera.apply(ice))
        for rock in self.rocks:
            self.screen.blit(rock.image, self.camera.apply(rock))
        for bird in self.birds:
            self.screen.blit(bird.image, self.camera.apply(bird))
        for coin in self.coins:
            self.screen.blit(coin.image, self.camera.apply(coin))

        self.scoreSprite.draw(self.screen)
        clouds.draw(self.screen)
        player.drawMessage(self.screen)

        if self.snowing:
            self.snow.draw(self.screen)

        self.checkForRain()

        particles.draw(self.screen, self.camera)

        # Draw game info
        font = load.load_font("Nexa Light", 30)
        fps = font.render("FPS: " + str(int(self.timer.get_fps())),
                          True, Game.textColor)
        speed = font.render("Speed: " + str(int(self.groundSpeed)),
                            True, Game.textColor)
        if self.showFPS:
            self.screen.blit(fps, (50, 60))
        self.screen.blit(speed, (SCREEN_WIDTH - 200, 30))
        timeLeft = "Time Left: "
        timer = font.render(timeLeft, True, Game.textColor)
        rect = timer.get_rect()
        rect.right = int(self.screen.get_rect().centerx)
        rect.top = 30
        self.screen.blit(timer, rect)
        time = font.render(str(self.totalGameTime - self.bgTime),
                           True, Game.textColor)
        rect = time.get_rect()
        rect.left = int(self.screen.get_rect().centerx)
        rect.top = 30
        self.screen.blit(time, rect)

        if self.gameover:
            if self.exit == False:  # when time runs out
                self.pause = True
                self.screen.blit(self.gameover_image, self.gameover_rect)
            else:
                self.done = True

        pygame.display.update()

    def handleEvents(self):
        self.timer.tick(60)
        for e in pygame.event.get():
            if e.type == QUIT or (e.type == KEYDOWN and e.key == K_ESCAPE):
                self.done = True
                pygame.quit()
                sys.exit()
            elif e.type == KEYDOWN:
                if not self.pause:
                    if e.key == K_UP:
                        self.player.moveUp(True)
                    if e.key == K_SPACE:
                        self.player.rotate(True)
                    # cheat: make it rain
                    if e.key == K_r:
                        self.bgTime = self.rainStart
                    # cheat: make it snow
                    if e.key == K_s:
                        self.snowing = not self.snowing
                    # cheat: show FPS
                    if e.key == K_f:
                        self.showFPS = not self.showFPS
                    # cheat: approach end of game
                    if e.key == K_e:
                        self.bgTime = self.totalGameTime - 50
                        self.rainStartColor = 0
                        if self.sundownTime == 0:
                            self.sundownTime = 1
                    # cheat: alter player speeds
                    if e.key == K_z:
                        self.player.groundSpeed += 1
                    elif e.key == K_x:
                        self.player.groundSpeed -= 1
                    # cheat: no crashing!
                    if e.key == K_c:
                        self.noCrashes = not self.noCrashes
                if e.key == K_p:
                    self.pause = not self.pause
                if self.gameover and e.key == K_RETURN:
                    self.exit = True
            elif e.type == KEYUP:
                if e.key == K_UP:
                    self.player.moveUp(False)
                if e.key == K_SPACE:
                    self.player.rotate(False)

    def createPlatforms(self, start=0):
        x = start
        y = 300
        for c in self.platformTypes:
            platformTypes = str(c)
            p = Platform(x, y, platformTypes)
            self.platforms.append(p)
            self.entities.add(p)
            x += p.width

    def generatePlatforms(self):
        self.platformTypes = ["start"]
        for i in range(self.numPlatforms):
            if self.custom:
                if self.customPlatTypes != None:
                    selections = "".join(self.customPlatTypes)
                    r = random.choice(selections)
                    platform = str(int(r) * 100)
                    self.platformTypes.append(platform)

                else: self.platformTypes.append(str(random.randint(1,
                                                self.customNumPlatforms) * 100))
            else:
                # randomly chooses platforms; weighted probability
                self.platformTypes.append(random.choice("911223344556"))
        return self.platformTypes

    def checkForRain(self):
        if abs(self.rainStart - self.bgTime) <= 1:
            # it started raining
            self.rain = Rain()
            self.rainStartColor = self.getTimeColor()
            self.darkening = True

        if self.rainStart < self.bgTime < self.rainEnd:
            # it is raining
            self.raining = True
            self.rain.draw(self.screen)
        else:
            # it's not raining
            self.raining = False

        if abs(self.bgTime - (self.rainStart + self.darkenTime)) <= 1:
            # sky is done darkening
            self.darkening = False

        if abs(self.bgTime - (self.rainStart + self.lightenTime)) <= 1:
            # 2/3 of rain is done, start lightening sky
            self.rainEndColor = self.getTimeColor(
                self.rainEnd + 40)  
            # anticipated color
            self.lightening = True

        if abs(self.bgTime - self.rainEnd - 40) <= 1:
            self.lightening = False

    def getTimeColor(self, time=None):  
        # throwback to rgb color blender
        if time != None:
            bgTime = time
        else:
            bgTime = self.bgTime
        if self.sundownTime != 0:
            # fraction of time elapsed
            r = 208 - ((208 - 59) *
                       ((bgTime - self.sundownTime) / self.totalGameTime))
            g = 229 - ((229 - 82) *
                       ((bgTime - self.sundownTime) / self.totalGameTime))
            b = 246 - ((246 - 119) *
                       ((bgTime - self.sundownTime) / self.totalGameTime))
            if r < 59:
                r = 59
            if g < 82:
                g = 82
            if b < 119:
                b = 119
            return [int(r), int(g), int(b)]
        else:
            return Game.bgColor

    def rainSky(self):
        if self.darkening:
            if self.bgTime <= self.rainStart + self.darkenTime:
                timeElapsed = (self.bgTime - self.rainStart)
                r = (self.rainStartColor[0] - ((self.rainStartColor[0] - 135)
                                               * timeElapsed / self.darkenTime))
                g = (self.rainStartColor[1] - ((self.rainStartColor[1] - 156)
                                               * timeElapsed / self.darkenTime))
                b = (self.rainStartColor[2] - ((self.rainStartColor[2] - 183)
                                               * timeElapsed / self.darkenTime))
                return [int(r), int(g), int(b)]
            else:
                return [135, 156, 183]
        elif self.lightening:
            secondsElapsed = self.bgTime - (self.rainEnd - self.darkenTime)
            if abs(secondsElapsed - (self.rainEnd - self.darkenTime + 40)) <= 5:
                self.raining = self.lightening = self.darkening = False
                # rain effects are over
                return self.rainEndColor
            else:
                a = self.rainEnd - self.darkenTime + 40
                color = self.rainEndColor
                r, g, b = color[0], color[1], color[2]
                newR = int(135 - (135 - r) * (secondsElapsed / a))
                newG = int(156 - (156 - g) * (secondsElapsed / a))
                newB = int(183 - (183 - g) * (secondsElapsed / a))
                return [int(newR), int(newG), int(newB)]
        else:  # just raining
            return [135, 156, 183]

    def setGameOver(self, message="Game Over"):
        # sets game over, shows a message depending on cause of death
        self.gameover = True
        images = []
        font = load.load_font("Nexa Light", 30)
        height = 0
        width = 0
        for text in message.split("\n"):
            images.append(font.render(text, True, (25, 51, 71)))
            height += images[-1].get_height()
            width = images[-1].get_width()
        self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32)
        self.gameover_image.fill((0, 0, 0, 0))
        for i in range(len(images)):
            rect = images[i].get_rect()
            rect.top = i * images[i].get_height()
            rect.centerx = width / 2
            self.gameover_image.blit(images[i], rect)

        self.gameover_rect = self.gameover_image.get_rect()
        self.gameover_rect.center = self.screen.get_rect().center
Exemple #9
0
class Game:
    def __init__(self,
                 screen,
                 usealpha=True,
                 noparticles=False,
                 endless=False):
        self.screen = screen
        self.usealpha = usealpha
        self.noparticles = noparticles

        self.sharks = []
        self.shark_sprites = pygame.sprite.Group()

        self.player = Steamboat()
        self.player_sprite = pygame.sprite.Group()
        self.player_sprite.add(self.player)

        self.health = Health()
        self.health_sprite = pygame.sprite.Group()
        self.health_sprite.add(self.health)

        self.damage_count = 0

        self.t = 0

        self.water = Water.global_water  #Water(self.usealpha)
        #Water.global_water = self.water
        self.water_sprite = pygame.sprite.Group()
        self.water_sprite.add(self.water)

        self.sky = util.load_image("taivas")
        self.sky = pygame.transform.scale(self.sky,
                                          (SCREEN_WIDTH, SCREEN_HEIGHT))

        self.cannonballs = []
        self.cannonball_sprites = pygame.sprite.Group()

        self.pirates = []
        self.pirate_sprites = pygame.sprite.Group()

        self.titanic = None
        self.titanic_sprite = pygame.sprite.Group()

        self.seagulls = []
        self.seagull_sprites = pygame.sprite.Group()

        self.particles = Particles(self.usealpha)
        self.particle_sprite = pygame.sprite.Group()
        self.particle_sprite.add(self.particles)

        self.mines = []
        self.mine_sprites = pygame.sprite.Group()

        self.score = Score()
        self.score_sprite = pygame.sprite.Group()
        self.score_sprite.add(self.score)

        self.powerups = []
        self.powerup_sprites = pygame.sprite.Group()

        self.level = Level(endless)

        self.lastshot = MIN_FIRE_DELAY + 1

        self.gameover = False
        self.gameover_image = None
        self.gameover_rect = None
        self.done = False

        self.pause = False
        font = util.load_font(
            "Cosmetica",
            40)  #pygame.font.Font(pygame.font.get_default_font(), 36)
        self.pause_image = font.render("Pause", True, (0, 0, 0))
        self.pause_rect = self.pause_image.get_rect()
        self.pause_rect.center = self.screen.get_rect().center

    def run(self):
        while not self.done:
            if not self.pause:
                if not self.gameover:
                    self.spawn_enemies()

                self.update_enemies()
                self.player.update()
                self.health.update()
                cloud.update()
                for cb in self.cannonballs:
                    cb.update()
                    if (cb.rect.right < 0
                            and cb.vect[0] < 0) or (cb.rect.left > SCREEN_WIDTH
                                                    and cb.vect[0] > 0):
                        self.cannonballs.remove(cb)
                        self.cannonball_sprites.remove(cb)
                self.score.update()

                # Add steam particles
                if not self.noparticles:
                    for i in range(3):
                        particle_point = self.player.get_point(
                            (5.0 + random.random() * 9.0, 0))
                        particle_point[0] += self.player.rect.centerx
                        particle_point[1] += self.player.rect.centery
                        self.particles.add_steam_particle(particle_point)

                    for i in range(3):
                        particle_point = self.player.get_point(
                            (19.0 + random.random() * 7.0, 5.0))
                        particle_point[0] += self.player.rect.centerx
                        particle_point[1] += self.player.rect.centery
                        self.particles.add_steam_particle(particle_point)

                    if self.titanic:
                        for j in range(4):
                            for i in range(3):
                                particle_point = self.titanic.get_point(
                                    (49 + random.random() * 9.0 + 28 * j, 25))
                                particle_point[0] += self.titanic.rect.centerx
                                particle_point[1] += self.titanic.rect.centery
                                self.particles.add_steam_particle(
                                    particle_point)

                    self.particles.update()

                self.water.update()

                if self.player.splash:
                    if not self.noparticles:
                        for i in range(30):
                            r = random.random()
                            x = int(r * self.player.rect.left +
                                    (1.0 - r) * self.player.rect.right)
                            point = (x, self.water.get_water_level(x))
                            self.particles.add_water_particle(point)

                for powerup in self.powerups:
                    powerup.update()
                    if powerup.picked:
                        self.powerups.remove(powerup)
                        self.powerup_sprites.remove(powerup)

                if not self.gameover:
                    self.check_collisions()

                if self.health.hearts_left == 0 and not self.player.dying:
                    self.player.die()

                if self.player.dying and not self.player.dead:
                    if not self.noparticles:
                        for i in range(3):
                            self.particles.add_explosion_particle(
                                (self.player.rect.centerx,
                                 self.player.rect.centery))
                            self.particles.add_debris_particle(
                                (self.player.rect.centerx,
                                 self.player.rect.centery))

                if self.player.dead:
                    #self.done = True
                    self.set_gameover()

                if self.damage_count > 0:
                    self.damage_count -= 1
                self.lastshot += 1
                self.t += 1

            self.draw()

            self.handle_events()

        return self.score.get_score()

    def set_gameover(self, message="Game Over"):
        self.gameover = True
        images = []
        font = util.load_font(
            "Cosmetica",
            40)  #pygame.font.Font(pygame.font.get_default_font(), 36)
        height = 0
        width = 0
        for text in message.split("\n"):
            images.append(font.render(text, True, (0, 0, 0)))
            height += images[-1].get_height()
            if images[-1].get_width() > width:
                width = images[-1].get_width()
        self.gameover_image = pygame.Surface((width, height), SRCALPHA, 32)
        self.gameover_image.fill((0, 0, 0, 0))
        for i in range(len(images)):
            rect = images[i].get_rect()
            rect.top = i * images[i].get_height()
            rect.centerx = width / 2
            self.gameover_image.blit(images[i], rect)

        self.gameover_rect = self.gameover_image.get_rect()
        self.gameover_rect.center = self.screen.get_rect().center

    def handle_events(self):
        nextframe = False
        framecount = 0
        while not nextframe:
            # wait until there's at least one event in the queue
            pygame.event.post(pygame.event.wait())
            for event in pygame.event.get():
                #event = pygame.event.wait()
                if event.type == QUIT or \
                   event.type == KEYDOWN and event.key == K_ESCAPE:
                    self.done = True
                    nextframe = True
                elif event.type == NEXTFRAME:
                    nextframe = True
                    framecount += 1
                elif self.gameover:
                    if event.type == JOYBUTTONDOWN:
                        self.done = True
                        nextframe = True
                    elif event.type == KEYDOWN:
                        self.done = True
                        nextframe = True
                    continue
                elif event.type == JOYAXISMOTION:
                    if event.axis == 0:
                        if event.value < -0.5:
                            self.player.move_left(True)
                        elif event.value > 0.5:
                            self.player.move_right(True)
                        else:
                            self.player.move_left(False)
                            self.player.move_right(False)
                elif event.type == JOYBUTTONDOWN:
                    if event.button == 0:
                        if not self.pause:
                            self.player.jump()
                    elif event.button == 1:
                        if not self.pause:
                            if self.lastshot > MIN_FIRE_DELAY and not self.player.dying:
                                cb = Cannonball(self.player.rect,
                                                self.player.angle)
                                self.cannonballs.append(cb)
                                self.cannonball_sprites.add(cb)
                                self.lastshot = 0
                    elif event.button == 5:
                        pygame.image.save(self.screen, "sshot.tga")
                        print "Screenshot saved as sshot.tga"
                    elif event.button == 8:
                        self.set_pause()
                elif event.type == KEYDOWN:
                    if event.key == K_LEFT:
                        self.player.move_left(True)
                    elif event.key == K_RIGHT:
                        self.player.move_right(True)
                    elif event.key == K_SPACE:
                        if not self.pause:
                            # Only 3 cannonballs at once
                            # Maximum firing rate set at the top
                            if self.lastshot > MIN_FIRE_DELAY and not self.player.dying:
                                cb = Cannonball(self.player.rect,
                                                self.player.angle)
                                self.cannonballs.append(cb)
                                self.cannonball_sprites.add(cb)
                                self.lastshot = 0
                    elif event.key == K_UP:
                        if not self.pause:
                            self.player.jump()
                    elif event.key == K_s:
                        pygame.image.save(self.screen, "sshot.tga")
                        print "Screenshot saved as sshot.tga"
                    elif event.key == K_p:
                        self.set_pause()
                elif event.type == KEYUP:
                    if event.key == K_LEFT:
                        self.player.move_left(False)
                    elif event.key == K_RIGHT:
                        self.player.move_right(False)

        #if framecount > 1:
        #    print "Missed " + str(framecount - 1) + " frames!"

    def set_pause(self):
        self.pause = not self.pause

    def draw(self):
        self.screen.blit(self.sky, self.screen.get_rect())
        self.health_sprite.draw(self.screen)
        self.score_sprite.draw(self.screen)
        self.player_sprite.draw(self.screen)
        self.powerup_sprites.draw(self.screen)
        self.pirate_sprites.draw(self.screen)
        if self.titanic:
            self.titanic_sprite.draw(self.screen)
        self.seagull_sprites.draw(self.screen)
        cloud.draw(self.screen)
        self.shark_sprites.draw(self.screen)
        self.mine_sprites.draw(self.screen)
        self.cannonball_sprites.draw(self.screen)
        self.water_sprite.draw(self.screen)
        if not self.noparticles:
            self.particle_sprite.draw(self.screen)

        if self.pause:
            self.screen.blit(self.pause_image, self.pause_rect)

        if self.gameover:
            self.screen.blit(self.gameover_image, self.gameover_rect)

        if self.level.t < 120:
            font = util.load_font("Cosmetica", 16)
            image = None
            i = 0
            if self.level.phase < len(self.level.phase_messages):
                for text in self.level.phase_messages[self.level.phase].split(
                        "\n"):
                    image = font.render(text, True, (0, 0, 0))
                    rect = image.get_rect()
                    rect.centerx = self.screen.get_rect().centerx
                    rect.top = 100 + rect.height * i
                    blit_image = pygame.Surface(
                        (image.get_width(), image.get_height()))
                    blit_image.fill((166, 183, 250))
                    blit_image.set_colorkey((166, 183, 250))
                    blit_image.blit(image, image.get_rect())
                    if self.level.t > 60:
                        blit_image.set_alpha(255 -
                                             (self.level.t - 60) * 255 / 60)
                    self.screen.blit(blit_image, rect)
                    i += 1

        pygame.display.flip()

    def check_collisions(self):
        collisions = PixelPerfect.spritecollide_pp(self.player,
                                                   self.powerup_sprites, 0)
        for powerup in collisions:
            if not powerup.fading:
                if not self.player.dying:
                    self.health.add()
                    powerup.pickup()

        collisions = PixelPerfect.spritecollide_pp(self.player,
                                                   self.mine_sprites, 0)

        for mine in collisions:
            if not mine.exploding:
                if not self.player.dying:
                    self.health.damage()
                    mine.explode()

        collisions = PixelPerfect.spritecollide_pp(self.player,
                                                   self.shark_sprites, 0)

        for shark in collisions:
            if not shark.dying:
                if not self.player.dying:
                    self.health.damage()
                    shark.die()

        collisions = PixelPerfect.spritecollide_pp(self.player,
                                                   self.cannonball_sprites, 0)

        for cb in collisions:
            if not self.player.dying:
                self.health.damage()
                self.cannonballs.remove(cb)
                self.cannonball_sprites.remove(cb)
                Mine.sound.play(
                )  # Umm... the mine has a nice explosion sound.

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites,
                                                  self.shark_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for shark in collisions[cb]:
                # The test on cb.vect is a rude hack preventing cannonballs from pirate ships from killing sharks.
                if not shark.dying and cb.vect[0] > 0:
                    self.score.add(15)
                    shark.die()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites,
                                                  self.seagull_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for seagull in collisions[cb]:
                # cb.vect test is a rude hack preventing pirates from killing seagulls
                if not seagull.dying and cb.vect[0] > 0:
                    self.score.add(75)
                    seagull.die()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

        collisions = PixelPerfect.groupcollide_pp(self.cannonball_sprites,
                                                  self.pirate_sprites, 0, 0)

        for cb in dict.keys(collisions):
            for pirate in collisions[cb]:
                # cb.vect hack for preventing pirates from killing each other
                if not pirate.dying and cb.vect[0] > 0:
                    Mine.sound.play()  # Umm... the mine has a nice sound.
                    self.score.add(25)
                    pirate.damage()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

        if self.titanic:
            collisions = PixelPerfect.spritecollide_pp(self.titanic,
                                                       self.cannonball_sprites,
                                                       0)
            for cb in collisions:
                if not self.titanic.dying and cb.vect[0] > 0:
                    Mine.sound.play()
                    self.score.add(7)
                    self.titanic.damage()
                    self.cannonballs.remove(cb)
                    self.cannonball_sprites.remove(cb)
                    break

    def update_enemies(self):
        for mine in self.mines:
            mine.update()
            if mine.exploding:
                if mine.explode_frames == 0:
                    self.mines.remove(mine)
                    self.mine_sprites.remove(mine)
                # this should really be done in the Mine class, but oh well, here's some explosion effects:
                if not self.noparticles:
                    for i in range(3):
                        self.particles.add_explosion_particle(
                            (mine.rect.centerx,
                             mine.rect.top + mine.image.get_rect().centerx))
                        self.particles.add_debris_particle(
                            (mine.rect.centerx,
                             mine.rect.top + mine.image.get_rect().centerx))
            if mine.rect.right < self.screen.get_rect().left:
                self.mines.remove(mine)
                self.mine_sprites.remove(mine)

        for shark in self.sharks:
            shark.update()
            if shark.dying:
                if not self.noparticles:
                    self.particles.add_blood_particle(shark.rect.center)
            if shark.rect.right < self.screen.get_rect().left or shark.dead:
                self.sharks.remove(shark)
                self.shark_sprites.remove(shark)

        for pirate in self.pirates:
            pirate.update()
            if pirate.t % 50 == 0 and not pirate.dying:
                # Pirate shoots, this should probably be handled by the Pirateboat class
                cb = Cannonball(pirate.rect, pirate.angle, left=True)
                self.cannonballs.append(cb)
                self.cannonball_sprites.add(cb)
            if pirate.rect.right < self.screen.get_rect().left or pirate.dead:
                self.pirates.remove(pirate)
                self.pirate_sprites.remove(pirate)
            elif pirate.dying:
                if not self.noparticles:
                    for i in range(3):
                        self.particles.add_explosion_particle(
                            (pirate.rect.centerx, pirate.rect.centery))
                        self.particles.add_wood_particle(
                            (pirate.rect.centerx, pirate.rect.centery))

        if self.titanic:
            self.titanic.update()
            if self.titanic.t % 100 == 0 and not self.titanic.dying:
                for i in range(3):
                    cb = Cannonball(self.titanic.rect,
                                    self.titanic.angle + (i - 1) * 10 - 50,
                                    left=True)
                    self.cannonballs.append(cb)
                    self.cannonball_sprites.add(cb)
            elif self.titanic.t % 100 == 50 and not self.titanic.dying:
                for i in range(3):
                    cb = Cannonball(self.titanic.rect,
                                    self.titanic.angle + (i - 1) * 10 - 60,
                                    left=True)
                    self.cannonballs.append(cb)
                    self.cannonball_sprites.add(cb)
            if self.titanic.dead:
                self.set_gameover("Congratulations!\nYou sunk Titanic!")
                self.titanic = None

        for seagull in self.seagulls:
            seagull.update()
            if seagull.rect.right < 0 or seagull.dead:
                self.seagulls.remove(seagull)
                self.seagull_sprites.remove(seagull)

    def spawn_enemies(self):
        spawns = self.level.get_spawns()
        if spawns[Level.SHARKS]:
            # Make a new shark
            self.sharks.append(Shark())
            self.shark_sprites.add(self.sharks[-1])

        if spawns[Level.PIRATES]:
            # Make a new pirate ship
            self.pirates.append(Pirateboat())
            self.pirate_sprites.add(self.pirates[-1])

        if spawns[Level.MINES]:
            self.mines.append(Mine())
            self.mine_sprites.add(self.mines[-1])

        if spawns[Level.SEAGULLS]:
            self.seagulls.append(Seagull())
            self.seagull_sprites.add(self.seagulls[-1])

        if spawns[Level.TITANIC]:
            self.titanic = Titanic()
            self.titanic_sprite.add(self.titanic)

        if spawns[Level.POWERUPS]:
            self.powerups.append(Powerup())
            self.powerup_sprites.add(self.powerups[-1])