[英]How do I move a character based on it's rotation?
我在 PyGame 中有一个角色,我想根据它的旋转向前移动。 目前它非常奇怪和不稳定。
这是我所有的代码: https ://www.toptal.com/developers/hastebin/enapuravet.lua
以下是相关代码:
def rotate(self, amount):
self.rotation += amount
if self.rotation == 181:
self.rotation = -180
elif self.rotation == -181:
self.rotation = 180
print(self.rotation)
self.capybara = pygame.transform.rotate(self.base_capybara, self.rotation)
self.rect = self.capybara.get_rect(center = self.rect.center)
def move_forward(self, speed):
print(self.rotation)
new_coordinates = calculate_new_xy((self.x, self.y), 2, self.rotation*(math.pi/180))
self.x = new_coordinates[0]
self.y = new_coordinates[1]
self.rect = self.capybara.get_rect(center = (self.x, self.y))
def calculate_new_xy(old_xy,speed,angle_in_radians):
print(angle_in_radians)
new_x = old_xy[0] + (speed*math.cos(angle_in_radians))
new_y = old_xy[1] + (speed*math.sin(angle_in_radians))
return new_x, new_y
这是它的作用: https ://gyazo.com/3b7bf1c5b2e760a53913b6d3acae6e67
我还尝试了其他一些 x_y 计算函数,如下所示:
move_vec = pygame.math.Vector2()
move_vec.from_polar((speed, angle_in_degrees))
return old_xy + move_vec
但他们有相同/非常相似的结果。
这是水豚:
由于pygame.Rect
应该代表屏幕上的一个区域,一个pygame.Rect
对象只能存储整数数据。
Rect 对象的坐标都是整数。 [...]
如果要以浮点精度存储对象位置,则必须将对象的位置存储在单独的变量和属性中,并同步pygame.Rect
对象。将坐标round
并将其分配给矩形的位置(例如.center
)。
math.sin
和math.cos
的角度单位是 Randian。 您需要使用math.radians
将角度从度数转换为弧度:
class Capybara:
def __init__(self, size_multiplier):
# [...]
self.x, self.y = 300, 300
self.rect = self.capybara.get_rect(center = (round(self.x), round(self.y)))
def rotate(self, amount):
self.rotation += amount
ifv self.rotation > 360:
self.rotation -= 360
elif self.rotation < 0:
self.rotation += 360
self.capybara = pygame.transform.rotate(self.base_capybara, self.rotation)
self.rect = self.capybara.get_rect(center = (round(self.x), round(self.y)))
def move(self, move):
self.x += move * math.cos(math.radians(self.rotation + 90))
self.y -= move * math.sin(math.radians(self.rotation + 90))
另请参阅使用矢量移动角色、移动时图像旋转或如何在使用键移动时在 pygame 中转动精灵。
最小的例子:
import pygame, math
pygame.init()
size = width, height = 600, 600
green = 50, 168, 82
screen = pygame.display.set_mode(size)
class Capybara:
def __init__(self, size_multiplier):
self.capybara = pygame.image.load('capybara.png')
self.o_size = 92, 206
self.new_size = (self.o_size[0] * size_multiplier,self.o_size[1] * size_multiplier)
self.capybara = pygame.transform.scale(self.capybara, self.new_size)
self.base_capybara = self.capybara
self.rotation = 0
self.x, self.y = 300, 300
self.rect = self.capybara.get_rect(center = (round(self.x), round(self.y)))
def rotate(self, amount):
self.rotation += amount
if self.rotation > 360:
self.rotation -= 360
elif self.rotation < 0:
self.rotation += 360
self.capybara = pygame.transform.rotate(self.base_capybara, self.rotation)
self.rect = self.capybara.get_rect(center = (round(self.x), round(self.y)))
def move(self, move):
self.x += move * math.cos(math.radians(self.rotation + 90))
self.y -= move * math.sin(math.radians(self.rotation + 90))
capybara = Capybara(0.8)
fpsClock = pygame.time.Clock()
rotate_l = False
rotate_r = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
keys = pygame.key.get_pressed()
rotate = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
move = keys[pygame.K_DOWN] - keys[pygame.K_UP]
capybara.move(-move * 5)
capybara.rotate(-rotate)
screen.fill(green)
screen.blit(capybara.capybara, capybara.rect)
pygame.display.update()
fpsClock.tick(60)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.