示例#1
0
def menu(screen):
    # Clear screen
    screen.fill(BLACK)

    # Set clock
    clock = pygame.time.Clock()

    # Using a ghost as background
    background_ghost_sprite_images = [pygame.image.load("resources/ghost/0" + str(j) + ".png") for j in range(ANIMATION_FRAMES)]
    for j in range(ANIMATION_FRAMES):
        background_ghost_sprite_images[j].convert_alpha()
        background_ghost_sprite_images[j] = pygame.transform.scale(background_ghost_sprite_images[j], (min(WIDTH, HEIGHT), min(WIDTH, HEIGHT)))
    background_ghost = Character.Ghost([[]], background_ghost_sprite_images)
    background_ghost.rect.center = (WIDTH/2, HEIGHT/2)

    # Add text slightly larger than usual
    courier_prime = pygame.font.Font("resources/text/courier.ttf", int(FONT_SIZE*1.5))

    default_grid_image = pygame.transform.scale(pygame.image.load("resources/grid/defaultgrid.png"), (min(WIDTH, HEIGHT)//3, min(WIDTH, HEIGHT)//3))
    default_grid_image_rect = default_grid_image.get_rect()
    default_grid_image_rect.bottomleft = (WIDTH/9, HEIGHT*8/9)

    default_grid_text = courier_prime.render("Default", True, WHITE, GREY)
    default_grid_text_rect = default_grid_text.get_rect()
    default_grid_text_rect.center = (default_grid_image_rect.centerx, default_grid_image_rect.top - FONT_SIZE*2)

    random_grid_image = pygame.transform.scale(pygame.image.load("resources/grid/randomgrid.png"), (min(WIDTH, HEIGHT)//3, min(WIDTH, HEIGHT)//3))
    random_grid_image_rect = random_grid_image.get_rect()
    random_grid_image_rect.bottomright = (WIDTH*8/9, HEIGHT*8/9)

    random_grid_text = courier_prime.render("Random", True, WHITE, GREY)
    random_grid_text_rect = random_grid_text.get_rect()
    random_grid_text_rect.center = (random_grid_image_rect.centerx, random_grid_image_rect.top - FONT_SIZE*2)

    ghost_frame_num = 0

    screen.blit(background_ghost.image, background_ghost.rect)
    screen.blit(default_grid_image, default_grid_image_rect)
    screen.blit(default_grid_text, default_grid_text_rect)
    screen.blit(random_grid_image, random_grid_image_rect)
    screen.blit(random_grid_text, random_grid_text_rect)

    while True:
        ghost_frame_num = (ghost_frame_num+1) % GHOST_FRAMES_PER_CYCLE

        # Process animation
        if ghost_frame_num % FRAMES_PER_ANIMATION_CYCLE == 0:
            background_ghost.image_num += background_ghost.image_delta
            if not (0 <= background_ghost.image_num < ANIMATION_FRAMES):
                background_ghost.image_delta *= -1
                background_ghost.image_num += background_ghost.image_delta
            background_ghost.image = background_ghost.images[background_ghost.image_num]

            screen.fill(BLACK)
            screen.blit(background_ghost.image, background_ghost.rect)
            screen.blit(default_grid_image, default_grid_image_rect)
            screen.blit(default_grid_text, default_grid_text_rect)
            screen.blit(random_grid_image, random_grid_image_rect)
            screen.blit(random_grid_text, random_grid_text_rect)

            pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONUP:
                if default_grid_image_rect.collidepoint(event.pos) or default_grid_text_rect.collidepoint(event.pos):
                    return DEFAULT_GAME_GRID
                if random_grid_image_rect.collidepoint(event.pos) or random_grid_text_rect.collidepoint(event.pos):
                    return generate_grid()
        
        clock.tick(100)
示例#2
0
def play(screen, game_grid):
    # Game variables
    obj_grid = game_grid # Grid containing each Way object
    num_dots = 0
    clock = pygame.time.Clock()

    # Game resources
    courier_prime = pygame.font.Font("resources/text/courier.ttf", FONT_SIZE)

    player_sprite_images = [pygame.image.load("resources/player/player.png")]
    player_sprite_images[0].convert_alpha()
    player_sprite_images[0] = pygame.transform.scale(player_sprite_images[0], (GRIDWIDTH//COL, GRIDHEIGHT//ROW))

    ghost_sprite_images = [[pygame.image.load("resources/ghost/" + str(i) + str(j) + ".png") for j in range(ANIMATION_FRAMES)] for i in range(GHOSTS)]
    for i in range(GHOSTS):
        for j in range(ANIMATION_FRAMES):
            ghost_sprite_images[i][j].convert_alpha()
            ghost_sprite_images[i][j] = pygame.transform.scale(ghost_sprite_images[i][j], (GRIDWIDTH//COL+4, GRIDHEIGHT//ROW+4))
    
    # Ghost target functions
    ghost_sprite_target_functions = [
        None, # Target straight on player
        lambda player: (player.gc[0] + 8*player.movement[0] + random.randint(-5, 5), player.gc[1] + 8*player.movement[1] + random.randint(-5, 5)), # Target somewhere in front of player
        lambda player: (player.gc[0] - 4*player.movement[0] + random.randint(-5, 5), player.gc[1] - 4*player.movement[1] + random.randint(-5, 5)), # Target somewhere behind player
        lambda player: (player.gc[0] + random.randint(-15, 15), player.gc[1] + random.randint(-15, 15)), # Target randomly near player
        lambda player: (player.gc[0] + random.randint(-15, 15), player.gc[1] + random.randint(-15, 15)) # Target randomly near player
    ]

    # Sprite groups
    walls = pygame.sprite.Group()
    ways = pygame.sprite.Group()
    ghosts = pygame.sprite.Group()
    player = Character.Player(game_grid, player_sprite_images)

    for i in range(GHOSTS):
        ghosts.add(Character.Ghost(game_grid, ghost_sprite_images[i], target=ghost_sprite_target_functions[i]))

    # For consistency, the coordinate system also starts from top left corner
    for r in range(ROW):
        for c in range(COL):
            if game_grid[r][c]:
                if (r, c) in [(0, ROW-1), (COL-1, 0)]:
                    cell = Grid.Way(c, r, dot=False)
                else:
                    cell = Grid.Way(c, r)
                    num_dots += 1
                obj_grid[r][c] = cell
                ways.add(cell)
            else:
                walls.add(Grid.Wall(c, r))
    
    # For score keeping purposes
    total_dots = num_dots

    # How movement is represented in this game is explained in the Character class
    # Frame number
    player_frame_num = 0
    ghost_frame_num = 0

    # Store player's next direction
    next_dir = (0, 0)

    screen.fill(BLACK)
    
    walls.draw(screen)
    ways.draw(screen)

    screen.blit(player.image, player.rect)
    ghosts.draw(screen)
    
    pygame.display.update()

    # Previous character locations to keep track of areas for updating screen
    prev_player_locations = [obj_grid[0][ROW-1].rect, obj_grid[COL-1][0].rect]
    prev_ghost_locations = [obj_grid[0][ROW-1].rect, obj_grid[COL-1][0].rect]

    # Align ghosts
    for ghost in ghosts:
        ghost.turn(ghost.plan(player))
        ghost.move()

    while player.lives:
        player_frame_num = (player_frame_num+1) % PLAYER_FRAMES_PER_CYCLE
        ghost_frame_num = (ghost_frame_num+1) % GHOST_FRAMES_PER_CYCLE
        dirty = [] # Parts of screen that need updating

        # Load only necessary areas
        dirty.extend(prev_player_locations)
        dirty.extend(prev_ghost_locations)
        dirty.append(obj_grid[player.gc[1]][player.gc[0]].rect)
        for ghost in ghosts:
            dirty.append(obj_grid[ghost.gc[1]][ghost.gc[0]].rect)
        
        # Process animation
        if ghost_frame_num % FRAMES_PER_ANIMATION_CYCLE == 0:
            for ghost in ghosts:
                ghost.image_num += ghost.image_delta
                if not (0 <= ghost.image_num < ANIMATION_FRAMES):
                    ghost.image_delta *= -1
                    ghost.image_num += ghost.image_delta
                ghost.image = ghost.images[ghost.image_num]
        
        # Process player events
        if player_frame_num == 0:
            # Eat dot event
            if obj_grid[player.gc[1]][player.gc[0]].dot:
                player.points += 1
                num_dots -= 1
                obj_grid[player.gc[1]][player.gc[0]].dot = False
                obj_grid[player.gc[1]][player.gc[0]].image.fill(obj_grid[player.gc[1]][player.gc[0]].color)
        
            # Kill event
            kill = False
            for ghost in ghosts:
                if ghost.gc == player.gc:
                    kill = True
                    break
            if kill:
                player.lives -= 1
                player.gc = [0, ROW-1]
                player.movement = (0, 0)
                for ghost in ghosts:
                    ghost.gc = [COL-1, 0]
                pygame.time.wait(1000)
        
            # Win event
            if num_dots == 0:
                return (True, player.points, total_dots)

            # Align player in current cell
            player.align()

            # Current cells become previous cells
            prev_player_locations.clear()
            prev_player_locations.append(obj_grid[player.gc[1]][player.gc[0]].rect)
            
            # Move player to new direction if possible
            player.turn(next_dir)
            player.move()
            
        # Process ghost events
        if ghost_frame_num == 0:
            # Kill event
            kill = False
            for ghost in ghosts:
                if ghost.gc == player.gc:
                    kill = True
                    break
            if kill:
                player.lives -= 1
                player.gc = [0, ROW-1]
                player.movement = (0, 0)
                for ghost in ghosts:
                    ghost.gc = [COL-1, 0]
                pygame.time.wait(1000)

            # Align ghosts in current cell
            for ghost in ghosts:
                ghost.align()

            # Current cells become previous cells
            prev_ghost_locations.clear()
            for ghost in ghosts:
                prev_ghost_locations.append(obj_grid[ghost.gc[1]][ghost.gc[0]].rect)

            # Move ghosts
            for ghost in ghosts:
                ghost.turn(ghost.plan(player))
                ghost.move()
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    if player.movement != (0, -1):
                        next_dir = (0, -1)
                elif event.key == pygame.K_DOWN:
                    if player.movement != (0, 1):
                        next_dir = (0, 1)
                elif event.key == pygame.K_LEFT:
                    if player.movement != (-1, 0):
                        next_dir = (-1, 0)
                elif event.key == pygame.K_RIGHT:
                    if player.movement != (1, 0):
                        next_dir = (1, 0)

        player.update()
        ghosts.update()

        ways.draw(screen)
        screen.blit(player.image, player.rect)
        ghosts.draw(screen)

        points_text = courier_prime.render("Points: " + str(player.points), True, WHITE, BLACK)
        points_text_rect = points_text.get_rect()
        points_text_rect.center = (GRIDWIDTH+(WIDTH-GRIDWIDTH)/2, HEIGHT/3)
        dirty.append(screen.blit(points_text, points_text_rect))

        lives_text = courier_prime.render("Lives: " + str(player.lives), True, WHITE, BLACK)
        lives_text_rect = lives_text.get_rect()
        lives_text_rect.center = (GRIDWIDTH+(WIDTH-GRIDWIDTH)/2, HEIGHT*2/3)
        dirty.append(screen.blit(lives_text, lives_text_rect))

        pygame.display.update(dirty)

        clock.tick(100)
    
    return (False, player.points, total_dots)