2016-11-12 109 views
0

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

左边是如何看起来在begning和后两个步骤下来 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是全部代码。如果有人帮助我,那么我真的很棒,因为我无法入睡。

+0

问题可以在'(64 * X ,64 * y)'。你不能使用'x','y'来从'world'获得价值并在屏幕上绘制它。现在,当你移动即时。 3步下来,然后你开始在'(64 * 3,64 * 0)'中绘图,但你总是开始在'(64 * 0,64 * 0)' – furas

回答

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) 
+0

绘图。非常感谢您的帮助,并且您已经更正其余的部分。 :)现在一切都很好。 –