I am creating a physics engine in python pygame and have recently encountered a problem when trying to reset the velocities and positions of my particles (balls) when pressing r. I did a lot of tests and even asked chat GPT but all I found was that ball.initialvel = ball.vel after it is assigned, and does not hold its original value, changing every time ball.vel is changed, which should not happen as this part of the code is only called once. Any help would be appreciated.
import numpy as npimport pygamefrom dataclasses import dataclassimport randomimport string# Molecular Dynamicsimport pygame# pygame setuppygame.init()screen = pygame.display.set_mode((1280, 720))clock = pygame.time.Clock()running = Truedt = 0#Constants and Initialisationsr = 40M = 10g = pygame.Vector2(0, 9.81)#Classes and Functions@dataclass class ball: #What properties is each ball going to have? rad: float = 40 colour: str = "red" vel: pygame.Vector2 = None pos: pygame.Vector2 = None accel: pygame.Vector2 = None mass: float = 1 initialvel: pygame.Vector2 = None **#initialised here** initialpos: pygame.Vector2 = None # Prevents bugs idfk def __post_init__(self): if self.pos is None: self.pos = pygame.Vector2(screen.get_width() / 2, screen.get_height() / 2) if self.vel is None: self.vel = pygame.Vector2(40,30) if self.accel is None: self.accel = g #Box collision algorithm reverses velocity when collides def BoxCollision(self): if self.pos.x - self.rad <= 50 or self.pos.x + self.rad >= 1230: self.vel.x = -self.vel.x if self.pos.y - self.rad <= 50 or self.pos.y + self.rad >= 670: self.vel.y = -self.vel.y #Frame by fram position update (verlet integration needed) def PosUpdate(self): pygame.draw.circle(screen, self.colour, self.pos, self.rad) self.vel += self.accel * dt self.BoxCollision() self.pos += self.vel * dt#Declarations of balls (objects)ballR = ball()ballB = ball(30,"blue" , pygame.Vector2(-35,40))ballY = ball(30,"yellow" , pygame.Vector2(-55,100))ballz = [ballR, ballB, ballY]**#ball initial positions and velocities are set here, despite this only being run once, i.intialpos and i.initialvel remains stuck to i.pos and i.vel and does not keep its original value.**for i in ballz: i.initialpos = i.pos i.initialvel = i.vel#Main Loopwhile running: # poll loop for events # pygame.QUIT event means the user clicked X to close your window for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): running = False# **Attempting to reset velocities and positions however they are equal at all times so this does nothing** #Restart function if event.type == pygame.KEYDOWN and event.key == pygame.K_r: for allballs in ballz: print("Before reset - Initial Velocity:", allballs.initialvel) print("Before reset - Velocity:", allballs.vel) allballs.pos = allballs.initialpos allballs.vel = allballs.initialvel # Reset velocity to initial value print("After reset - Initial Velocity:", allballs.initialvel) print("After reset - Velocity:", allballs.vel) #Wait 1 minute for analysis if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: pygame.time.wait(60000) #Create new ball function #if event.type == pygame.KEYDOWN and event.key == pygame.K_b: #random.choice(string.ascii_letters) = ball(50, "green", pygame.Vector2(random.randrange(100), 9)) # fill the screen with a color to wipe away anything from last frame screen.fill("black") # pygame.draw.rect(screen, colour, (x, y, width, height) box = pygame.draw.rect(screen, "blue", (50, 50, 1180, 620), width = 1) #position update ballR.PosUpdate() ballB.PosUpdate() ballY.PosUpdate() # flip() the display to put your work on screen pygame.display.flip() #print(ball_vel) # limits FPS to 60 # dt is delta time in seconds(not really) since last frame, used for framerate- # independent physics. dt = clock.tick(144) / 100pygame.quit()