Skip to content

Instantly share code, notes, and snippets.

@matheusgomes28
Created July 18, 2013 00:13

Revisions

  1. matheusgomes28 created this gist Jul 18, 2013.
    64 changes: 64 additions & 0 deletions classes.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    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))
    48 changes: 48 additions & 0 deletions functions.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    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
    125 changes: 125 additions & 0 deletions main.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,125 @@
    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
    ##################