Wednesday, August 25, 2021

kv 41 moving balls collision


#widget4.py
from kivy.app import App
from kivy.graphics import Ellipse, Color
from kivy.metrics import dp
from kivy.properties import Clock
from kivy.uix.widget import Widget
from random import random

class Widget4(Widget):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.balls_properties = []
        self.num = 10
        for i in range(self.num):
            new_ball = {
                "size": dp(50+50*random()),
                "vx": 1+9*random(),
                "vy": 1+9*random()
            }

            self.balls_properties.append(new_ball)

        with self.canvas:
            self.balls = []
            for i in range (self.num):
                Color(random(), random(), random())
                size = self.balls_properties[i]["size"]
                ball = Ellipse(pos=(0, 0), size=(size, size))
                self.balls.append(ball)

        Clock.schedule_interval(self.update, 0.2)

    def on_size(self, *args):
        for i in range(self.num):
            size = self.balls_properties[i]["size"]
            self.balls[i].pos = ((self.width-size)*random(), (self.height-size)*random())

    def update(self, dt):
        for i in range(self.num):
            x, y = self.balls[i].pos
            size = self.balls_properties[i]["size"]
            vx = self.balls_properties[i]["vx"]
            vy = self.balls_properties[i]["vy"]

            x += vx
            y += vy

            if y + size > self.height:
                y = self.height - size
                self.balls_properties[i]["vy"] = -vy
            if x + size > self.width:
                x = self.width - size
                self.balls_properties[i]["vx"] = -vx
            if y < 0:
                y = 0
                self.balls_properties[i]["vy"] = -vy
            if x < 0:
                x = 0
                self.balls_properties[i]["vx"] = -vx

            self.balls[i].pos = (x, y)

            #collision with other balls
            for j in range(i+1, self.num):
                xj, yj = self.balls[j].pos
                sizej = self.balls_properties[j]["size"]
                vxj = self.balls_properties[j]["vx"]
                vyj = self.balls_properties[j]["vy"]

                if (xj-x)**2 + (yj-y)**2 < (size/2 + sizej/2)**2:
                    print(i, j)
                    #if balls head same directory, swap velocity
                    #else reverse velocity
                    while (xj - x) ** 2 + (yj - y) ** 2 < (size / 2 + sizej / 2) ** 2:
                        x -= vx
                        y -= vy
                        xj -= vxj
                        yj -= vyj
                        self.balls[i].pos = (x, y)
                        self.balls[j].pos = (xj, yj)
                    if vx * vxj < 0:
                        self.balls_properties[i]["vx"] = -vx
                        self.balls_properties[j]["vx"] = -vxj
                    else:
                        self.balls_properties[i]["vx"] = vxj
                        self.balls_properties[j]["vx"] = vx
                    if vy * vyj < 0:
                        self.balls_properties[i]["vy"] = -vy
                        self.balls_properties[j]["vy"] = -vyj
                    else:
                        self.balls_properties[i]["vy"] = vyj
                        self.balls_properties[j]["vy"] = vy


class Widget4App(App):
    def build(self):
        return Widget4()


Widget4App().run()

reference:

No comments:

Post a Comment