I'm making a game in kivy where when you press on the soccer ball it moves. I want the ball to move only when I press exactly on the ball, if I press anywhere else it shouldn't move. Currently, the ball moves if I press anywhere close to the ball which Is not what I want. Is there anything I can do so that it only moves when I press exactly on the ball? Below is my code!
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 code
#: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
I also tried keep_ratio: True allow_stretch: True but it still didn't work
ball
is a circle
(or rather disk
) which has some radius
- if you check distance between ball center
and mouse position
and it is smaller then radius
then you clicked inside this circle
or disk
.
More precisely using the Pythagorean formula a**2 + b**2 == c**2
or rather disk's definition : x**2 + y**2 <= r**2
(ball.centerx - touch.pos.x)**2 + (ball.centery - touch.pos.y)**2 <= radius**2
Kivy has class Vector to make it simpler - but I can't test it.
Vector(ball.center).distance(touch.pos) <= radius
And you should use it instead of 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)
I'm not sure but maybe it even keeps ball position as Vector()
and you could use directly
ball.center.distance(touch.pos) <= radius