I've been trying to make a code with pygame to simulate simple gravity. At the moment, there is only one object (HOM) which is orbiting the sun. However, for reasons unknown to me, whenever I run the code, HOM travels round the sun in an orbit at the start, but then accelerates away from the sun when it reaches ~135 degrees from vertical.
Does anyone know why this is happening and how I can fix it? I have been printing some variables to try and source the problem, but have had no luck so far.
Code:
import pygame,sys,time
from math import *
screen=pygame.display.set_mode((800,600))
G = 5
class Object: #Just an object, like a moon or planet
def __init__(self,mass,init_cds,init_vel,orbit_obj='Sun'):
self.mass = mass
self.cds = init_cds
self.velocity = init_vel
self.accel = [0,0]
self.angle = 0
self.orb_obj = orbit_obj
def display(self):
int_cds = (round(self.cds[0]),round(self.cds[1]))#Stores its co-ordinates as floats, has to convert to integers for draw function
pygame.draw.circle(screen,(255,0,0),int_cds,10)
def calc_gravity(self):
if self.orb_obj == 'Sun':
c_x,c_y = 400,300
c_mass = 10000
else:
c_x,c_y = self.orb_obj.cds
c_mass = self.orb_obj.mass
d_x = self.cds[0]-c_x
d_y = self.cds[1]-c_y
dist = sqrt(d_x**2+d_y**2) #Find direct distance
angle = atan(d_x/d_y) #Find angle
print(d_x,d_y)
print(dist,degrees(angle))
if dist == 0:
acc = 0
else:
acc = G*c_mass/(dist**2) #F=G(Mm)/r^2, a=F/m -> a=GM/r^2
print(acc)
acc_x = acc*sin(angle) #Convert acceleration from magnitude+angle -> x and y components
acc_y = acc*cos(angle)
self.accel = [acc_x,acc_y]
print(self.accel)
self.velocity = [self.velocity[0]+self.accel[0],self.velocity[1]+self.accel[1]] #Add acceleration to velocity
print(self.velocity)
self.cds = (self.cds[0]+self.velocity[0],self.cds[1]+self.velocity[1]) #Change co-ordinates by velocity
print(self.cds)
print('-------------------') #For seperating each run of the function when printing variables
HOM = Object(1000000,(400,100),[10,0]) #The problem planet
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill((0,0,0))
pygame.draw.circle(screen,(255,255,0),(400,300),25)
HOM.display()
HOM.calc_gravity()
clock.tick(30)
pygame.display.flip()