大家好,我正在使用 python kivy 应用程序开发 Chwazi 小丑。 快速背景:在这个应用程序中,当您按下(并按住并跳动(变大变小))时会出现一个圆圈 我遇到了跳动动画的问题,因为当我使用这个功能时:
def beat_animation(self, circle):
anim = Animation(size=(circle.size[0]*1.2, circle.size[1]*1.2), duration=0.5)
anim += Animation(size=(circle.size[0], circle.size[1]), duration=0.5)
anim.repeat = True
anim.start(circle)
我的圆圈按照我想要的那样越来越大越来越小,但问题是它没有保持在光标周围。 (这是一个应用程序,它支持多点触控,所以它应该对所有圈子都这样做)
这是完整的代码:
import random
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Ellipse, Color
from kivy.uix.label import Label
from kivy.animation import Animation
class Touch(Widget):
def __init__(self, **kwargs):
super(Touch, self).__init__(**kwargs)
self.circles = {} # Dictionary to store circles for each finger
def on_touch_down(self, touch):
if touch.id not in self.circles:
with self.canvas:
width, height = self.size # Get the screen size
circle_size = min(width, height) * 0.3 # Calculate the circle size as 10% of the smaller dimension of the screen
color = Color(random.random(),random.random() ,random.random() ,1.0) #random color for the circle
circle = Ellipse(pos=(touch.x - circle_size/2, touch.y - circle_size/2), size=(circle_size, circle_size))
self.circles[touch.id] = (color, circle)
self.beat_animation(circle)
def beat_animation(self, circle):
anim = Animation(size=(circle.size[0]*1.2, circle.size[1]*1.2), duration=0.5)
anim += Animation(size=(circle.size[0], circle.size[1]), duration=0.5)
anim.repeat = True
anim.start(circle)
def on_touch_move(self, touch):
width, height = self.size # Get the screen size
circle_size = min(width,height) * 0.3 # Calculate the circle size as 10% of the smaller dimension of the screen
if touch.id in self.circles:
color, circle = self.circles[touch.id]
circle.pos = (touch.x - circle_size/2, touch.y - circle_size/2)
def on_touch_up(self, touch):
if touch.id in self.circles:
color, circle = self.circles.pop(touch.id)
self.canvas.remove(color)
self.canvas.remove(circle)
class MultiTouchApp(App):
def build(self):
return Touch()
if __name__ == "__main__":
MultiTouchApp().run()
我尝试像这样添加更改:
def beat_animation(self, circle, touch):
anim = Animation(pos=(touch.x - circle.size[0] / 2, touch.y - circle.size[1] / 2),size=(circle.size[0] * 1.2, circle.size[1] * 1.2), duration=0.5)
anim += Animation(pos=(touch.x - circle.size[0] / 2, touch.y - circle.size[1] / 2),size=(circle.size[0] / 1.2, circle.size[1] / 1.2), duration=0.5)
anim.repeat = True
anim.start(circle)
但是当我停止移动手指时,圆圈只是跳回到最初创建的位置(我认为这是因为传递给beat_animation的触摸参数没有动态变化),我不知道如何修复它
解决此类问题的一般方法是使用充当动画和画布指令之间中介的属性。
在这种情况下,我认为实现你想要的最简单的方法是将每个圆圈分成一个单独的小部件并使用
FloatLayout
作为父级:
import random
import kivy
from kivy.app import App
from kivy.animation import Animation
from kivy.graphics import Ellipse, Color
from kivy.properties import ListProperty, ColorProperty, NumericProperty, ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
class BeatingTouchCircle(Widget):
radius = NumericProperty(1)
position = ListProperty([0, 0])
color = ColorProperty((0, 0, 0, 1))
def __init__(self, radius, position, color, *args, **kwargs):
super().__init__(*args, **kwargs)
self.radius = radius
self.position = position
self.color = color
with self.canvas:
Color(rgba = self.color)
self.circle = Ellipse(
pos = (self.position[0] - self.radius, self.position[1] - self.radius),
size = (self.radius * 2, self.radius * 2)
)
self.beat_animation()
self.bind(radius=self.on_radius_changed)
def beat_animation(self):
anim = Animation(radius = self.radius * 1.2, duration = 0.5)
anim += Animation(radius = self.radius, duration = 0.5)
anim.repeat = True
anim.start(self)
def on_radius_changed(self, *_):
self.circle.size = (self.radius * 2, self.radius * 2)
self.circle.pos = (self.position[0] - self.radius, self.position[1] - self.radius)
class Touch(FloatLayout):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.circles = {} # Dictionary to store circles for each finger
def on_touch_down(self, touch):
if touch.id not in self.circles:
radius = min(self.size) * 0.15
color = (random.random(),random.random() ,random.random() ,1.0) #random color for the circle
circle = BeatingTouchCircle(radius, (touch.x, touch.y), color)
self.circles[touch.id] = (circle, touch)
self.add_widget(circle)
def on_touch_move(self, touch):
if circle := self.circles.get(touch.id):
circle, touch = circle
circle.position = (touch.x, touch.y)
def on_touch_up(self, touch):
if circle := self.circles.get(touch.id):
self.remove_widget(circle[0])
del self.circles[touch.id]
class MultiTouchApp(App):
def build(self):
return Touch()
if __name__ == "__main__":
MultiTouchApp().run()