在Kivy中使对象旋转并朝触摸移动

3 投票
1 回答
2235 浏览
提问于 2025-04-18 20:48

我在开发的游戏中遇到了一些问题,想让一个物体朝着用户触摸的地方移动。以下是我目前的代码:

class Player(Widget):
angle = NumericProperty(0)

def on_touch_move(self, touch):
    y = (touch.y - self.center[1])
    x = (touch.x - self.center[0])
    calc = math.degrees(math.atan2(y, x))
    new_angle = calc if calc > 0 else 360+calc

    self.angle = new_angle
    self.pos = [touch.x - 50, touch.y - 50]

我希望的是,当用户触摸(并且按住屏幕)时,“玩家”能够不断旋转,朝着触摸的位置移动,并且逐渐靠近这个位置。有什么建议吗?我会继续努力,并告诉你我用的是什么。

提前谢谢你,
Ilmiont

编辑:
自从我发帖以来,我尝试了这个方法,效果好多了……但是物体经常在离光标几像素的地方停下来,偏离了一点。我希望它能够停在光标正上方,也就是说,玩家在手机上用手指按住的位置。

    def on_touch_move(self, touch):
    y = (touch.y - self.center[1])
    x = (touch.x - self.center[0])
    calc = math.degrees(math.atan2(y, x))
    new_angle = calc if calc > 0 else 360+calc

    self.angle = new_angle
    anim = Animation(x = touch.x, y = touch.y)
    anim.start(self)

1 个回答

2

这里有一个非常简单的例子:

from kivy.lang import Builder
from kivy.base import runTouchApp
from kivy.uix.image import Image

from kivy.graphics import Rotate
from kivy.properties import NumericProperty

from math import atan2, degrees, abs

from kivy.animation import Animation

Builder.load_string('''                                                                                                                                        
<PlayerImage>:                                                                                                                                                 
    canvas.before:                                                                                                                                             
        PushMatrix                                                                                                                                             
        Rotate:                                                                                                                                                
            angle: self.angle                                                                                                                                  
            axis: (0, 0, 1)                                                                                                                                    
            origin: self.center                                                                                                                                
    canvas.after:                                                                                                                                              
        PopMatrix                                                                                                                                              
''')

class PlayerImage(Image):
    angle = NumericProperty(0)

    def on_touch_down(self, touch):
        Animation.cancel_all(self)
        angle = degrees(atan2(touch.y - self.center_y, 
                              touch.x - self.center_x))

        Animation(center=touch.pos, angle=angle).start(self)


root = Builder.load_string('''                                                                                                                                 
Widget:                                                                                                                                                        
    PlayerImage:                                                                                                                                               
        source: 'colours.png'                                                                                                                                  
        allow_stretch: True                                                                                                                                    
        keep_ratio: False                                                                                                                                      
''')

runTouchApp(root)

这个例子只是做了一些基本的事情,但也许能帮你解决问题。

有一个很重要的地方你可能想要改进,那就是使用动画的方式有点不灵活。如果你的游戏是动态的,这个任务可能更适合放在游戏更新循环里,每次更新时逐步移动和旋转。这样做的好处是更灵活,能够更容易地以恒定的速度移动或旋转,而不是像现在这样总是精确地花费1秒。

当然,还有一些小细节,比如让角度在-π到π之间循环,而不是在达到某个值时几乎转一圈。

撰写回答