Kivy:对象运动/更新问题(Kivy Pong 教程改编)

我改编了 kivy pong 教程 ( https://kivy.org/doc/stable/tutorials/pong.html ) 的一部分来创建一个应该每秒更新 60 次的球类,在屏幕上移动球。同样,当球击中两侧时,应向相反方向反射。然而,球只是坐在屏幕的角落一动不动。我犯的语法/逻辑错误是什么?


这是我的代码:


from kivy.lang import Builder

from kivy.app import App

from kivy.uix.boxlayout import BoxLayout

from kivy.uix.image import Image

from kivy import Config

from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition,\

SlideTransition

from kivy.uix.widget import Widget

from kivy.animation import Animation

from kivy.properties import NumericProperty, ReferenceListProperty,\

ObjectProperty

from kivy.clock import Clock

from kivy.vector import Vector

from random import randint


Builder.load_string('''

<Ball>:

    Image:

        source: '58-Breakout-Tiles.png'

        size: 15, 15

        pos: self.pos




<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

    cog: cog

    AnchorLayout:

        anchor_x: 'right'

        anchor_y: 'top'

        Image:

            id: cog

            size_hint: .03, .03

            source: 'settings-cog.png'


    Ball:

        id: ball

        center: self.parent.center

''')



呼啦一阵风
浏览 230回答 2
2回答

九州编程

该问题有两种解决方案。方法一——kv文件消除&nbsp;Image:添加size_hint: None, None以覆盖 (1, 1) 或 (100, 100) 的默认大小添加&nbsp;canvas:片段Builder.load_string('''<Ball>:&nbsp; &nbsp; size_hint: None, None&nbsp; &nbsp; size: 15, 15&nbsp; &nbsp; canvas:&nbsp; &nbsp; &nbsp; &nbsp; Rectangle:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; source: '58-Breakout-Tiles.png'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pos: self.pos&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size: self.sizeKivy Canvas »来源source此属性表示要从中加载纹理的文件名。如果要使用图像作为源,请执行以下操作:with self.canvas:&nbsp; &nbsp; Rectangle(source='mylogo.png', pos=self.pos, size=self.size)这是 Kivy 语言中的等价物:<MyWidget>:&nbsp; &nbsp; canvas:&nbsp; &nbsp; &nbsp; &nbsp; Rectangle:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; source: 'mylogo.png'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pos: self.pos&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size: self.size方法 2 - kv & py 文件将球定义从 kv 文件移动到 Python 脚本中创建球图像的纹理向画布声明一个包含球纹理的矩形只要有一个或更改self.rect,就将矩形绑定到一个方法。update_ball()possize片段 - pyfrom kivy.core.image import Imagefrom kivy.graphics import Rectangle...class Ball(Widget):&nbsp; &nbsp; velocityX, velocityY = NumericProperty(0), NumericProperty(0)&nbsp; &nbsp; velocity = ReferenceListProperty(velocityX, velocityY)&nbsp; &nbsp; def __init__(self, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; super(Ball, self).__init__(**kwargs)&nbsp; &nbsp; &nbsp; &nbsp; texture = Image('58-Breakout-Tiles.png').texture&nbsp; &nbsp; &nbsp; &nbsp; self.size_hint = None, None&nbsp; &nbsp; &nbsp; &nbsp; self.size = (15, 15)&nbsp; &nbsp; &nbsp; &nbsp; with self.canvas:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.rect = Rectangle(texture=texture, pos=self.pos, size=self.size)&nbsp; &nbsp; &nbsp; &nbsp; self.bind(pos=self.update_ball, size=self.update_ball)&nbsp; &nbsp; def update_ball(self, *args):&nbsp; &nbsp; &nbsp; &nbsp; self.rect.pos = self.pos&nbsp; &nbsp; &nbsp; &nbsp; self.rect.size = self.size&nbsp; &nbsp; def move(self):&nbsp; &nbsp; &nbsp; &nbsp; self.pos = Vector(*self.velocity) + self.pos片段 - kvBuilder.load_string('''<SettingsScreen>:Kivy 帆布 »纹理texture表示用于绘制此指令的纹理的属性。你可以像这样设置一个新的纹理:from kivy.core.image import Imagetexture = Image('logo.png').texturewith self.canvas:&nbsp; &nbsp; Rectangle(texture=texture, pos=self.pos, size=self.size)通常,您将使用源属性而不是纹理。

慕姐4208626

您的代码大部分都在工作。一个相当简单的解决方法是将您更改Ball为扩展Image(而不是Widget),然后添加size_hint: None, None.因此,Ball类声明变为:class Ball(Image):类本身可以保持不变对于规则Ball在你的kv文件被简化为:<Ball>:&nbsp; &nbsp; source: '58-Breakout-Tiles.png'在您的GameScreen规则中,该Ball部分变为:Ball:&nbsp; &nbsp; id: ball&nbsp; &nbsp; size_hint: None, None&nbsp; &nbsp; center: self.parent.center只需添加size_hint.我认为这足以让它发挥作用。或者,您可以将size_hint加到您的Ball作为:Ball:&nbsp; &nbsp; id: ball&nbsp; &nbsp; size_hint: None, None&nbsp; &nbsp; center: self.parent.center并改变pos: self.pos对pos: root.pos你的<Ball>:规则为:<Ball>:&nbsp; &nbsp; Image:&nbsp; &nbsp; &nbsp; &nbsp; source: '58-Breakout-Tiles.png'&nbsp; &nbsp; &nbsp; &nbsp; size: 15, 15&nbsp; &nbsp; &nbsp; &nbsp; pos: root.pos原始代码的主要问题是Image向 aWidget添加一个只是向Ball Widget. Widget不是 a 的ALayout不处理绘制其子项。原Pong游戏的把球图像中得到解决这个Canvas的Ball Widget。这Image门课基本上是为你做的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python