我正在使用 Pyglet 库在 Python 中开发 RTS 游戏。 精灵的旋转范围为 -180 到 180 度。 精灵无法正确地从-179旋转到179,它顺时针旋转,一直到179传递0,而不是逆时针旋转,仅用2度就达到179。
from math import trunc, degrees, atan2
from pyglet.app import run
from pyglet.clock import schedule_interval
from pyglet.window import Window
from pyglet.graphics import Batch
from pyglet.sprite import Sprite
from pyglet.image.codecs.png import PNGImageDecoder
from pyglet.window import mouse
from pyglet.image import load
from pyglet.text import Label
from pyglet.canvas import Display
class MAIN(Window):
def __init__(self):
window_width = Display().get_default_screen().width // 2
window_height = Display().get_default_screen().height // 2
super().__init__(window_width, window_height)
self.batch = Batch()
self.sptiteWidth, self.spriteHeight = 100, 100
# SPRITE
image = load('img/sprite.png', decoder=PNGImageDecoder())
image.anchor_x, image.anchor_y = self.sptiteWidth // 2, self.spriteHeight // 2
self.sprite = Sprite(image, x = window_width // 2, y = window_height // 2, batch=self.batch)
self.angle = 0
self.rotate = False
# LABEL
self.label = Label(
color=(255, 255, 255),
font_name ='Times New Roman',
font_size = 22,
x = self.width // 2, y = self.height // 4,
anchor_x ='center', anchor_y ='center')
def update(self, dt):
self.label.text = f'MOUSE ANGLE: {self.angle} || SPRITE ANGLE: {self.sprite.rotation}'
if self.rotate:
rotationSpeed = 1
if self.sprite.rotation != self.angle:
if self.sprite.rotation < self.angle:
self.sprite.rotation += rotationSpeed
else:
self.sprite.rotation -= rotationSpeed
def on_mouse_press(self, x, y, button, modifiers):
if button == mouse.LEFT:
self.angle = trunc(degrees(atan2(x - self.sprite.x, y - self.sprite.y)))
# if self.angle < 0:
# self.angle += 360
self.rotate = True
def on_draw(self):
self.clear()
self.batch.draw()
self.label.draw()
if __name__ == "__main__":
fps = 60
main = MAIN()
schedule_interval(main.update, 1 / fps)
run()
如果你的目的只是让你的精灵朝最快到达目标的方向旋转,那么代码就是高度基于逻辑的。因此,我将使用图表而不是文字,这应该有助于更好地理解概念。
在这里,由于您正在使用 -180 到 180,因此您首先要弄清楚:
为此,我们需要弄清楚“差异”是否小于 180,即上部区域(-180 到 180 区域)。如果不是,则意味着在底部区域(穿过 -180 和 180 边界)工作会更快。
现在,我们实际上还不知道哪个角是左角,哪个角是直角。为此,我们只需问,哪一个更大?
那么,
我们还需要考虑到,当我们跨越-180和180边界线时,我们需要根据我们要去的方向进行转换(-180到180、180到-180)。
def update(self, dt):
self.label.text = f'MOUSE ANGLE: {self.angle} || SPRITE ANGLE: {self.sprite.rotation}'
if self.rotate:
rotationSpeed = 1
if self.sprite.rotation != self.angle:
#New code
if abs(self.sprite.rotation-self.angle) < 180:
if self.sprite.rotation > self.angle:
self.sprite.rotation -= rotationSpeed
else:
self.sprite.rotation += rotationSpeed
else:
if self.sprite.rotation > self.angle:
self.sprite.rotation += rotationSpeed
else:
self.sprite.rotation -= rotationSpeed
if self.sprite.rotation > 180: self.sprite.rotation = -180
if self.sprite.rotation < -180: self.sprite.rotation = 180
#Your old code
# if self.sprite.rotation < self.angle:
# self.sprite.rotation += rotationSpeed
# else:
# self.sprite.rotation -= rotationSpeed