Should by sim class be updating the balls, or should the balls be updating themselves?
Posted by ElegantPoet3386@reddit | learnprogramming | View on Reddit | 6 comments
So, I'm still working on my physics simulation that I started 3 days ago. Right now there's a sim class that controls the simulation. I decided today to also make a ball class so that I can reuse logic for every single ball, that way multiple balls won't become a nightmare to code though. My code is as follows.
import arcade
import random
GRAVITY = -1000;
C = 0.8;
class Sim(arcade.View):
def __init__(self):
super().__init__();
ball = Ball(100,window.height-50,0,0,50,100,(255,255,255))
self.ball_list = [ball]
def on_draw(self):
self.clear();
for i in range(len(self.ball_list)):
arcade.draw_circle_filled(self.ball_list[i].x,self.ball_list[i].y,self.ball_list[i].radius,self.ball_list[i].color)
def on_update(self, delta_time):
for i in range(len(self.ball_list)):
self.ball_list[i].velocity_y+=GRAVITY*delta_time
self.ball_list[i].y += self.ball_list[i].velocity_y*delta_time
if(self.ball_list[i].y - self.ball_list[i].radius < 0):
self.ball_list[i].velocity_y *= -(C**0.5)
self.ball_list[i].y = self.ball_list[i].radius
class Ball():
def __init__(self,x,y,v_x,v_y,r,m,color:tuple):
self.x = x
self.y = y
self.velocity_x = v_x
self.velocity_y = v_y
self.radius = r
self.mass = m
self.color = color;
As you can see, right now the Simulation class controls the drawing, and the updating of every single ball. and loops through all of the balls on every tick. Note that on_update and on_draw are called by arcade not me.
The thing I'm wondering, would it be better practice to move the updating and drawing logic to the ball class? Maybe write methods for them, and the simulation only calls their methods every tick. Is this a good idea or am I just giving myself more work?
desrtfx@reddit
I just noticed something in your code - not 100% related to your question, though:
You are going a bit clumsy about this. Since you're writing Python code, there is a much easier way:
Since
ball_listis a list, which is iterable, you can directly loop over the list and get each ball object. You do not need to iterate over the length of the list and then, access the elements by index.Thick-Standard-2396@reddit
Yeah the ball should definitely handle its own physics updates, that's way cleaner. You could add an `update()` method to Ball that takes delta_time and does all the gravity/collision stuff, then sim just calls `ball.update(delta_time)` for each one
Drawing is bit trickier since arcade needs the actual coordinates but you could still have Ball return its draw parameters or handle the arcade call itself. Makes adding new ball types much easier later when you don't have to touch sim class every time
Skyshaper@reddit
What you're saying is the physics are stored in the balls (or at least, should be).
Temporary_Pie2733@reddit
Every argument to
draw_circle_filledcomes from the same instance ofBall. I’d do something likeXypheric@reddit
Just wanted to comment and say it’s refreshing to see some actual questions and code here these days!
desrtfx@reddit
IMO, any object should be self responsible for what it can do.
This means that the ball should update itself when it's due for an update - signaled through an
update()method in the class, and it should also be able to draw itself, which would also mean that it should, when created, get the link to thearcadepassed into.This way, you can offload the actual recalculation and drawing to the individual objects and only need to loop over the objects in your
Sim.This approach, especially the
updategoes in hand with the Observer (or publisher/subscriber) design pattern.The subscriber (ball) presents a method, like "update" or "notify" and the publisher (Sim) maintains a list of subscribers and notifies them when it's their time to do something (like updating, or drawing).
You might even have already used that pattern without knowing that it is a design pattern.