kivy 仅在按下图像时移动图像

kivy move image only when image is pressed

我正在用 kivy 制作一款游戏,当您按下足球时,它就会移动。我希望只有当我准确地按下球时球才会移动,如果我按下其他任何地方它都不应该移动。目前,如果我按靠近球的任何地方,球就会移动,这不是我想要的。有什么我可以做的,只有当我准确地按下球时它才会移动吗?下面是我的代码!

main.py

class Ball(Image):
velocity = NumericProperty(0)


def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        self.source = "icons/ball.png"
        self.velocity = 275
    return super().on_touch_down(touch)

def on_touch_up(self, touch):
    if self.collide_point(*touch.pos):
        self.source = "icons/ball.png"
    return super().on_touch_up(touch)


class MainApp(App):
    GRAVITY = 300


def move_ball(self, time_passed):
    ball = self.root.ids.game_screen.ids.ball
    ball.y = ball.y + ball.velocity * time_passed
    ball.velocity = ball.velocity - self.GRAVITY * time_passed


def start_game(self):
    Clock.schedule_interval(self.move_ball, 1/60.)

kivy代码

#:import utils kivy.utils


<GameScreen>:
    FloatLayout:
        canvas:
            Color:
                rgb: utils.get_color_from_hex("#39B3F2")
            Rectangle:
                size: self.size
                pos: self.pos
    GridLayout:
        rows: 1
        pos_hint: {"top": 1, "left": 1}
        size_hint: 1, .1
        Image:
            source: "icons/sun.png"
    GridLayout:
        rows: 1
        pos_hint: {"top": 1, "left": 1}
        size_hint: 1, .2
        Image:
            source: "icons/clouds.png"
    GridLayout:
        rows: 1
        pos_hint: {"bottom": 1, "left": 1}
        size_hint: 1, .5
        Image:
            source: "icons/Field4.png"
            allow_stretch: True
            keep_ratio: False
            pos: self.pos


    Button:
        size_hint: None, None
        font_size: dp(20)
        font_name: 'SackersGothicStd-Medium.otf'
        text: "Start Game"
        color: "gold"
        pos_hint: { "center_x": 0.5, "center_y": 0.3}
        size: 150, 55
        size_hint: None, None
        background_normal: ''
        background_color: (57/255.0, 179/255.0, 242/255.0, .10)


        on_release:
            self.disabled = True
            self.opacity = 0
            root.play_sound()
            app.start_game()


    Ball:
        source: "icons/ball.png"
        size_hint: None, None
        size: 500, 500
        pos_hint: {"center_x": 0.5}
        id: ball

我也试过了keep_ratio:对 allow_stretch:正确 但还是不行

ball 是一个 circle(或者更确切地说 disk),它有一些 radius - 如果你检查 ball center 和 [=19= 之间的距离] 并且它比 radius 小,然后您在 circledisk.

中单击

更精确地使用 Pythagorean formula a**2 + b**2 == c**2
或者更确切地说 disk's definition : x**2 + y**2 <= r**2

(ball.centerx - touch.pos.x)**2 + (ball.centery - touch.pos.y)**2 <= radius**2

Kivy class Vector 使它更简单 - 但我无法测试它。

Vector(ball.center).distance(touch.pos) <= radius

你应该使用它而不是 collide_point()

class Ball(Image):

    velocity = NumericProperty(0)
 
    radius = 50  # you have to get it manually from image     
    
    def on_touch_down(self, touch):
        if Vector(self.center).distance(touch.pos) <= radius:
            self.source = "icons/ball.png"
            self.velocity = 275

        return super().on_touch_down(touch)
    
    def on_touch_up(self, touch):
        if Vector(self.center).distance(touch.pos) <= radius:
            self.source = "icons/ball.png"

        return super().on_touch_up(touch)

我不确定,但也许它甚至可以将球的位置保持为 Vector(),你可以直接使用

ball.center.distance(touch.pos) <= radius