from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse
from kivy.core.window import Window
from kivy.clock import Clock
import random
import math

# ウィンドウサイズ
Window.size = (400, 400)

class Ball:
    def __init__(self, canvas, x, y, radius, dx, dy, color=(1, 0, 0)):
        self.x = x
        self.y = y
        self.radius = radius
        self.dx = dx
        self.dy = dy
        self.color = color

        with canvas:
            Color(*self.color)
            self.ellipse = Ellipse(pos=(self.x - self.radius, self.y - self.radius),
                                   size=(2 * self.radius, 2 * self.radius))

    def update(self):
        # 移動
        self.x += self.dx
        self.y += self.dy

        # 壁との反射
        if self.x - self.radius <= 0 or self.x + self.radius >= Window.width:
            self.dx *= -1
        if self.y - self.radius <= 0 or self.y + self.radius >= Window.height:
            self.dy *= -1

        # 位置座標を更新
        self.ellipse.pos = (self.x - self.radius, self.y - self.radius)

class BouncingBallApp(Widget):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.balls = [] # 複数のボールオブジェクトを入れる配列を定義
        self.max_balls = 20  # 最大ボール数

        # 0.5秒ごとに新しいボールを追加
        Clock.schedule_interval(self.add_ball, 0.5)
        # 毎フレーム更新
        Clock.schedule_interval(self.update, 1/60)

    def add_ball(self, dt):
        if len(self.balls) < self.max_balls: #生成したボールが最大数に達していないとき
            # 中心から発射
            x, y = Window.width / 2, Window.height / 2
            radius = 10

            # ランダム方向・速度
            speed = 2
            angle = random.uniform(0, 2 * math.pi)
            # random.uniform(a, b) は、 a から b の範囲でランダムな実数を返す 関数
            # math.pi は円周率 (π ≒ 3.14159)、0 ~ 2π は、円を1周する角度の範囲(ラジアン単位)
            dx = speed * math.cos(angle)
            dy = speed * math.sin(angle)
            # angle=0のときcos=1,sin=0で右方向
            # angle=π/2のときcos=0,sin=1で上方向
            # angle=πのときcos=-1,sin=0で左方向
            # angle=3π/2のときcos=0,sin=-1で下方向

            # ランダム色 (RGB 0〜1)
            color = (random.random(), random.random(), random.random())

            ball = Ball(self.canvas, x, y, radius, dx, dy, color)
            self.balls.append(ball)

    def update(self, dt):
        for ball in self.balls:
            ball.update()

class MyApp(App):
    def build(self):
        return BouncingBallApp()

if __name__ == "__main__":
    MyApp().run()
投稿者

manager

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


日本語が含まれない投稿は受付られません。(スパム対策)