0

何らかの理由で、私のスプライトの動きは、A を押すと斜め上と左、D を押すと斜め下と右だけになり、どの方向にも動くように正しいベクトルが与えられているにもかかわらず、W/S は機能しません。入力が処理される場所は次のとおりです。

class Operator:
    PLAYER = 'player'
    COMPUTER = 'computer'

    def __init__(self, type, AI=None):
        self.type = type
        self.AI = AI

    def handle(self, entity):
        keys = pygame.key.get_pressed()
        direction = Vector(0, 0)

        if self.type == Operator.PLAYER:
            if keys[pygame.K_w]:
                direction += Vector(0, -1)

            if keys[pygame.K_s]:
                direction += Vector(0, 1)

            if keys[pygame.K_a]:
                direction += Vector(-1, 0)

            if keys[pygame.K_d]:
                direction += Vector(1, 0)

        if direction:
            entity.move(direction)

        return bool(direction)

関連するスプライト コードは次のとおりです。

class Sprite(pygame.sprite.Sprite):
    @property
    def x(self):
        return self._x_coordinate

    @x.setter
    def x(self, value):
        self._x_coordinate = self.rect.centerx = wrap(value,
                                                      WIDTH,
                                                      -self.width)

    @property
    def y(self):
        return self._y_coordinate

    @x.setter
    def y(self, value):
        self._y_coordinate = self.rect.centery = wrap(value,
                                                      HEIGHT,
                                                      -self.height)

    @property
    def position(self):
        return Vector(self.x, self.y)

    @position.setter
    def position(self, value: Vector):
        self.x, self.y = value

    @property
    def width(self):
        return self.rect.width

    @property
    def height(self):
        return self.rect.height

    def set_surface(self, surface):
        self.image = surface

class Entity(Sprite):
    @property
    def colliding(self):
        return pygame.sprite.spritecollide(self,
                                           sprites(self),
                                           False)

    @property
    def velocity(self):
        return self.internal_velocity + self.external_velocity

    @property
    def angle(self):
        return self.velocity.as_polar()[1]

    def __init__(self, size, position, operator=None, image=None, color='#FF4C4C'):
        super().__init__()

        if image:
            image = pygame.image.load(image)

        self.image = pygame.Surface(image.get_size() if image else size)
        self.rect = self.image.get_rect()

        self.position = position
        self.operator = operator
        self.internal_velocity = Vector(0, 0)
        self.external_velocity = Vector(0, 0)

        if not image:
            self.image.fill(color)
        else:
            self.image.blit(image, ORIGIN)

    def draw(self, surface):
        if camera.on_screen(self):
            surface.blit(self.image,
                         (self.x - self.width / 2, self.y - self.height / 2))

        if debugging:
            offset = Vector()
            offset.from_polar((20, self.angle))

            pygame.draw.line(surface,
                             '#54CE0E',
                             self.position,
                             self.position + offset,
                             1)

    def update(self):
        if self.operator and not self.operator.handle(self):
            self.internal_velocity *= FRICTION
            self.external_velocity *= FRICTION

        self.position += self.velocity

        if self.internal_velocity.x and 0.2 > self.internal_velocity.x > -0.2:
            self.internal_velocity.x = floor(self.internal_velocity.x)

        if self.internal_velocity.y and 0.2 > self.internal_velocity.y > -0.2:
            self.internal_velocity.y = floor(self.internal_velocity.y)

    def move(self, vector: Vector):
        self.internal_velocity += vector

        if self.internal_velocity.length() > MOVE_SPEED:
            self.internal_velocity.scale_to_length(MOVE_SPEED)

    def set_operator(self, operator):
        self.operator = operator

def wrap(number, maximum, minimum=0):
    return (number - minimum) % (maximum - minimum + 1) + minimum

def floor(number):
    if number > 0:
        return math.floor(number)
    elif not number:
        return 0
    else:
        return math.floor(abs(number)) * -1

プログラム全体を提供できますが、350 行を少し超えるので、必要な場合はお知らせください。

4

1 に答える 1