Pygame滚动地图不会滚动

时间:2016-11-12 08:53:13

标签: python pygame

我在pygame中制作了一个roguelike,有几天我无法处理地图滚动问题。

左边是两个步骤后的乞讨和右边的情况 enter image description here 正如你所看到的那样,顶部的一些标题消失了,其余的都没有移动。我尝试从roguebasin实现算法,但它没有帮助。这个问题花了我几天的生命,我不知道什么是错的。我在这里发布了两个我遇到问题的函数。

def world_gen():
camera_x = scrolling_map(hero.x, 5, 10, map_width)
camera_y = scrolling_map(hero.y, 5, 10, map_height)
for x in range(camera_x, camera_x+11):
    for y in range(camera_y, camera_y+11):
        if world[y][x] != 0:
            display_surf.blit(find_title(world[y][x]).image, (64 * x, 64 * y))
            display_surf.blit(hero.image, (64 * 5, 64 * 5))

def scrolling_map(p, hs, s, m):
"""
    Get the position of the camera in a scrolling map:

     - p is the position of the player.
     - hs is half of the screen size, and s is the full screen size.
     - m is the size of the map.
    """

if p < hs:
    return 0
elif p >= m - hs:
    return m - s
else:
    return p - hs

here都是代码。如果有人帮助我,我真的很高兴因为我无法入睡因为这个。

1 个答案:

答案 0 :(得分:1)

我没有检查过这个,但我认为问题是(64 * x, 64 * y),因为你移动了相机,但你也移动了它将被绘制的地方。但是你总是从(64 * 0, 64 * 0)

开始

你必须把它搬回去

if world[y][x] != 0:
    a = x - camera_x
    b = y - camera_y
    display_surf.blit(find_title(world[y][x]).image, (64 * a, 64 * b))

编辑测试 - 它有效

import sys
import random
import pygame
#from pygame.locals import * # don't need it

# --- constants --- (UPPER_CASE names)

FPS = 30
WINDOW_WIDTH = 704
WINDOW_HEIGHT = 704
MAP_WIDTH = 30
MAP_HEIGHT = 14 # not 15

GREEN = (100, 255, 0)

# --- classes --- (CamelCase names)

class Object:
    # this is a generic object: the player, a monster, an item, the stairs...
    # it's always represented by a character on screen.

    def __init__(self, x, y, image):
        self.x = x
        self.y = y

        self.image = pygame.image.load(image)

        # use pygame.Rect() to keep object position and size -
        # it use by other Pygame function
        # ie. pygame.sprite.Sprite() and "colision detection"
        # or pygame.sprite.Group()

        self.rect = self.image.get_rect()
        self.rect.x = 64 * 5 
        self.rect.y = 64 * 5

    def move(self, dx, dy):
        if self.y+dx < len(world) and self.y+dy < len(world[0]):
            if find_title(world[self.y+dy][self.x+dx]).solid is False:  #this line checks if move is possible
                self.x += dx
                self.y += dy

    def draw(self, screen):
        screen.blit(self.image, self.rect)

    def event_handler(self, event):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                if self.x - 1 >= 0:
                    self.move(-1, 0)
            elif event.key == pygame.K_RIGHT:
                if self.x + 1 < MAP_WIDTH:
                    self.move(1, 0)
            elif event.key == pygame.K_UP:
                if self.y - 1 >= 0:
                    self.move(0, -1)
            elif event.key == pygame.K_DOWN:
                if self.y + 1 < MAP_HEIGHT:
                    self.move(0, 1)


class Title:
    # this is a class for titles like grass, road and so on

    def __init__(self, title_number, solid, image):
        self.title_number = title_number
        self.solid = solid
        self.image = pygame.image.load(image)

# --- functions --- (lower_case names)

def find_title(n):
    tiles = [nothing, grass, fance]

    if n < len(tiles):
        return tiles[n]

#    if n == 0:
#        return nothing
#    if n == 1:
#        return grass
#    if n == 2:
#        return fance

def world_draw(screen): # could be split in "move_camera" and "draw_world" 

    for x in range(camera_x, camera_x+11):
        for y in range(camera_y, camera_y+11):
            if y < len(world) and x < len(world[0]): # control map size
                if world[y][x] != 0:
                    a = x - camera_x
                    b = y - camera_y
                    screen.blit(find_title(world[y][x]).image, (64 * a, 64 * b))

def scrolling_map(position, half_size, screen_size, map_size): # use readable names
    """
        Get the position of the camera in a scrolling map:

         - p is the position of the player.
         - hs is half of the screen size, and s is the full screen size.
         - m is the size of the map.
        """

    if position < half_size:
        return 0
    elif position >= map_size - half_size:
        return map_size - screen_size
    else:
        return position - half_size

# --- main ---

world = [[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]


# - init -

pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), 0, 32)
screen_rect = screen.get_rect()
pygame.display.set_caption("Rl")

# - objects -

hero = Object(5, 5, "hero.png")
grass = Title(1, False, "grass.png")
fance = Title(2, True, "fance.png")
nothing = Title(0, False, "road.png")

# - mainloop -

fps_clock = pygame.time.Clock()

while True:

    # - events -

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        hero.event_handler(event)

    # - updates (without draw) -

    camera_x = scrolling_map(hero.x, 5, 10, MAP_WIDTH)
    camera_y = scrolling_map(hero.y, 5, 10, MAP_HEIGHT)

    # - draws (without updates) -

    screen.fill(GREEN)

    world_draw(screen)

    hero.draw(screen)

    pygame.display.update()

    # - FPS - control speed -
    # pygame.time.delay(50) # you don't need it - you have `fps_clock.tick` for this

    fps_clock.tick(FPS)