用户控制的精灵卡在框中。 Python 2.7.9 w/Pygame

问题描述:

感谢您查看我的问题并帮助我。我有一个用户控制的精灵,它应该会导致屏幕围绕精灵的位置移动,就像老式的Gameboy Pokemon游戏一样,但这并没有发生。相反,我的精灵卡在一盒坐标中,我用它来帮助定义背景偏移的参数。这是我认为的代码是导致此:用户控制的精灵卡在框中。 Python 2.7.9 w/Pygame

# Shift world left (-x) 
    if player.rect.right >= 510: 
     diff = player.rect.right - 510 
     player.rect.right = 510 
     current_level.shift_world_x(-diff) 

    # Shift world right (+x) 
    if player.rect.left <= 130: 
     diff = 130 - player.rect.left 
     player.rect.left = 130 
     current_level.shift_world_x(diff) 

    # Shift world up (-y) 
    if player.rect.top <= 100: 
     diff = 100 - player.rect.top 
     player.rect.top = 100 
     current_level.shift_world_y(diff) 

    # Shift world down (y) 
    if player.rect.bottom >= 380: 
     diff = player.rect.bottom - 380 
     player.rect.bottom = 380 
     current_level.shift_world_y(-diff) 

如果我把一个#旁边player.rect.right = 510,或任何其他三个一些变体,我的精灵可以自由移动,但屏幕不会移位。

所有资产Zip文件是在这里: https://www.dropbox.com/s/3g2w0mv1fuupetl/DoneGeon.zip?dl=0

我的代码全部如下:

import pygame 

"""---Global Constants---""" 

# Colors 
BLACK = (0, 0, 0) 

# Screen Variables 
screen_x = 720 
screen_y = 480 

# Background variables 
back_x = 0 
back_y = -243 
back_x_change = 0 
back_y_change = 0 

class Player(pygame.sprite.Sprite): 
    """---User Controled Character---""" 

    # Methods 
    def __init__(self): 
     """---Contructor Function---""" 

     # Call parent's constructor 
     pygame.sprite.Sprite.__init__(self) 

     # Load player image 
     self.image = pygame.image.load("player.png").convert() 

     # Set referance to image "hit box" 
     self.rect = self.image.get_rect() 

     # Set speed of player 
     self.change_x = 0 
     self.change_y = 0 


    def update(self): 
     """---Move the Player---""" 

     # Move left/right 
     self.rect.x += self.change_x 

     # Move up/down 
     self.rect.y += self.change_y 

    # User controlled movements 
    def go_left(self): 
     self.change_x = -3 
    def go_right(self): 
     self.change_x = 3 
    def go_up(self): 
     self.change_y = -3 
    def go_down(self): 
     self.change_y = 3 
    def stop_x(self): 
     self.change_x = 0 
    def stop_y(self): 
     self.change_y = 0 

class Barrier(pygame.sprite.Sprite): 
    """---Barriers that prevent player from passing---""" 

    def __init__(self,width,height): 
     """ Barrier constructor """ 
     pygame.sprite.Sprite.__init__(self) 

     self.image = pygame.Surface([width,height]) 
     self.image.fill(BLACK) 

     self.rect = self.image.get_rect() 

class Level(): 
    """---All levels will spawn from this generic class---""" 

    def __init__(self,player): 
     """ Needed for when sprites collide with player """ 
     self.barrier_list = pygame.sprite.Group() 
     self.enemy_list = pygame.sprite.Group() 
     self.player = player 

     # Distance world has been shifted left/right 
     self.world_shift_x = 0 

     # Background image 
     background_base = None 
     background_layera = None 

     # Distance world has been shifted up/down 
     self.world_shift_y = 0 


    def update(self): 
     """ Update everything on level """ 
     self.barrier_list.update() 
     self.enemy_list.update() 

    def draw(self,screen): 
     """ Draw everything on level """ 

     # Draw barriers 
     self.barrier_list.draw(screen) 

     # Draw the base layer 
     screen.blit(self.background_base,(back_x,back_y)) 

     # Draw all sprites 
     self.enemy_list.draw(screen) 

     # Draw Layer A 
     screen.blit(self.background_layera,(back_x,back_y)) 

    def shift_world_x(self,shift_x): 
     """ When character moves left/right, everything must follow """ 

     # Track shift amount 
     self.world_shift_x += shift_x 

     # Go through all list and shift 
     for barrier in self.barrier_list: 
      barrier.rect.x += shift_x 

     for enemy in self.enemy_list: 
      enemy.rect.x += shift_x 

    def shift_world_y(self,shift_y): 
     """ When character moves up/down, everything must follow """ 

     # Track shift amount 
     self.world_shift_y += shift_y 

     # Go through all list and shift 
     for barrier in self.barrier_list: 
      barrier.rect.y += shift_y 

     for enemy in self.enemy_list: 
      enemy.rect.y += shift_y 

class Level_1(Level): 
    """---Forest 1---""" 

    def __init__(self,player): 
     """ Create the level """ 

     # Call parent constructor 
     Level.__init__(self,player) 

     self.level_limit_x = -1912 
     self.level_limit_y = 1080 

     # Make background 
     self.background_base = pygame.image.load("base1.png").convert() 
     self.background_layera = pygame.image.load("layera1.png").convert() 
     self.background_layera.set_colorkey(BLACK) 


     # List with w, h, x = 32, y = 32 of barriers 
     # Remove comment to activate-> level = [] 

     # Go through the list above and add barriers 
     # Remove comment to activate-> for barriers in level: 


def main(): 
    """---Main Program---""" 
    pygame.init() 

    # Set screen size and caption 
    size = (screen_x,screen_y) 
    screen = pygame.display.set_mode(size) 
    pygame.display.set_caption("DoneGeon") 

    # Create Player 
    player = Player() 

    # Create all levels 
    level_list= [] 
    level_list.append(Level_1(player)) 

    # Set current level 
    current_level_no = 0 
    current_level = level_list[current_level_no] 

    # Add all sprites 
    active_sprite_list = pygame.sprite.Group() 

    # Add player 
    player.level = current_level 
    player.rect.x = 360 
    player.rect.y = 240 
    active_sprite_list.add(player) 

    # Loop until closed 
    done = False 

    # Screen update rate 
    clock = pygame.time.Clock() 

    # -------- Main Program Loop ----------- 
    while not done: 

     """---Main event loop---""" 

     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       done = True 

      """---User Controls---""" 

      # Key Pressed 
      if event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_LEFT: 
        player.go_left() 
       if event.key == pygame.K_RIGHT: 
        player.go_right() 
       if event.key == pygame.K_UP: 
        player.go_up() 
       if event.key == pygame.K_DOWN: 
        player.go_down() 

      # Key Released 
      if event.type == pygame.KEYUP: 
       if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: 
        player.stop_x() 
       if event.key == pygame.K_UP or event.key == pygame.K_DOWN: 
        player.stop_y() 

     """---Game Logic---""" 

     # Update Player 
     active_sprite_list.update() 

     # Update items in level 
     current_level.update() 

     # Shift world left (-x) 
     if player.rect.right >= 510: 
      diff = player.rect.right - 510 
      player.rect.right = 510 
      current_level.shift_world_x(-diff) 

     # Shift world right (+x) 
     if player.rect.left <= 130: 
      diff = 130 - player.rect.left 
      player.rect.left = 130 
      current_level.shift_world_x(diff) 

     # Shift world up (-y) 
     if player.rect.top <= 100: 
      diff = 100 - player.rect.top 
      player.rect.top = 100 
      current_level.shift_world_y(diff) 

     # Shift world down (y) 
     if player.rect.bottom >= 380: 
      diff = player.rect.bottom - 380 
      player.rect.bottom = 380 
      current_level.shift_world_y(-diff) 


     """---Draw below here---""" 
     current_level.draw(screen) 
     active_sprite_list.draw(screen) 

     pygame.display.flip() 
     clock.tick(60) 


    pygame.quit() 

if __name__ == "__main__": 
    main() 

感谢您的任何建议!

我想你会发现,如果你记录玩家x和世界x的变化,你会发现这更容易追踪。通常游戏中的小变化是不可见的,所以日志记录是监视游戏循环中发生的事情的唯一方法。

我还没有测试过这个,但我敢打赌,你在错误的地方有一个负面的。这:

def shift_world_x(self,shift_x): 
    """ When character moves left/right, everything must follow """ 

表明,如果玩家右边缘移动经过世界右侧边缘的世界第一右边缘应该扩展到匹配的球员,但是这个代码反向:

if player.rect.right >= 510: 
    diff = player.rect.right - 510 
    player.rect.right = 510 
    current_level.shift_world_x(-diff) 

如果玩家。右移动到513 diff将会是3,所以shift_world_x将被调用-3,将世界框左移动到507.玩家权利将被设置为510,所以玩家权利仍然会在下一个环路的框外。这表明世界图像会飘向左边,玩家精灵会卡在右边缘,但听起来像是被困在右边缘(我专注于一个边缘,因为所有的逻辑都是相同的)。

如果你在上面的if中记录player.rect.right和world.rect.right,你应该看到值的变化,并且更好地感受游戏逻辑正在做什么。

+0

谢谢,我能找到问题。在绘制背景的第104和第110行中,x和y坐标必须是“self.world_shift_x”和“self.world_shift_y”,以根据玩家精灵动作物理移动他们的位置。如果没有这些,他们的位置永远不会改变,无论精灵x或y位置。再次感谢你的帮助! – RavusFlapjack