【问题标题】:Kivy on_touch_move and DragBehaviour not moving Image WidgetKivy on_touch_move 和 DragBehaviour 不移动 Image Widget
【发布时间】:2019-04-11 20:50:57
【问题描述】:

我试图让我的玩家图像在被 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

https://i.stack.imgur.com/ypd7C.png

https://i.stack.imgur.com/rNvLz.png

【问题讨论】:

    标签: python python-3.x kivy kivy-language


    【解决方案1】:

    根本原因

    播放器小部件没有移动,因为self.player.pos_hint = {'top': 0.1, 'right': 0.6}

    解决方案

    kv 文件

    • 从方法initWidgets() 中删除self.player.pos_hint = {'top': 0.1, 'right': 0.6}

    片段 - 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()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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多