[英]Weird vector movement in pygame
For some reason the movement of my sprite is only diagonally up and left when pressing A, diagonally down and right when pressing D, and W/S just don't work despite the correct vectors being given to move in any direction.出于某种原因,我的精灵的移动仅在按 A 时沿对角线向上和向左移动,在按 D 时沿对角线向下和向右移动,而 W/S 只是不起作用,尽管给定了正确的向量以向任何方向移动。 Here's where the inputs are handled:这是处理输入的地方:
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)
And here is the relevant sprite code:这是相关的精灵代码:
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
I can provide the whole program, but it's a little over 350 lines so let me know if it's needed.我可以提供整个程序,但它有 350 多行,所以如果需要,请告诉我。
Something weird seems to be going on in your Entiry.update function.您的 Entiry.update function 中似乎发生了一些奇怪的事情。
if self.operator and not self.operator.handle(self):
self.internal_velocity *= FRICTION
self.external_velocity *= FRICTION
Firstly self.operator is not a boolean.首先 self.operator 不是 boolean。 Second, self.operator.handle
returns true if both x and y values are non zero.其次,如果 x 和 y 值都非零, self.operator.handle
返回 true。 This means friction is only applied when entity is not moving, which does not make any sense.这意味着仅在实体不移动时才应用摩擦,这没有任何意义。 But taking the whole if statement into account friction is always being applied because self.operator will always have a value.但是考虑到整个 if 语句的摩擦总是被应用,因为 self.operator 总是有一个值。 But all of this would only change scale not the direction.但这一切只会改变规模而不是方向。
The real problem seems to be the typo, again in update function.真正的问题似乎是错字,再次更新 function。 I have no idea what is happening here but I am pretty sure this is the problem because if these evaluate to true, your self.internal_velocity vector changes direction.我不知道这里发生了什么,但我很确定这是问题所在,因为如果这些评估为真,你的 self.internal_velocity 向量就会改变方向。 If your vector has has friction applied to it and thus has a value between -1 and 1, it will get floored right down to 0. Assuming your FRICTION constant is less than 1. Which is why I am assuming it does not work.如果你的向量施加了摩擦力,因此它的值在 -1 和 1 之间,它将下降到 0。假设你的 FRICTION 常数小于 1。这就是我假设它不起作用的原因。
if self.internal_velocity.x and 0.2 > self.internal_velocity.x > -0.2:
and和
if self.internal_velocity.y and 0.2 > self.internal_velocity.y > -0.2:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.