I'm trying to make a game, but first I want to create a simple simulator.
The goal is to drop a ball on a surface and then roll it off the edge.
Here is my code:
import os, sys, math, pygame, pygame.mixer
from pygame.locals import *
import randomly
import euclid
import pdb
Import math
#Definate some basic colors
black = 0, 0, 0
White = 255, 255, 255
Red = 255, 0, 0
green = 0, 255, 0
blue = 0, 0, 255
Colors = [black, red, green, blue]
Gravity = Euclidean vector2 (0,0,80,0)
draw = 0.1
initial_velocity = 20
#Definition of the screen size
screen_size = screen_width, screen_height = 600, 400
Class MyCircle:
def __init __ (self, position, size, color = (255, 255, 255), velocity = Euclid.Vector2 (0,0), acceleration = Euclid.Vector2 (0,0), width = 1):
Self position = position
self.size = size
self.color = color
self.width = width
self.velocity = speed
self.accel = accel
#__ set_initial_velocity ()
def display (self):
rx, ry = int (self.position.x), int (self.position.y)
pygame.draw.circle (screen, self.color, (rx, ry), self.size, self.width)
def move (self):
self.position + = self.velocity * dtime + 0.5 * (self.accel * (dtime ** 2))
self.velocity + = self.accel * dtime
# self.velocity - = self.velocity * drag * dtime
# self.bounce ()
def change_velocity (self, speed):
self.velocity = speed
def bounce (self):
if self.position.x <= self.size:
self.position.x = 2*self.size-self.position.x
self.velocity = self.velocity.reflect(euclid.Vector2(1,0))
elif self.position.x >= screen_width - self.size:
self.position.x = 2 * (screen_width - self.size) - self.position.x
self.velocity = self.velocity.reflect (euclid.Vector2 (1,0))
if self.position.y <= self.size:
self.position.y = 2*self.size - self.position.y
self.velocity = self.velocity.reflect(euclid.Vector(0,1))
elif self.position.y >= screen_height - self.size:
self.position.y = 2 * (screen_height - self.size) - self.position.y
self.velocity = self.velocity.reflect (euclid.Vector2 (0,1))
# Equation for the distance between surfaces
#d (t) = | A (t) -B (t) | - (Ra + Rb)
def surface_distance (self, other, time):
radiiAB = self.size + other.size
posA = self.position + self.velocity * time + 0.5 * (self.accel * (time ** 2))
posB = other.position + other.velocity * time + 0.5 * (other.accel * (time ** 2))
posAB = abs (posA-posB)
return posAB - radiiAB
def collide (yourself, others):
if self.surface_distance (other, dtime) <= 0:
collision_vector = self.position - other.position
collision_vector.normalize ()
self.velocity = self.velocity.reflect (collision_vector)
other.velocity = other.velocity.reflect (collision_vector)
Class MySurface ():
def __init __ (self, size, color = (255, 255, 255), angle = math.pi / 2, width = 0):
self.theta = angle
self.position1 =[50,100]
self.position2 =[self.position1[0]+ 50 * math.cos (self-position1[0])
Selbstposition1[1]+ 50 * abs (math.sin (self-position1[1]))]self.color = color
self.width = width
self.accel = euclid.Vector2 (schwerkraft.y * math.cos (self.theta), - 1 * schwerkraft.y * math.sin (self.theta))
# pdb.set_trace ()
def display (self):
line = pygame.draw.aaline (screen, (0,0,0), self-position1, self-position2,5)
def surface_distance (self, circ, time):
theta = self & thetas;
pos_ball = orbital position + orbital velocity * time + 0.5 * (orbital period * (time ** 2))
#map coordinates to the surface the ball should contact
ball_y = self.position1[1]- (- 1 * pos_ball.x * math.sin (theta) + pos_ball.y * math.cos (theta))
# Map the actual surface into its own coordinate system
pos1y_adjusted = self.position1[1]- (- 1 * self.position1[1]* math.sin (theta) + self.position1[1]* math.cos (theta))
ydelta = ball_y-pos1y_adjusted
return value
def collide (self, compass, counter):
ydelta = self.surface_distance (circ, dtime)
if ydelta <= circ.size:
circ.accel = self.accel # adjusts the acceleration based on the line angle
if counter <1:
circ.velocity = euclid.Vector2 (0,0)
Counter = counter + 1
otherwise:
Counter + = 1
Return counter
# pdb.set_trace ()
#Setting the display and getting the surface object
screen = pygame.display.set_mode (screen_size)
#Create a UHB object
clock = pygame.time.Clock ()
# Put a title on the window
pygame.display.set_caption (& # 39; First Class! & # 39;)
number_of_circles = 10
my_circles = []
Create #ball
Size = 10
Color = colors[0]
my_circle = MyCircle (euclid.Vector2 (70,40), size, color, euclid.Vector2 (0,0), gravity)
my_circle.velocity = euclid.Vector2 (0,10)
my_circle.velocity.normalize ()
# Create a surface
Angle = -1 * math.radians (30)
my_surface = MySurface (screen, color, angle)
direction_tick = 0.0
Counter = 0;
# Defines variables for fps and continues to run
fps_limit = 60
run_me = true
while run_me:
# Limit the frame rate
clock.tick (fps_limit)
for an event in pygame.event.get ():
if event.type == pygame.QUIT:
run_me = false
# Limit the frame rate
dtime_ms = clock.tick (fps_limit)
dtime = dtime_ms / 1000.0
# Delete the screen
Screen lock ()
screen.fill (white)
counter = my_surface.collide (my_circle, counter)
my_circle.move ()
my_circle.display ()
my_surface.display ()
screen.unlock ()
# Show everything on the screen
pygame.display.flip ()
# Leave the game
pygame.quit ()
sys.exit ()
Everything starts fine as shown below:
As soon as you run the game, the ball will run in the same direction:
Now I know that I can adjust the acceleration vectors again as soon as the ball reaches the edge of the surface. Is there something in Pygame that already does the appropriate physics for me?
I.U. In Unity, there is a concept of RigidBody, and the ball hits the RigidBody and rolls off. As soon as he reaches the body edge, the ball changes the acceleration.
Here is the link for euclid: https://github.com/xocoatzin/pyeuclid/blob/master/euclid.py