Start_python’s diary

ふたり暮らし

アラフィフ夫婦のフリーランスプラン

Kivy ボールが動かない(Python Kivyの取説・使い方 番外編)

はじめに

本日は最後までボールは動きません。

特に進展もないので飛ばしてもらった方がいいです。ハマった様子を見たい方のみ先にお進みください。

 

Kivyのチュートリアルの「ボールのアニメーションを追加する」でボールが動きません。

プログラムのコード

# フル画面を解除して画面の幅と高さを設定
from kivy.config import Config
Config.set('graphics', 'fullscreen', 0)
Config.set('graphics', 'width', 320)
Config.set('graphics', 'height', 568)
Config.set('graphics', 'resizable', 0)

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty,     ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
from random import randint


class MainScreen(BoxLayout):
    pass

class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos
        print(self.pos)


class PongGame(Widget):
    ball = ObjectProperty(None)

    def serve_ball(self):
        self.ball.center = self.center
        self.ball.velocity = Vector(4, 0).rotate(randint(0, 360))

    def update(self, dt):
        self.ball.move()

        # bounce off top and bottom
        if (self.ball.y < 0) or (self.ball.top > self.height):
            self.ball.velocity_y *= -1

        # bounce off left and right
        if (self.ball.x < 0) or (self.ball.right > self.width):
            self.ball.velocity_x *= -1

class PongApp(App):
    def build(self):
        self.title = 'テスト'
        game = PongGame()
        game.serve_ball()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return MainScreen()

if __name__ == '__main__':
    PongApp().run()

kvファイル(pong.kv)

<MainScreen>:
    BoxLayout:
        orientation: "vertical"

        BoxLayout:
            Button:
                size_hint_x: 0.2
                text: "1"
            Label:
                size_hint_x: 0.6
                text: "today"
            Button:
                size_hint_x: 0.2
                text: "2"

        PongGame:
            size_hint_y: 10

        BoxLayout:
            Button:
                text: "3"
            Button:
                text: "4"
            Button:
                text: "5"

<PongBall>:
    size: 50, 50 
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size       

<PongGame>:
    ball: pong_ball

    canvas:
        Rectangle:
            pos: self.center_x - 5, self.y
            size: 10, self.height
            
    Label:
        font_size: 70  
        center_x: root.width / 4
        top: root.top - 50
        text: "0"
        
    Label:
        font_size: 70  
        center_x: root.width * 3 / 4
        top: root.top - 50
        text: "0"
    
    PongBall:
        id: pong_ball
        center: self.parent.center

 

f:id:Start_python:20191212154210g:plain

ボールは真ん中で止まったままです。横に「self.pos」を表示してますが、値だけは変わっているのに反映されていないようです。

 

前回はここまで。

 

returnの部分を「return MainScreen()」から「return game」へ変更してみました。

class PongApp(App):
    def build(self):
        self.title = 'テスト'
        game = PongGame()
        game.serve_ball()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return game

if __name__ == '__main__':
    PongApp().run()

 

f:id:Start_python:20191212154456g:plain

ボールは動きましたが全体のレイアウトがなくなりました。

クラスの勉強不足です。インスタンス化して呼び出したいのですが「レイアウト イン レイアウト」の場合のやり方がわかりません。

 

メインプログラムをいじったり、kvファイルをいじったりしましたがダメです。いろいろ調べてかなり悩みましたがうまくいきません。一晩おいて、ふとしたときに解決策を思い付きました。次回に試してみたいと思います。

 

 

保存ファイル

lesson57.py

pong.kv

 

 

文責:Luke