2016-04-25 16 views
1

Ich versuche, ein 2D-Spiel in Pygame, das ein bisschen wie Pokemon funktioniert. Ich bin jetzt wirklich auf ein Problem gestoßen, da ich nicht weiß, wie ich es lösen soll.Pygame 2D-Fliese Scroll-Kanten laden nicht

Wenn ich meinen Charakter bewege, scrolle ich stattdessen die Karte, damit der Spieler zentriert bleibt. Ich habe eine "Animation" erstellt, indem ich die Entfernung um 2 Pixel auf einmal verschoben habe, anstatt die gesamte Kachelgröße zu verschieben, damit ich weiche Bewegungen erhalte. Das Problem, das ich habe ist, dass, wenn ich mich bewege, der Bildschirm nicht die neuen Fliesen in den Rändern lädt, auf die ich mich bewege, so dass die Ränder ein weißer Raum enden, bis ich die volle Animation vollendet habe. Ich werde meinen Code verknüpfen und hoffentlich kann jemand mir helfen :)

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() 

Antwort

2

Ich schreibe ein ähnliches Spiel und ich werde meine Logik mit Ihnen teilen. meine Blöcke sind 32x32, also ist jeder Block 32 Pixesl.

enter image description here

Der äußere Rand ist die Sprites-Bildschirm und der Innenvierkant ist der Monitor. Sie haben immer ein Sprite-Extra auf allen Seiten des Bildschirms. Wenn Sie jetzt die Pixelbewegung auf einer beliebigen Seite des Bildschirms zählen, können Sie leicht verfolgen, wann Sie die nächste Reihe oder Spalte von Sprites zeichnen müssen, aber nicht, dass sie immer DRAWN OFF SCREEN sind. Wenn meine Pixelbewegung -8 ist (linke Bewegung), zeichne ich eine Spritespalte auf der rechten Seite nur an der Grenze des Bildschirms, aber außerhalb des sichtbaren Bereichs. Gleiches gilt für die andere Seite.

Hier ist ein Code aus meinem Programm. Dies ist der Sprite-Addiercode.

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 

und hier ist der Sprite-Entfernungscode.

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 

Der Code ist ziemlich einfach zu folgen, wie ich sie kommentiert habe. Hoffe das hilft.

+0

Ich habe nach unten und rechts Bewegung durch wechselnde Arbeits: SCREEN = pygame.display.set_mode ((tileSize * (MAP_WIDTH), tileSize * (MAP_HEIGHT))) zu: SCREEN = pygame.display.set_mode ((tileSize * (MAP_WIDTH-1), TILESIZE * (MAP_HEIGHT-1))). Also vielen Dank dafür! Meine Frage ist nur, wie ich die Rahmen zeichne, die jetzt negativ sein sollten? Die Fliesen über dem Bildschirm und die nach links! Danke für die Hilfe bis jetzt! – madswed

+0

Wenn Sie meine Hilfe akzeptieren, können Sie sie als akzeptiert markieren. :) Bitte erläutern Sie die Frage. Was meinst du mit "zeichne die Rahmen, die negativ sein sollten? Die Kacheln über dem Bildschirm und die links davon!"? Warum müssen Sie diese zeichnen? Sind sie nicht aus dem sichtbaren Bildschirmbereich? – emorphus

+0

Ok ich werde mein Bestes versuchen .. Die Fliesen über dem Bildschirm und auf der linken Seite des Bildschirms sind in der Tat außerhalb des sichtbaren Bereichs. Das Problem I ist, dass, wenn ich mein Zeichen verschiebe, zeichne ich einen Offset: (Spalte * TILESIZE + offsetX, Zeile * TILESIZE + offsetY)) so, was es im Offset-Bereich zeigt, ist das Weiß: SCREEN.fill (WHITE) Ich dachte, wenn ich außerhalb des sichtbaren Bildschirms 1 Kachel in jede Richtung zeichnen könnte, wäre der Versatz, den es zieht, nicht weiß, sondern die nächsten Kacheln stattdessen! – madswed