用户控制的精灵卡在盒子里。 Python 2.7.9 w / Pygame

时间:2016-02-29 06:10:25

标签: python-2.7 class pygame sprite

感谢您查看我的问题并帮助我。我有一个用户控制的精灵,应该导致屏幕转移到精灵的位置,有点像旧的Gameboy口袋妖怪游戏,但这不会发生。相反,我的精灵卡在一个坐标框内,我用它来帮助定义背景移动的参数。这是我认为导致这个问题的代码:

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

感谢您的任何建议!

1 个答案:

答案 0 :(得分:0)

如果您记录播放器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)

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

如果您在上面显示的if中记录了player.rect.right和world.rect.right,您应该会看到更改后的值,并更好地了解游戏逻辑的作用。