2017-09-18 10 views
1

これは私の頭を何日間もしてきました。私は、中に固定されたプレーヤーと、プレーヤーの後ろに流動的に移動するタイルベースの背景と、プレーヤーの動きに応じて追加のタイル画像を生成するゲームを作成しようとしています。背景はこれまでのところ完全に動作します。Python(Pygame) - オブジェクトのインスタンスが異なる速度で背景に移動する

オブジェクトを背景(ツリーなど)に追加しようとすると、問題が発生します。私はこのオブジェクトを特定の背景位置に固定しておきたいが、プレイヤーが動くにつれて、オブジェクトは背景に対して徐々に動きます。つまり、オブジェクトは、プレイヤーが(必要なように)移動するにつれて移動しますが、もあまりにもに移動します。

World.updateメソッドの原因をself.tileShiftセクションで切り離しました。この/ ifif/ififセクション全体を削除した場合、動作は良く見えます(バックグラウンドは正しく更新されないので、このセクションが必要です)。何とか、タイルシフトがスキップすると、画面上のすべてのオブジェクトも数ピクセルだけスキップされます。研究と実験の1週間以上を過ごした後、私はまだそれを修正することができません。画像を変更したり、タイルシフトのカットオフポイントを変更したり、更新/描画メソッドを呼び出す順序を変更しようとしました。

下記のコードは、下記のように大量に削除されています。パターンがある背景のタイル画像が必要であることに注意してください(Worldクラスのinitを参照してください)。そうしないと、誤った動きが非常に緩やかであるため、記述している動作を見ることができなくなります。最高のパフォーマンスを得るには、70x70のPNGイメージを使用します。

うまくいけば、この説明が理にかなっています。追加情報が必要な場合はお知らせください。どんな助けでも大歓迎です!!

import pygame 

# Initialisation 
SCREEN_WIDTH, SCREEN_HEIGHT = 800, 850 
pygame.init() # Initialise pygame 
window = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # Set the window surface (the main screen of the game) 
pygame.display.set_caption("Game") # Game window caption 
window_rect = window.get_rect() 

# GLOBAL VARIABLES 
WorldMove = dict(x=0, y=0) # List for the direction and amount the background moves as the player moves 
PlayerMoveSpeed = 5 

# CLASSES 
class World(pygame.sprite.Sprite): 
    def __init__(self): 
     self.tileShift = dict(x=0, y=0) # Tracker for when the player has passed from one map tile to another 

     # Load and set up the tile images 
     self.tiles = pygame.image.load("Images\Tiles\Tile.png") 
     self.tileSize = self.tiles.get_rect().size[0] # Assumes a square size 
     self.map = pygame.Surface((self.tileSize*14,self.tileSize*15)) # Visible area surface size, based on tile size 
     self.rect = self.map.get_rect() # Create a rect attribute for the World, so it can be blitted to the window 
     self.rect.x, self.rect.y = -self.tileSize,-self.tileSize # The map is blitted starting one tile size above left of the screen (so we see no whitespace) 

    def update(self): 
     # Move the map around the player based on WorldMove, which is set in the player_move function 
     self.rect.x += WorldMove["x"] 
     self.rect.y += WorldMove["y"] 

     # Update the tileShift based on player movement so we know when they've moved onto another tile 
     if WorldMove["x"] != 0: self.tileShift["x"] -= WorldMove["x"] 
     if WorldMove["y"] != 0: self.tileShift["y"] -= WorldMove["y"] 

     # Once the self.tileShift has passed the size of one of the tile images, reset it and move self.matrix by 1 
     if self.tileShift["x"] < -self.tileSize: 
      self.tileShift["x"] = 0 # Reset the tileShift variable 
      self.rect.x = -self.tileSize # Reset the point from which the map is blitted to window to top left of visible screen 
     elif self.tileShift["x"] > self.tileSize: 
      self.tileShift["x"] = 0 
      self.rect.x = -self.tileSize 
     if self.tileShift["y"] > self.tileSize: 
      self.tileShift["y"] = 0 
      self.rect.y = -self.tileSize 
     elif self.tileShift["y"] < -self.tileSize: 
      self.tileShift["y"] = 0 
      self.rect.y = -self.tileSize 

    def draw(self): 
     # Draw the tiles in a grid in the visible area 
     for y in range(15): # Visible number of tiles on y axis 
      for x in range(14): # Visible number of tiles on x axis 
       self.map.blit(self.tiles, (self.tileSize*x, self.tileSize*y)) # Blit each tile onto self.map 
     window.blit(self.map, self.rect) # Blit self.map onto the window 

class Player(pygame.sprite.Sprite): 
    def __init__(self): 
     self.image = pygame.Surface((35, 35)) 
     self.image.fill((0, 0, 0)) 
     self.rect = (SCREEN_WIDTH/2, SCREEN_HEIGHT/2) # Player is always in middle of screen 

    def player_move(self): 
     global WorldMove # Make sure that we're referring to and updating the global variable for the world movement 

     key = pygame.key.get_pressed() 
     x, y = 0, 0 

     if key[pygame.K_w] or key[pygame.K_UP]: y = PlayerMoveSpeed 
     if key[pygame.K_d] or key[pygame.K_RIGHT]: x = -PlayerMoveSpeed 
     if key[pygame.K_a] or key[pygame.K_LEFT]: x = PlayerMoveSpeed 
     if key[pygame.K_s] or key[pygame.K_DOWN]: y = -PlayerMoveSpeed 

     if x != 0 and y != 0: # If more than one key pressed, move diagonally 
      WorldMove["x"] = int(x/1.5) 
      WorldMove["y"] = int(y/1.5) 
     else: 
      WorldMove["x"] = x 
      WorldMove["y"] = y 

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

class Object(pygame.sprite.Sprite): 

    def __init__(self): 
     self.image = pygame.Surface((50,100)) 
     self.image.fill((50,50,250)) 
     self.rect = self.image.get_rect() 
     self.rect.center = window_rect.center 
     self.rect.x, self.rect.y = 100, 100 # Spawn location of the object 

    def update(self): # Move the object as the world moves around the player 
     self.rect.x += WorldMove["x"] 
     self.rect.y += WorldMove["y"] 

    def draw(self): # Blit the object onto the screen at its location 
     window.blit(self.image, self.rect) 

# Set Objects 
world = World() 
object = Object() 
player = Player() 

# Main Loop 
gameRunning = True 

while gameRunning: 

    # Player events 
    for event in pygame.event.get(): 

     if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): 
      gameRunning = False 

     player.player_move() # Move player based on movement key(s) pressed (if any) 

    # Class updates and drawing to the screen 
    window.fill((255, 255, 255)) # Fill the window with background white 
    world.update() 
    world.draw() 
    object.update() 
    object.draw() 
    player.draw() 

    pygame.display.update() # Refresh the display 

# End - only reaches this point if gameRunning = False 
pygame.quit() 
+0

それはこれは、あなたがより多くの研究を行うことができます場合は*視差*スクロールと呼ばれる。 – jwg

答えて

0

代わりの-self.tileSizeWorldインスタンスのself.rectを設定し、インまたはself.tileSizeでRECT属性とself.tileShiftをデクリメント:

if self.tileShift["x"] < -self.tileSize: 
    self.tileShift["x"] += self.tileSize 
    self.rect.x -= self.tileSize 
elif self.tileShift["x"] > self.tileSize: 
    self.tileShift["x"] -= self.tileSize 
    self.rect.x += self.tileSize 
if self.tileShift["y"] > self.tileSize: 
    self.tileShift["y"] -= self.tileSize 
    self.rect.y += self.tileSize 
elif self.tileShift["y"] < -self.tileSize: 
    self.tileShift["y"] += self.tileSize 
    self.rect.y -= self.tileSize 
+0

これはそれでした!どうもありがとうございました – Matthew

関連する問題