Created
July 18, 2013 00:13
-
-
Save matheusgomes28/6025721 to your computer and use it in GitHub Desktop.
Simple Python game. This game was created to simulate some (not all) laws of physics and mathematics such as gravity, forces, vectors etc... Free to use and modify!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame, sys | |
import pygame.gfxdraw | |
pygame.init() | |
class Obstacle(object): | |
""" The Obstacle class defines simple methods and properties of | |
obstacle objects such as rectangles and circles""" | |
def __init__(self, center, WIDTH, HEIGHT): | |
self.center = pygame.math.Vector2(center) | |
self.WIDTH = WIDTH | |
self.HEIGHT = HEIGHT | |
self.top_left = [(self.center[0] - (WIDTH / 2)),(self.center[1] - (HEIGHT / 2))] | |
def in_range(directions, width, height): | |
"""This method returns True if the object is | |
inside the range of another object (NOT CIRCLE!!!)""" | |
class Ball(Obstacle): | |
""" | |
This class defines a ball object | |
(surface, color, center, width/radius) -> GUI object. | |
""" | |
def __init__(self, SURFACE, COLOR, center, WIDTH): | |
assert (type(center) == tuple), "Center must be a coordinate" | |
Obstacle.__init__(self, center, WIDTH, WIDTH) # Width sent twice as the height = width. | |
self.SURFACE = SURFACE | |
self.COLOR = COLOR | |
self.RADIUS = int(self.WIDTH / 2) | |
def draw(self): | |
#pygame.draw.circle(self.SURFACE, self.COLOR, (int(self.center[0]), int(self.center[1])), self.RADIUS, 2) | |
pygame.gfxdraw.filled_circle(self.SURFACE, int(self.center[0]), int(self.center[1]), self.RADIUS, self.COLOR) | |
pygame.gfxdraw.aacircle(self.SURFACE, int(self.center[0]), int(self.center[1]), self.RADIUS, self.COLOR) | |
def move(self, valueX=0, valueY=0): | |
#Reassigning center vector | |
self.center[0] = ((self.center[0] + valueX) % 400) | |
self.center[1] = (self.center[1] + valueY) | |
self.draw() | |
class RecObstacle(Obstacle): | |
""" | |
The RecObstacle class creates a new rectangle instance and adds | |
methods and properties that allow the created rectangle to be | |
added to the 'display surface' | |
(surface, color, center, width, height) -> GUI object | |
[display obj, list, list, int, int] | |
""" | |
def __init__(self, SURFACE, COLOR, center, WIDTH, HEIGHT): | |
Obstacle.__init__(self,(center[0], center[1]), WIDTH, HEIGHT) | |
self.SURFACE = SURFACE | |
self.COLOR = COLOR | |
self.directions = [[0,1]] | |
def draw(self): | |
pygame.draw.rect(self.SURFACE, self.COLOR, (self.top_left[0], self.top_left[1], self.WIDTH, self.HEIGHT)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame | |
pygame.init() | |
def calculate_accel(forces, m): | |
"""This function will calculate the acceleration | |
of an object using newton's law: F = MA | |
if mass = 1: | |
calculate_accel([0,10]) -> [0,10] | |
""" | |
temp = [0,0] # Temporary holder for resultant force | |
for i in forces: | |
temp[0] = temp[0] + i[0] | |
temp[1] = temp[1] + i[1] | |
return pygame.math.Vector2([round(temp[0] / m), round(temp[1] / m)]) | |
def ball_collision(list_of_balls): | |
""" This function returns True if a ball | |
object collides with another ball object""" | |
for a1 in list_of_balls: | |
for a2 in list_of_balls: | |
if (a1.center.distance_to(a2.center)) <= (a1.RADIUS + a2.RADIUS): | |
if a1.center != a2.center: | |
return True | |
else: | |
return False | |
else: | |
return False | |
def handle_ground_collision(ball_obj, rec_obj): | |
"""This function works as a collision detection for | |
the ground and the ball. This is still a primitive | |
collision detector. | |
(all object, Rectangle object) -> Boolean""" | |
temp = pygame.math.Vector2((ball_obj.center[0], ball_obj.center[1] + ball_obj.RADIUS)) | |
if temp.distance_to([ball_obj.center[0], rec_obj.center[1] - rec_obj.HEIGHT/2]) == 0: | |
return True | |
else: | |
return False |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame, classes, sys | |
from pygame.locals import * | |
from functions import * | |
pygame.init() #Initialising pygame functions and variables | |
#Colors R G B | |
BLACK = ( 0, 0, 0) | |
WHITE = (255,255,255) | |
BLUE = ( 0, 0,255) | |
FPS = 150 #Frames per second / display update time | |
######################### | |
### Movement settings ### | |
######################### | |
forces = [] # Empty forces list / holds forces acting on a particle / Forces in newtons | |
mass = 10 # Mass of the ball in kg. | |
g = 9.8 #universal gravity pull | |
ACCEL = pygame.math.Vector2((0, 0)) #Acceleration vector | |
velocity = pygame.math.Vector2([0,0]) #Velocity starting at 0 | |
METRES = 200 # 200 pixels == 1 metres | |
friction = 3 | |
is_vert_rest = False | |
def detect_collision(ball_center, rec_direction, rec_range): | |
"""Advanced collision detection, uses vectors in order | |
to triangulate positions and distances.""" | |
pass | |
def main(): | |
""" Main program precedure. This function contains | |
the game loop.""" | |
global DISPLAY, FPSCLOCK, ball, rectangle #Canvas globals created inside main function / only initializes if this is "__main__" | |
global ACCEL, velocity, forces, is_vert_rest # Outside-created variables / Re-declaring so we can modify the values globally | |
# Display settings | |
DISPLAY = pygame.display.set_mode((400,600)) | |
pygame.display.set_caption("Vector Test") | |
ball = classes.Ball(DISPLAY, BLUE, (200, 200), 40) | |
rectangle = classes.RecObstacle(DISPLAY, BLACK, (200,575), 400, 50) | |
FPSCLOCK = pygame.time.Clock() | |
while True: | |
## Constant updates of the game ### | |
DISPLAY.fill(WHITE) | |
rectangle.draw() | |
############################ | |
### Dynamics of the ball ### | |
############################ | |
forces.append([0, mass * g]) # Acceleration due to gravity | |
#Collision detection | |
if handle_ground_collision(ball, rectangle): | |
velocity[1] = -.8*(velocity[1]) | |
velocity[0] = velocity[0] * (1 - (friction / FPS)) | |
if velocity[1] < (1/FPS) and velocity[1] > -(1/FPS): #Limit of movement | |
is_vert_rest = True | |
else: | |
is_vert_rest = False | |
ball.draw() | |
#Velocity update | |
velocity[1] = velocity[1] + (ACCEL[1] / FPS) | |
if (ball.center[1] + ball.RADIUS) + (velocity[1] + (ACCEL[1] / FPS)) >= (rectangle.center[1] - (rectangle.HEIGHT / 2)): | |
ball.move(velocity[0], (rectangle.center[1] - rectangle.HEIGHT/2) - (ball.center[1] + ball.RADIUS)) | |
else: | |
ball.move((velocity[0] * METRES) / FPS, (velocity[1] * METRES) / FPS) | |
############################ | |
if is_vert_rest: | |
ACCEL[1] = 0 | |
velocity[1] = 0 | |
else: | |
ACCEL = calculate_accel(forces, mass) # Calculate acceleration | |
forces = [] | |
mouse = pygame.mouse.get_pressed() | |
mouse_pos = pygame.mouse.get_pos() | |
if mouse[0]: | |
pygame.draw.aaline(DISPLAY, BLACK, mouse_pos, ball.center) | |
# QUIT event checking | |
for event in pygame.event.get(): | |
if event.type == QUIT: | |
pygame.quit() | |
sys.exit() | |
elif event.type == MOUSEBUTTONUP : | |
velocity[0] = velocity[0] + (mouse_pos[0] - ball.center[0]) / (METRES / 4) | |
velocity[1] = velocity[1] + (mouse_pos[1] - ball.center[1]) / (METRES / 4) | |
pygame.display.update() # update the canvas | |
FPSCLOCK.tick(FPS) | |
if __name__ == "__main__": | |
main() | |
################## | |
# CODE BY: Matheus Gomes | |
# Open source | |
# Free to use and modify | |
################## |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment