如何在鼠标左键单击时正确旋转精灵?

问题描述 投票:0回答:1

我正在使用 Pyglet 库在 Python 中开发 RTS 游戏。 精灵的旋转范围为 -180 到 180 度。 精灵无法正确地从-179旋转到179,它顺时针旋转,一直到179传递0,而不是逆时针旋转,仅用2度就达到179。

enter image description here雪碧

enter image description here

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()
python pyglet
1个回答
0
投票

如果你的目的只是让你的精灵朝最快到达目标的方向旋转,那么代码就是高度基于逻辑的。因此,我将使用图表而不是文字,这应该有助于更好地理解概念。

在这里,由于您正在使用 -180 到 180,因此您首先要弄清楚: Diagram of logic

为此,我们需要弄清楚“差异”是否小于 180,即上部区域(-180 到 180 区域)。如果不是,则意味着在底部区域(穿过 -180 和 180 边界)工作会更快。

现在,我们实际上还不知道哪个角是左角,哪个角是直角。为此,我们只需问,哪一个更大?

那么,

  1. 如果在顶部工作,左侧角度是精灵角度,我们顺时针移动
  2. 如果顶部和直角是精灵角度,我们逆时针移动
  3. 如果在底部工作并且左侧角度是精灵角度,我们逆时针移动
  4. 如果底部和直角是精灵角度,我们顺时针移动

我们还需要考虑到,当我们跨越-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
© www.soinside.com 2019 - 2024. All rights reserved.