示例#1
0
def playgame(screen, gamestate):

    gamestate.next_level()

    opendoor_snd = pygame.mixer.Sound(data.filepath("open_door.wav"))
    pickup_key_snd = pygame.mixer.Sound(data.filepath("pickup_key.wav"))

    background = pygame.Surface(screen.get_size())
    background = background.convert()
    background.fill(BG_COLOUR)

    timeupfont = pygame.font.SysFont("Arial", 30)

    tbuffer = TextBufferRenderer("Arial", 15)

    m = maze.Maze(22, 18)
    m.generate()
    maze_surface = pygame.Surface((m.width * 16, m.height * 16),
                                  pygame.constants.SRCALPHA,
                                  32).convert_alpha()

    gamestate.maze = m

    #fixed positions
    player_start_node = m.get_node(0, 0)
    player_sprite = RailsThing(gamestate, player_start_node.pos_px)
    gamestate.player = player_sprite
    f = Fog(gamestate)

    lock_start_node = m._data[-1]
    lockspr = LockedDoor(gamestate, lock_start_node.pos_px)

    # ensure everything else is on its own square
    # but not too close to player

    availnodes = [
        x for x in m._data
        if x.distance_from(player_start_node) > INIT_DISTANCE_FROM_PLAYER
    ]
    random.shuffle(availnodes)

    for x in xrange(gamestate.mobs_available):
        n = availnodes.pop()
        mob = Mob(gamestate, n.pos_px)
        if random.choice([True, False, False]):
            mob.toggle_mob_type()
        gamestate.mobs.append(mob)


    availkeynodes = [x for x in m._data if \
                     x.distance_from(player_start_node) > INIT_DISTANCE_FROM_PLAYER and \
                     x.distance_from(lock_start_node) > INIT_DISTANCE_FROM_PLAYER ]
    key_node = random.choice(availkeynodes)
    keyspr = Key(gamestate, key_node.pos_px)

    mutator_surface = pygame.Surface((64, 64), pygame.constants.SRCALPHA,
                                     32).convert_alpha()
    mutator_surface.fill((255, 255, 255, 30))

    charge_surface = surfutil.load_sprite_surface("chargebar.png")
    charge_surface = pygame.transform.scale(
        charge_surface,
        (charge_surface.get_width() * 2, charge_surface.get_height() * 2))

    spark_surface = surfutil.load_sprite_surface("spark.png")

    # blank screen
    screen.blit(background, (0, 0))
    pygame.display.flip()

    clock = pygame.time.Clock()
    start_time = pygame.time.get_ticks()
    MAZE_POS = (16, 16)
    death_count = 0
    raw_click_pos = (0, 0)
    while True:

        # USER INPUT
        # ======================================

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return 'quit'
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                return 'title'
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_g:
                print 'No soup for you GruikInc!'
            #    m.generate()
            #    drawmaze(maze_surface, m)
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                raw_click_pos = pygame.mouse.get_pos()
                #print raw_click_pos
                click_pos = (raw_click_pos[0] - MAZE_POS[0],
                             raw_click_pos[1] - MAZE_POS[1])

                if gamestate.charge == MAX_CHARGE:
                    f.mutate_snd.play()
                    r = pygame.Rect(click_pos, mutator_surface.get_size())
                    selected = set(m.collides_nodes(r))
                    m.regenerate_selected(selected)
                    gamestate.charge = 0

        # UPDATE
        # ======================================

        current_time = pygame.time.get_ticks()
        gamestate.time_left = max(
            int(gamestate.time - (current_time - start_time) / 1000), 0)
        if gamestate.time_left <= 0 and not player_sprite.is_dead:
            player_sprite.die(None)

        player_sprite.update()
        keyspr.update()
        lockspr.update()

        player_hitbox = player_sprite.hitbox
        for mob in gamestate.mobs:
            mob.update()

        for mob in gamestate.alive_mobs:
            if player_hitbox.colliderect(mob.hitbox):
                player_sprite.on_mob_hit(mob)

        if keyspr.follow_sprite is not player_sprite and player_hitbox.colliderect(
                keyspr.hitbox):
            pickup_key_snd.play()
            gamestate.score += 200
            keyspr.follow(player_sprite)

        if keyspr.follow_sprite is player_sprite and lockspr.x == player_sprite.x and lockspr.y == player_sprite.y:
            opendoor_snd.play()
            gamestate.score += 200
            gamestate.mobs_saved = len(player_sprite.mob_followers)
            gamestate.mobs_saved_total += gamestate.mobs_saved
            return 'win'

        f.update()
        if f.passed:
            f = Fog(gamestate)

        if player_sprite.is_dead:
            death_count += 1
            if death_count > 100:
                return 'gameover'

        gamestate.charge = min(MAX_CHARGE, gamestate.charge + CHARGE_PER_FRAME)

        current_time = pygame.time.get_ticks()
        gamestate.sparks = [
            x for x in gamestate.sparks
            if (current_time - x[0]) < SPARK_TIME_MS
        ]

        # RENDER
        # ======================================

        screen.blit(background, (0, 0))

        m.render_to_surface(maze_surface)
        lockspr.render(maze_surface)

        for mob in gamestate.mobs:
            mob.render(maze_surface)
        keyspr.render(maze_surface)

        # make sure we can always see your dude
        player_sprite.render(maze_surface)

        # fog
        f.render(maze_surface)

        #sparks
        for (t, p) in gamestate.sparks:
            maze_surface.blit(spark_surface, p)

        screen.blit(maze_surface, MAZE_POS)

        screen.blit(mutator_surface, pygame.mouse.get_pos())

        tbuffer.clear()
        tbuffer.add("Level: %d" % gamestate.level)
        tbuffer.add("Score: %d" % gamestate.score)

        # print the status
        c = ega.BRIGHT_MAGENTA
        if gamestate.time_left < 15 and gamestate.time_left & 1:
            c = ega.BRIGHT_WHITE
        tbuffer.add("Time: %d" % gamestate.time_left, c)
        tbuffer.render_to_surface(screen, SCORE_POS)

        # print time up msg if needed
        if gamestate.time_left <= 0:
            timeupsurf = timeupfont.render("TIME UP!", True,
                                           ega.BRIGHT_MAGENTA)
            screen.blit(timeupsurf, (128, 100))

        charge_width = int(charge_surface.get_width() * gamestate.charge /
                           MAX_CHARGE)
        charge_area = pygame.Rect(0, 0, charge_width, 100)
        screen.blit(charge_surface, (380, 280), charge_area)

        pygame.display.flip()

        # TIMING
        # ======================================

        clock.tick(30)