2016-04-25 8 views
1

Im пытается сделать 2d игру в pygame, что своего рода работает как покемон. Теперь я действительно застрял в проблеме, и я не знаю, как ее решить.Pygame 2d плитка прокрутки края не загружается

Когда я перемещаю свой персонаж, я прокручиваю карту, чтобы игрок оставался центрированным. Я создал «анимацию», смещая расстояние на 2 пикселя за раз, вместо того, чтобы перемещать полный размер плитки, поэтому я получаю плавные перемещения. Проблема заключается в том, что когда я двигаюсь, экран не загружает новые плитки по краям, к которым я двигаюсь, чтобы края заканчивались белым пространством, пока я не завершил полную анимацию. Я свяжусь с моим кодом и надеюсь, что кто-то может мне помочь :)

TILESIZE = 32 
MAP_WIDTH = 25 
MAP_HEIGHT = 25 

class Player(pygame.sprite.Sprite): 
    def __init__(self, color, width, height): 
     # Call the parent class (Sprite) constructor 
     super().__init__() 
     self.name = "Player" 
     self.width = width 
     self.height = height 
     self.image = pygame.Surface([width, height]) 
     self.image.fill(color) 
     self.rect = self.image.get_rect() 
     self.rect.x = int(TILESIZE * (MAP_WIDTH/2)) - TILESIZE/2 
     self.rect.y = int(TILESIZE * (MAP_HEIGHT/2)) - TILESIZE/2 

class World: 
    def __init__(self): 
     self.shiftX = 0 
     self.shiftY = 0 
     self.tile_map = [ [DIRT for w in range(MAP_WIDTH)] for h in range(MAP_HEIGHT)] 
     for row in range(MAP_HEIGHT): 
      for column in range(MAP_WIDTH): 
       try: 
        if real_map[row + self.shiftY][column + self.shiftX] == 0: 
         tile = DIRT 
        elif real_map[row + self.shiftY][column + self.shiftX] == 1: 
         tile = GRASS 
        elif real_map[row + self.shiftY][column + self.shiftX] == 2: 
         tile = WATER 
        else: 
         tile = DIRT 
        self.tile_map[row][column] = tile 
       except: 
        self.tile_map[row][column] = WATER 

    def shiftWorld(self): 

     for row in range(MAP_HEIGHT): 
      for column in range(MAP_WIDTH): 
       try: 
        if real_map[row + self.shiftY][column + self.shiftX] == 0: 
         tile = DIRT 
        elif real_map[row + self.shiftY][column + self.shiftX] == 1: 
         tile = GRASS 
        elif real_map[row + self.shiftY][column + self.shiftX] == 2: 
         tile = WATER 
        else: 
         tile = DIRT 
        self.tile_map[row][column] = tile 
       except: 
        self.tile_map[row][column] = WATER 

    def okToMove(self, key): 
     if key[K_w]: 
      if self.tile_map[int(MAP_WIDTH/2 - 1)][int(MAP_HEIGHT/2)] != 2: 
       return True 
     elif key[K_s]: 
      if self.tile_map[int(MAP_WIDTH/2 + 1)][int(MAP_HEIGHT/2)] != 2: 
       return True 
     elif key[K_a]: 
      if self.tile_map[int(MAP_WIDTH/2)][int(MAP_HEIGHT/2) - 1] != 2: 
       return True 
     elif key[K_d]: 
      if self.tile_map[int(MAP_WIDTH/2)][int(MAP_HEIGHT/2) + 1] != 2: 
       return True 

def start_game(): 
    pygame.init() 
    clock = pygame.time.Clock() 
    #HÄR KAN VI MÅLA UPP MER 
    #SCREEN = pygame.display.set_mode((MAP_WIDTH*TILESIZE, MAP_HEIGHT*TILESIZE)) 
    world = World() 
    SCREEN = pygame.display.set_mode((TILESIZE * (MAP_WIDTH-2), TILESIZE * (MAP_HEIGHT-4))) 
    running = True 
    player = Player(BLACK, 32, 32) 
    sprites = pygame.sprite.Group() 
    sprites.add(player) 
    movement = 0 
    offsetY = 0 
    offsetX = 0 
    animation_north = False 
    animation_south = False 
    animation_west = False 
    animation_east = False 

    while running: 
     for event in pygame.event.get(): 
      if event.type==QUIT: 
       pygame.quit() 
       sys.exit() 
      elif event.type == pygame.KEYDOWN: 
       #Get keyinput and do whatever needs to be done 
       key = pygame.key.get_pressed() 
       if key[K_ESCAPE]: 
        pygame.quit() 
        sys.exit() 

       if animation_east or animation_north or animation_south or animation_west: 
        pass 
       else: 
        if key[K_w]: 
         okToMove = world.okToMove(key) 
         if okToMove == True: 
          animation_north = True 
         else: 
          pass 
        elif key[K_a]: 
         okToMove = world.okToMove(key) 
         if okToMove == True: 
          animation_west = True 

        elif key[K_s]: 
         okToMove = world.okToMove(key) 
         if okToMove == True: 
          animation_south = True 

        elif key[K_d]: 
         okToMove = world.okToMove(key) 
         if okToMove == True: 
          animation_east = True 




     if animation_north == True: 
      if movement == 32: 
       movement = 0 
       world.shiftY -= 1 
       world.shiftWorld() 
       offsetY = 0 
       animation_north = False 

      else: 
       offsetY += 4 
       movement += 4 

     if animation_south == True: 
      if movement == 32: 
       movement = 0 
       world.shiftY += 1 
       world.shiftWorld() 
       offsetY = 0 
       animation_south = False 
       intY = 0 
      else: 
       offsetY -= 4 
       movement += 4 

     if animation_west == True: 
      if movement == 32: 
       movement = 0 
       world.shiftX -= 1 
       world.shiftWorld() 
       offsetX = 0 
       animation_west = False 
      else: 
       offsetX += 4 
       movement += 4 

     if animation_east == True: 
      if movement == 32: 
       world.shiftX += 1 
       world.shiftWorld() 
       movement = 0 
       offsetX = 0 
       animation_east = False 
      else: 
       offsetX -= 4 
       movement += 4 


     SCREEN.fill(WHITE) 

     for row in range(MAP_HEIGHT): 
      for column in range(MAP_WIDTH): 
       SCREEN.blit(textures[world.tile_map[row][column]], (column*TILESIZE + offsetX, row*TILESIZE + offsetY)) 


     sprites.draw(SCREEN) 
     pygame.display.update() 
     pygame.display.flip() 
     clock.tick(60) 

start_game() 

ответ

2

Я пишу подобную игру, и я поделюсь с вами своей логикой. мои блоки 32x32, поэтому каждый блок 32 пикселя.

enter image description here

Внешняя граница экрана спрайты и внутренний квадрат монитора. У вас всегда есть один спрайт со всех сторон экрана. теперь, если вы считаете движение пикселя на любой стороне экрана, вам легко отслеживать, когда вам нужно нарисовать следующую строку или столбец спрайтов, но не так, чтобы они всегда были DRAWN OFF SCREEN. если мое движение пикселей равно -8 (левое движение), я рисую колонку спрайтов на правой стороне как раз на границе экрана, а вне видимой области. То же самое касается другой стороны.

Вот какой-то код из моей программы. Это код добавления спрайтов.

def add_sprites(self): 

    """sprites are added to the group which appear on screen right. the column number is the value in ColDrawn. We selct columns from the list according to this value. Once the end of the column list is reached we start again from the first one. We cycle thru the list depending on the NumCycle[0] value.""" 

    if self.ColDrawn < self.Columns_in_Dungeon - 1: 
     self.ColDrawn += 1 

    else: # all the columns drawn so increment the flag 
     self.ColDrawn = 0 
     self.NumCycle[1] += 1 

    if self.NumCycle[1] >= self.NumCycle[0]: # if the flag is equal to the number of cycles the screen is scrolled then set numcycle[2] to True 
     self.NumCycle[2] = True 

    else: # screen can be scrolled 
     spritecol = self.all_wall_sprite_columns_list[self.ColDrawn] 
     self.wallspritegroup.add(spritecol) # add column of sprites to the sprite group 
    return 

и здесь код удаления спрайтов.

def remove_sprites(self): 

    """sprites are removed from the group as they exit from screen left.""" 

    for sprt in self.wallspritegroup: # remove_basic sprites that move_basic off screen on left 

     if sprt.rect.x <= -48: 
      sprt.rect.x = self.screenw # reset the x position and 
      sprt.kill() 
      #spritegrp.remove_basic(sprt) # remove_basic the sprite from the sprite group 

    return 

Код довольно прост в использовании, поскольку я прокомментировал их. Надеюсь это поможет.

+0

я получил вниз и вправо рабочее движение за счет изменения: SCREEN = pygame.display.set_mode ((TILESIZE * (MAP_WIDTH), TILESIZE * (MAP_HEIGHT))) к: SCREEN = pygame.display.set_mode ((TILESIZE * (MAP_WIDTH-1), TILESIZE * (MAP_HEIGHT-1))). Так что спасибо за это! Мой вопрос в том, как я рисую рамки, которые должны быть отрицательными сейчас? Плитки над экраном и те, что слева! Спасибо за помощь до сих пор! – madswed

+0

Если вы принимаете мою помощь, вы можете отметить ее принятой. :) Пожалуйста, уточните вопрос. Что вы подразумеваете под «нарисовать рамки, которые должны быть отрицательными? Плитки над экраном и те, что слева!»? Зачем вам их рисовать? Разве они не с видимой области экрана? – emorphus

+0

Хорошо, я постараюсь изо всех сил. Плитки над экраном и слева от экрана действительно находятся за пределами видимой области. Проблема в том, что когда я перемещаю свой персонаж, я рисую смещение: (столбец * TILESIZE + offsetX, строка * TILESIZE + offsetY)) , так что он показывает в области смещения белый: SCREEN.fill (WHITE) Я думал, что если бы я мог рисовать за пределами видимого экрана 1 плитки во всех направлениях, смещение, которое он рисует, не было бы белым, а вот следующие плитки! – madswed