python - Kivy on_touch_move 和 DragBehaviour 不移动 Image Widget
问题描述
我试图让我的播放器图像在由 on_touch_move 事件触发时移动。我曾尝试使用 DragBehaviour,但没有成功。同样,更新 Player Image 的 x 坐标也没有效果。
代码
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.image import Image
from kivy import Config
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty,\
StringProperty
from kivy.clock import Clock
from kivy.vector import Vector
from random import randint
Builder.load_string('''
<Ball>:
size_hint: None, None
source: '58-Breakout-Tiles.png'
pos: self.pos
size: 15, 15
<Player>:
size_hint: None, None
source: '49-Breakout-Tiles.png'
pos: self.pos
size: 60, 30
<SettingsScreen>:
close: close
AnchorLayout:
anchor_x: 'left'
anchor_y: 'top'
Image:
id: close
size_hint: .03, .03
source: 'grey_crossGrey.png'
GridLayout:
cols: 2
Label:
font_name: "vgafix.fon"
text: 'Music: '
Switch:
active: True
Label:
font_name: "vgafix.fon"
text: 'Sounds: '
Switch:
active: True
<MenuScreen>:
cog: cog
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
Image:
id: cog
size_hint: .03, .03
source: 'settings-cog.png'
BoxLayout:
orientation: 'vertical'
Image:
source: "brickbreaker log.png"
Label:
font_name: "vgafix.fon"
text: 'Tap to start'
<GameScreen>:
ball: ball
player: player
cog: cog
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
Image:
id: cog
size_hint: .03, .03
source: 'settings-cog.png'
Ball:
id: ball
size_hint: None, None
center: self.parent.center
Player:
id: player
size_hint: None, None
''')
Config.set('graphics', 'multisamples', '0')
class Ball(Image):
velocityX, velocityY = NumericProperty(0), NumericProperty(0)
velocity = ReferenceListProperty(velocityX, velocityY)
def move(self):
self.pos = Vector(*self.velocity) + self.pos
class Player(Image):
def __init__(self, **kwargs):
super(Player, self).__init__(**kwargs)
def on_touch_move(self, touch):
if self.collide_point(*touch.pos):
if (self.x >= 0) and (self.x <= self.width - 15):
self.x += (abs(self.x - touch.x))
class Brick(Image):
pass
class SettingsScreen(Screen):
def __init__(self, **kwargs):
super(SettingsScreen, self).__init__(**kwargs)
self.previous = StringProperty('')
def on_touch_down(self, touch):
if self.close.collide_point(*touch.pos):
self.manager.current = self.previous
class MenuScreen(Screen):
def on_touch_down(self, touch):
if self.cog.collide_point(*touch.pos):
self.manager.get_screen('settings').previous = self.manager.current
self.manager.current = 'settings'
else:
self.manager.transition = FadeTransition()
self.manager.current = 'game'
class GameScreen(Screen):
def __init__(self, **kwargs):
super(GameScreen, self).__init__(**kwargs)
self.initWidgets()
def on_pre_enter(self, *args):
self.interval = Clock.schedule_interval(self.update, 1.0 / 60.0)
def on_touch_down(self, touch):
if self.cog.collide_point(*touch.pos):
self.manager.get_screen('settings').previous = self.manager.current
self.manager.current = 'settings'
def initWidgets(self):
self.ball.center = self.center
self.ball.velocity = Vector(0, 4).rotate(randint(0, 360))
self.player.pos_hint = {'top': 0.1, 'right': 0.6}
def update(self, dt):
self.ball.move()
if (self.ball.y < 0) or (self.ball.y > self.height - 15):
self.ball.velocityY *= -1
# bounce off left and right
if (self.ball.x < 0) or (self.ball.x > self.width - 15):
self.ball.velocityX *= -1
def on_pre_leave(self, *args):
self.interval.cancel()
sm = ScreenManager(transition=FadeTransition())
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(GameScreen(name='game'))
sm.add_widget(SettingsScreen(name='settings'))
class BrickBreakerInsanityApp(App):
def build(self):
return sm
if __name__ == '__main__':
BrickBreakerInsanityApp().run
代码资产(必填):
https://drive.google.com/open?id=1GAnv5DfjNUuAXTybmsan90Dm0OuSVOfb
https://i.stack.imgur.com/rR799.png
https://i.stack.imgur.com/ngYvL.png
https://i.stack.imgur.com/AuxI3.png
解决方案
根本原因
播放器小部件没有移动,因为self.player.pos_hint = {'top': 0.1, 'right': 0.6}
解决方案
.kv 文件
self.player.pos_hint = {'top': 0.1, 'right': 0.6}
从方法中移除initWidgets()
片段 - kv
Ball:
id: ball
center: root.center
Player:
id: player
y: root.height * 0.1 - self.height
x: root.width * 0.6 - self.width
py文件
- 将方法添加
on_touch_move()
到class Player()
or中class GameScreen()
:
片段 - Py:方法 1
class Player(Image):
def on_touch_move(self, touch):
if (touch.x >= 0) and (touch.x <= self.parent.width - self.width):
self.x = touch.x
return True
return super(Player, self).on_touch_move(touch)
...
class GameScreen(Screen):
...
def initWidgets(self):
self.ball.velocity = Vector(0, 4).rotate(randint(0, 360))
片段 - Py:方法 2
class Player(Image):
pass
...
class GameScreen(Screen):
...
def initWidgets(self):
self.ball.velocity = Vector(0, 4).rotate(randint(0, 360))
...
def on_touch_move(self, touch):
if (touch.x >= 0) and (touch.x <= self.width - self.player.width):
self.player.x = touch.x
return True
return super(GameScreen, self).on_touch_move(touch)
推荐阅读
- hyperlink - 我想创建一个带有多个 pdf 链接的 whatsapp 共享链接,该链接在消息上显示单个单词的超链接
- c++ - 如何在 C++ 中使用模板参数作为参数覆盖方法?
- google-apps-script - 将单元格复制到另一个工作表的脚本,例如,基于单元格的背景颜色
- javascript - 运行 php 脚本“隐藏”
- docker - 将 Hyperledger 的 orderer.exemple.com 上传到 docker compose 时出错
- reactjs - AntD Upload在裁剪图片前需要验证
- java - 创建 bean 时出现运行时错误。java.lang.AbstractMethodError:
- ansible - 从无python远程主机获取文件
- python - 使用 if elif .. 检查今天的点和昨天的点的多个条件检查数据框行
- excel - Excel - 数据透视表 - 来自多个工作表的数据