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
小,然后您在 circle
或 disk
.
中单击
更精确地使用 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
我正在用 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
小,然后您在 circle
或 disk
.
更精确地使用 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