def step(self, dt): """ Computes one game step or tick, dt being the approx time elapsed since the previous tick """ black = (0, 0, 0) self.screen.fill(black) # Handle body drag creation self.input.update() if self.input.body: body = self.input.body clickP = self.input.clickPosition pg.draw.line(self.screen, pg.Color(255,255,255,255), (clickP.x, clickP.y), (body.position.x, body.position.y), 1) self.drawCircle(self.screen, self.screenToWorld(body.position), pg.Color(255,255,255,255), body.radius) lockedPhysicsList = [] # Used for dynamic calculations and collisions # Iterate over tree, update and draw for body in self.rootBody: body.update(dt) bodyPos = body.getWorldPosition() self.drawCircle(self.screen, bodyPos, body.color, body.radius) lockedPhysicsList.append(body) # Update and draw all dynamic bodies for index, body in enumerate(self.dynamicBodies): body.update(lockedPhysicsList, dt) self.drawCircle(self.screen, (body.position), pg.Color(255,255,255,255), body.radius) if Vec2D.magnitudeSquared(body.position) > 1000000 or body.hasCollided(): # Out of game area del self.dynamicBodies[index] pg.display.flip()
def update(self, lockedBodies, dt): """ Updates velocity and applies to position based on all the locked bodies in the system """ for body in lockedBodies: rawDisplace = body.getWorldPosition() - self.position direction = Vec2D.normalize(rawDisplace) displacementSquared = Vec2D.magnitudeSquared(rawDisplace) acceleration = dt * self.gConstant * body.mass / max( 10, displacementSquared ) # min radius 10 to prevent crazy acceleration self.velocity = self.velocity + Vec2D.scale( direction, acceleration) self.position = self.position + self.velocity # Have we collided if not self.collided: actualDisplacement = math.sqrt(displacementSquared) if actualDisplacement < (self.radius + body.radius): self.collided = True # Collision has occured