移动Sprite问题

时间:2018-01-04 17:38:36

标签: python pygame

当这部分代码运行时,它会显示精灵,但是当按下箭头键时没有任何动作,香港专业教育学院尝试使用print语句尝试调试但没有出现任何问题,怎么办?我解决了吗?这里我添加了与我的程序中的运动相关的所有内容,其他文件包括屏幕和退出循环

from spritechanges import *
from lklk import *
import pygame
import time
WHITE = (255, 255, 255)
BLACK = (0, 0, 0, 0)
clock = pygame.time.Clock()
FPS = 120

# Create a surface/image and draw a circle onto it.
sprite_image = pygame.Surface((50, 50))
pygame.draw.circle(sprite_image, WHITE, [25, 25], 20)
# Create surface/image draw a line onto it
width = 40
height = 60


# Create an instance of the Sprite class.
class Sprite(pygame.sprite.Sprite):
    def __init__(self, pos):
        super(Sprite, self).__init__()  # platform
        self.width = width
        self.height = height
        self.platform = pygame.Surface((width, height))
        self.platform.fill(WHITE)
        # set a reference to the image rect
        self.rect = self.platform.get_rect()
        # Assign the global image to `self.image`.
        self.image = sprite_image

        # Create a rect which will be used as blit
        # position and for the collision detection.
        self.rect = self.image.get_rect()
        # Set the rect's center to the passed `pos`.
        self.rect.center = pos
        self._vx = 0
        self._vy = 0
        # Assign the pos also to these attributes.
        self._spritex = pos[0]
        self._spritey = pos[1]
        # set of sprites sprite can bump against
        self.level = None

def update(self):
    self._gravity = 99
    block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
    for block in block_hit_list:
        if self._vx > 0:
            self.rect.right = block.rect.left
        elif self._vx < 0:
            # Otherwise if we are moving left, do the opposite.
            self.rect.left = block.rect.right
    self.rect.y += self.change_y

    # Check and see if we hit anything
    block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
    for block in block_hit_list:

        # Reset our position based on the top/bottom of the object.
        if self._vy > 0:
            self.rect.bottom = block.rect.top
        elif self._vy < 0:
            self.rect.top = block.rect.bottom

        # Stop our vertical movement
        self._vy = 0

    self._vx = 0
    self.rect.y += 2
    platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
    self.rect.y -= 2

    # If it is ok to jump, set our speed upwards
    if len(platform_hit_list) > 0 or self.rect.bottom >= H:
        self._xy = -10

        # Player-controlled movement:


def go_left(self):
    """ Called when the user hits the left arrow. """
    self._vx = -6


def go_right(self):
    """ Called when the user hits the right arrow. """
    self._vx = 6


def stop(self):
    """ Called when the user lets off the keyboard. """
    self._vx = 0

    # Adjust the position.
    self._spritex += self._vx
    self._spritey += self._vy

    # And update the center of the rect.
    self.rect.center = (self._spritex, self._spritey)

sprite = Sprite([400, 550])

active_sprite_list = pygame.sprite.Group()
sprite.level = current_level

sprite.rect.x = 340
sprite.rect.y = H - sprite.rect.height
active_sprite_list.add(sprite)
done = True
while not done:
    events()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                sprite.go_left()
            if event.key == pygame.K_RIGHT:
                sprite.go_right()
            if event.key == pygame.K_UP:
                sprite.jump()

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT and sprite.change_x < 0:
                sprite.stop()
            if event.key == pygame.K_RIGHT and sprite.change_x > 0:
                sprite.stop()
                # If the player gets near the right side, shift the world left (-x)
        if sprite.rect.right > W:
            sprite.rect.right = W

            # If the player gets near the left side, shift the world right (+x)
        if sprite.rect.left < 0:
            sprite.rect.left = 0
        DS.fill(BLACK)

        # Blit the sprite's image at the sprite's rect.topleft position.
        DS.blit(sprite.image, sprite.rect)

        pygame.display.flip()

        clock.tick(FPS)

    pygame.quit()

2 个答案:

答案 0 :(得分:0)

这是问题吗?

self._vx = 0

每当用户离开键盘时,您最终会将位置调整为零?

答案 1 :(得分:0)

stop方法中的某些代码应该在update方法中。跳转代码需要采用单独的jump方法。此外,在主while循环中调用active_sprite_list.update()以更新所有包含的精灵,并active_sprite_list.draw(DS)来绘制它们。这是一个完整的工作示例:

import pygame


pygame.init()

clock = pygame.time.Clock()
FPS = 60
DS = pygame.display.set_mode((640, 480))
sprite_image = pygame.Surface((50, 50), pygame.SRCALPHA)
pygame.draw.circle(sprite_image, (90, 100, 200), [25, 25], 25)
W, H = DS.get_size()


class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, w, h):
        super(Platform, self).__init__()
        self.image = pygame.Surface((w, h))
        self.image.fill((90, 90, 120))
        self.rect = self.image.get_rect(topleft=(x, y))


class Sprite(pygame.sprite.Sprite):
    def __init__(self, pos):
        super(Sprite, self).__init__()
        self.image = sprite_image
        self.rect = self.image.get_rect()
        self.rect.center = pos
        self._vx = 0
        self._vy = 0
        self._spritex = pos[0]
        self._spritey = pos[1]
        self.level = None
        self._gravity = .9

    def update(self):
        # Adjust the x-position.
        self._spritex += self._vx
        self.rect.centerx = self._spritex  # And update the rect.

        block_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        for block in block_hit_list:
            if self._vx > 0:
                self.rect.right = block.rect.left
            elif self._vx < 0:
                # Otherwise if we are moving left, do the opposite.
                self.rect.left = block.rect.right
            self._spritex = self.rect.centerx  # Update the position.

        # Adjust the y-position.
        self._vy += self._gravity  # Accelerate downwards.
        self._spritey += self._vy
        self.rect.centery = self._spritey  # And update the rect.

        # Check and see if we hit anything
        block_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        for block in block_hit_list:
            # Reset our position based on the top/bottom of the object.
            if self._vy > 0:
                self.rect.bottom = block.rect.top
            elif self._vy < 0:
                self.rect.top = block.rect.bottom
            self._spritey = self.rect.centery  # Update the position.
            # Stop our vertical movement
            self._vy = 0

    def jump(self):
        self.rect.y += 2
        platform_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        self.rect.y -= 2

        # If it is ok to jump, set our speed upwards
        if len(platform_hit_list) > 0 or self.rect.bottom >= H:
            self._vy = -17

    def go_left(self):
        """ Called when the user hits the left arrow. """
        self._vx = -3

    def go_right(self):
        """ Called when the user hits the right arrow. """
        self._vx = 3

    def stop(self):
        """ Called when the user lets off the keyboard. """
        self._vx = 0


sprite = Sprite([60, 60])

active_sprite_list = pygame.sprite.Group(sprite)
sprite.level = pygame.sprite.Group(
    Platform(20, 400, 200, 20), Platform(220, 300, 20, 120),
    Platform(220, 300, 300, 20))
active_sprite_list.add(sprite.level)

done = False
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                sprite.go_left()
            if event.key == pygame.K_RIGHT:
                sprite.go_right()
            if event.key == pygame.K_UP:
                sprite.jump()
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT and sprite._vx < 0:
                sprite.stop()
            if event.key == pygame.K_RIGHT and sprite._vx > 0:
                sprite.stop()
    # If the player gets near the right side, shift the world left (-x)
    if sprite.rect.right > W:
        sprite.rect.right = W
        # If the player gets near the left side, shift the world right (+x)
    if sprite.rect.left < 0:
        sprite.rect.left = 0

    active_sprite_list.update()

    DS.fill((50, 50, 50))
    # Blit the sprite's image at the sprite's rect.topleft position.
    active_sprite_list.draw(DS)
    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()