예제 #1
0
def main():
    pygame.init()

    # Variable where the position where the new ball will be placed is stored
    mouseDownPosition = Vec2d(-1, -1)

    #Import images
    background = pygame.image.load("background.png")
    background = pygame.transform.scale(background, (1600, 600))

    background2 = pygame.image.load("background2.png")
    background2 = pygame.transform.scale(background2, (1600, 600))

    star = pygame.image.load("star-icon.png")
    star = pygame.transform.scale(star, (100, 100))

    star2 = pygame.image.load("star-icon2.png")
    star2 = pygame.transform.scale(star2, (100, 100))

    width = 1600
    height = 600
    screen = pygame.display.set_mode([width, height])
    screen_center = Vec2d(width / 2, height / 2)
    coords = Coords(screen_center.copy(), 1, True)
    zoom = 100
    coords.zoom_at_coords(Vec2d(0, 0), zoom)

    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()

    # Initialize menu
    startButton = pygame.Rect(250, 200, 300, 50)
    controlsButton = pygame.Rect(250, 300, 300, 50)
    quitButton = pygame.Rect(250, 400, 300, 50)
    backButton = pygame.Rect(250, 500, 300, 50)

    myfont = pygame.font.SysFont('Comic Sans MS', 30)
    title = myfont.render('GRUMPY LIZADS', False, (0, 0, 0))
    play = myfont.render('Play', False, (0, 0, 0))
    controls = myfont.render('Controls', False, (0, 0, 0))
    quitGame = myfont.render('Quit', False, (0, 0, 0))
    back = myfont.render('Back', False, (0, 0, 0))

    # -------- Main Program Loop -----------\
    frame_rate = 60
    n_per_frame = 5
    playback_speed = 1  # 1 is real time, 10 is 10x real speed, etc.
    dt = playback_speed / frame_rate / n_per_frame

    # Variable where the position where the new ball will be placed is stored
    mouseDownPosition = Vec2d(-1, -1)

    # Main game loop
    exitGame = False
    while not exitGame:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exitGame = True

            if event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = event.pos  # gets mouse position

                # checks if mouse position is over the button
                if quitButton.collidepoint(mouse_pos):
                    exitGame = True
                if controlsButton.collidepoint(mouse_pos):
                    fire = myfont.render('Fire:   Left Click and Drag', False,
                                         (0, 0, 0))
                    panRight = myfont.render('Pan Right:   Right Arrow Key',
                                             False, (0, 0, 0))
                    panLeft = myfont.render('Pan Left:   Left Arrow Key',
                                            False, (0, 0, 0))
                    controlsDone = False
                    while not controlsDone:
                        for event in pygame.event.get():
                            if event.type == pygame.QUIT:  # If user clicked close
                                controlsDone = True
                                exitGame = True
                            if event.type == pygame.MOUSEBUTTONDOWN:
                                mouse_pos = event.pos

                                if backButton.collidepoint(mouse_pos):
                                    controlsDone = True
                        # Draw
                        screen.blit(background, (0, 0))
                        screen.blit(title, (275, 100))

                        pygame.draw.rect(screen, GRAY, backButton)
                        screen.blit(back, (370, 500))

                        screen.fill(CLEARGRAY, pygame.Rect(200, 200, 400, 50))
                        screen.fill(CLEARGRAY, pygame.Rect(200, 300, 400, 50))
                        screen.fill(CLEARGRAY, pygame.Rect(200, 400, 400, 50))

                        screen.blit(fire, (225, 200))
                        screen.blit(panRight, (205, 300))
                        screen.blit(panLeft, (220, 400))

                        # --- Update the screen with what we've drawn.
                        pygame.display.update()

                        # This limits the loop to 60 frames per second
                        clock.tick(frame_rate)

                if startButton.collidepoint(mouse_pos):
                    # Create initial objects to demonstrate
                    objects = []
                    backgroundOffset = 0
                    mouseDownPosition = Vec2d(-1, -1)
                    score = 0
                    breakables = 3
                    scoreText = myfont.render("Score = " + str(score), False,
                                              (255, 255, 255))

                    # Blocks

                    objects.append(
                        Polygon(Vec2d(2, -1.75), Vec2d(0, 0), 1,
                                make_rectangle(2, 1), GRAY, 0, 0))
                    objects.append(
                        Polygon(Vec2d(1.4, -.25), Vec2d(0, 0), 1,
                                make_rectangle(0.6, 1.7), GRAY, 0, 0))
                    objects.append(
                        Polygon(Vec2d(2.6, -.25), Vec2d(0, 0), 1,
                                make_rectangle(0.6, 1.7), GRAY, 0, 0))
                    objects.append(
                        Polygon(Vec2d(5, -.25), Vec2d(0, 0), 1,
                                make_rectangle(1, 4), GRAY, 0, 0))

                    # PIGS
                    objects.append(
                        Polygon(Vec2d(2, -1), Vec2d(0, 0), 1,
                                make_rectangle(0.4, 0.4), GREEN, 0, 0, True,
                                True))
                    objects.append(
                        Polygon(Vec2d(5, 2), Vec2d(0, 0), 1,
                                make_rectangle(0.4, 0.4), GREEN, 0, 0, True,
                                True))
                    objects.append(
                        Polygon(Vec2d(7, -2), Vec2d(0, 0), 1,
                                make_rectangle(0.4, 0.4), GREEN, 0, 0, True,
                                True))

                    # Walls
                    objects.append(Wall(Vec2d(0, -2.25), Vec2d(0, 1), BLACK))
                    objects.append(Wall(Vec2d(-8, 0), Vec2d(1, 0), BLACK))
                    objects.append(Wall(Vec2d(8, 0), Vec2d(-1, 0), BLACK))

                    done = False
                    lineDrawn = False
                    count = 0
                    max_collisions = 1
                    result = []
                    while not done:
                        # --- Main event loop
                        for event in pygame.event.get():
                            if event.type == pygame.QUIT:  # If user clicked close
                                objects = []
                                exitGame = True
                                done = True
                            elif event.type == pygame.KEYDOWN:
                                if event.key == pygame.K_ESCAPE:
                                    objects = []
                                    done = True
                            elif event.type == pygame.MOUSEBUTTONDOWN:
                                if pygame.mouse.get_pressed(
                                )[0] and mouseDownPosition.x == -1:
                                    # Set mouseDownPosition to the currernt position
                                    mouseDownPosition = Vec2d(
                                        pygame.mouse.get_pos()[0],
                                        pygame.mouse.get_pos()[1])
                                    lineDrawn = True

                        # When the user releases the mouse button
                        if pygame.mouse.get_pressed(
                        )[0] == False and mouseDownPosition.x != -1:
                            # Calculate the velocity based on the distance between the two mouse positions
                            newVelocityX = (mouseDownPosition.x -
                                            pygame.mouse.get_pos()[0]) * 0.07
                            newVelocityY = (mouseDownPosition.y -
                                            pygame.mouse.get_pos()[1]) * -0.07
                            # Create the new ball
                            #cannon(Vec2d(-3, 0), Vec2d(newVelocityX,newVelocityY))
                            objects.append(
                                Polygon(Vec2d(-6.8, -1.1),
                                        Vec2d(newVelocityX, newVelocityY), 1,
                                        make_polygon(0.3, 8, 0, 1), BLACK, 0,
                                        0, False))
                            count += 1
                            mouseDownPosition = Vec2d(-1, -1)
                            lineDrawn = False
                        """
                        keys = pygame.key.get_pressed()
                        if keys[pygame.K_RIGHT]:
                            if(backgroundOffset > -800):
                                coords.pan_in_coords(Vec2d(.1,0))
                                backgroundOffset -= 10
                        if keys[pygame.K_LEFT]:
                            if(backgroundOffset < 0):
                                coords.pan_in_coords(Vec2d(-.1,0))
                                backgroundOffset += 10
                        """
                        if count == 3 or breakables == 0:
                            score += 20 * (3 - count)
                            scoringDone = False
                            done = True
                            while not scoringDone:
                                # --- Main event loop
                                for event in pygame.event.get():
                                    if event.type == pygame.QUIT:  # If user clicked close
                                        objects = []
                                        exitGame = True
                                        scoringDone = True
                                    elif event.type == pygame.KEYDOWN:
                                        if event.key == pygame.K_ESCAPE:
                                            objects = []
                                            scoringDone = True

                                for N in range(n_per_frame):
                                    # Physics
                                    # Calculate the force on each object
                                    for obj in objects:
                                        obj.force.zero()
                                        obj.force += Vec2d(0, -10)  # gravity

                                    # Move each object according to physics
                                    for obj in objects:
                                        obj.update(dt)

                                    for i in range(max_collisions):
                                        collided = False
                                        for i1 in range(len(objects)):
                                            for i2 in range(i1):
                                                if check_collision(
                                                        objects[i1],
                                                        objects[i2], result):
                                                    resolve_collision(result)
                                                    collided = True
                                                    #print("Collision")
                                                    #paused = True
                                        if not collided:  # if all collisions resolved, then we're done
                                            break

                                # Draw background
                                screen.blit(background, (backgroundOffset, 0))

                                # Drawing
                                for obj in objects:
                                    obj.draw(screen, coords)

                                for obj in objects:
                                    if obj.destroyed:
                                        #Update Score
                                        if obj.pig:
                                            breakables -= 1
                                            score += 20
                                        score += round(Decimal(obj.mass),
                                                       2) * 2
                                        scoreText = myfont.render(
                                            "Score = " + str(score), False,
                                            (255, 255, 255))

                                        #Delete destroyed objects
                                        objects.remove(obj)
                                        del obj

                                screen.blit(background2, (backgroundOffset, 0))

                                # Draw score
                                screen.blit(scoreText, (700, 250))

                                if breakables == 3:
                                    screen.blit(star2, (600, 100))
                                    screen.blit(star2, (740, 100))
                                    screen.blit(star2, (890, 100))
                                if breakables == 2:
                                    screen.blit(star, (600, 100))
                                    screen.blit(star2, (740, 100))
                                    screen.blit(star2, (890, 100))
                                if breakables == 1:
                                    screen.blit(star, (600, 100))
                                    screen.blit(star, (740, 100))
                                    screen.blit(star2, (890, 100))
                                if breakables == 0:
                                    screen.blit(star, (600, 100))
                                    screen.blit(star, (740, 100))
                                    screen.blit(star, (890, 100))

                                # --- Update the screen with what we've drawn.
                                pygame.display.update()

                                # This limits the loop to the specified frame rate
                                clock.tick(frame_rate)

                        for N in range(n_per_frame):
                            # Physics
                            # Calculate the force on each object
                            for obj in objects:
                                obj.force.zero()
                                obj.force += Vec2d(0, -10)  # gravity

                            # Move each object according to physics
                            for obj in objects:
                                obj.update(dt)

                            for i in range(max_collisions):
                                collided = False
                                for i1 in range(len(objects)):
                                    for i2 in range(i1):
                                        if check_collision(
                                                objects[i1], objects[i2],
                                                result):
                                            resolve_collision(result)
                                            collided = True
                                            #print("Collision")
                                            #paused = True
                                if not collided:  # if all collisions resolved, then we're done
                                    break

                        # Draw background
                        screen.blit(background, (backgroundOffset, 0))

                        # Drawing
                        for obj in objects:
                            obj.draw(screen, coords)  # draw object to screen

                        for obj in objects:
                            if obj.destroyed:
                                #Update Score
                                if obj.pig:
                                    breakables -= 1
                                    score += 20
                                score += round(Decimal(obj.mass), 2) * 2
                                scoreText = myfont.render(
                                    "Score = " + str(score), False,
                                    (255, 255, 255))

                                #Delete destroyed objects
                                objects.remove(obj)
                                del obj

                        screen.blit(background2, (backgroundOffset, 0))

                        # Draw score
                        screen.blit(scoreText, (50, 50))

                        if lineDrawn:
                            pygame.draw.line(screen, BLACK, mouseDownPosition,
                                             pygame.mouse.get_pos(), 1)
                        # --- Update the screen with what we've drawn.
                        pygame.display.update()

                        # This limits the loop to the specified frame rate
                        clock.tick(frame_rate)

        # Draw background
        screen.blit(background, (0, 0))

        # Draw buttons
        pygame.draw.rect(screen, GRAY, startButton)
        pygame.draw.rect(screen, GRAY, controlsButton)
        pygame.draw.rect(screen, GRAY, quitButton)

        # Draw Text
        screen.blit(title, (275, 100))
        screen.blit(play, (370, 200))
        screen.blit(controls, (340, 300))
        screen.blit(quitGame, (370, 400))

        # --- Update the screen with what we've drawn.
        pygame.display.update()

        # This limits the loop to the specified frame rate
        clock.tick(frame_rate)

    pygame.quit()
예제 #2
0
def main():
    pygame.init()

    width = 1200
    height = 800

    screen = pygame.display.set_mode([width, height])
    screen_center = Vec2d(width / 2, height / 2)
    coords = Coords(screen_center.copy(), 1, True)
    # ^ Center of window is (0,0), scale is 1:1, and +y is up

    coords.zoom_at_coords(Vec2d(0, 0), 2)
    # ^Sets camera center

    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()

    planets = []

    frame_rate = 60
    playback_speed = 1
    dt = playback_speed / frame_rate
    paused = False
    done = False

    mouseClicked = False
    mousePosDown = Vec2d(0, 0)
    mousePosUp = Vec2d(0, 0)

    wall1 = Wall(Vec2d(150, 0), 45, 213, 4)
    wall2 = Wall(Vec2d(-150, 0), 315, 213, 4)

    print(wall1.normal)
    print(wall2.normal)

    while not done:
        gameMouse = pygame.mouse  #Mouse obj
        mousePosTup = gameMouse.get_pos(
        )  #Mouse pos in default coordinates as list
        mousePosVec = Vec2d(
            mousePosTup[0],
            mousePosTup[1])  #Mouse pos in default coordinates as vec2d
        mouseCoordPos = coords.pos_to_coords(
            mousePosVec)  #Mouse pos in standardized coords as vec2d

        initVelocity = 0

        # --- Main event loop
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  # If user clicked close
                done = True
            if event.type == pygame.MOUSEBUTTONDOWN:
                paused = True
                if mouseClicked == False:
                    mouseClicked = True
                    mousePosDown = mouseCoordPos  #wiil get the pos of Mouse at first click location
                    print("setting planet")
                    global newPlanet
                    newPlanet = CircleLine(Vec2d(0, 0), mousePosDown, 15)

                if mouseClicked == True:
                    mousePosUp = mouseCoordPos  #For drawing initial velocity vector
                    #draw a vector on screen here

            if event.type == pygame.MOUSEBUTTONUP:
                mouseClicked = False
                mousePosUp = mouseCoordPos

                initVelocity = mousePosUp - mousePosDown
                print("Vel", initVelocity.x, initVelocity.y)
                initVelocity *= 0.1
                print("Vel", initVelocity.x, initVelocity.y)

                initMom = initVelocity * newPlanet.mass
                newPlanet.vel = initVelocity
                newPlanet.mom = initMom
                planets.append(newPlanet)
                #will add new planet to the array of planets with vector of mouse up and mouse click
                paused = False

                print("Have to send planet in vector from center to mouse")

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    paused = not paused
                if event.key == pygame.K_0 or pygame.K_KP0:
                    com = ForceCalculator.calculateCOM(planets)
                    comVel = ForceCalculator.calculateCOMVel(planets)
                    for obj in planets:
                        obj.center -= com
                        obj.vel -= comVel
                        obj.mom = obj.vel * obj.mass
        #If the game is not paused, update the objects in it
        if (not paused):
            objLen = len(planets)
            for i in range(0, objLen):
                #                forces = []
                #                for j in range(0, objLen):
                #                    #Calculate a force that each object has on this object and append it to the list of foces acting on it
                #                    if(not i==j):
                #                        forces.append(ForceCalculator.calculateGravity(planets[i].center, planets[i].mass, planets[j].center, planets[j].mass, 10))
                #
                #                summationForce = ForceCalculator.sumForces(forces)  #Currently result of all gravitational forces from other planets
                summationForce = ForceCalculator.calculateGravity(
                    planets[i].center, planets[i].mass, Vec2d(0, -1000000000),
                    600000000000000000,
                    10)  #Gravity of "Earth" acting on this "ball"
                planets[i].update_force(summationForce)

            for i in range(0, objLen):
                planets[i].update(dt)

            #goes through the array of planets to see if they are colliding and if they are then, caclulate the collision
            for i in range(0, objLen):
                for j in range(0, objLen):
                    if (not i == j):
                        ForceCalculator.calculateCollision(
                            planets[i], planets[j])
                ForceCalculator.calculateWallCollision(planets[i], wall1)
                ForceCalculator.calculateWallCollision(planets[i], wall2)

            for i in range(0, objLen):
                planets[i].update(dt)

        screen.fill(BLACK)  # wipe the screen
        for obj in planets:
            obj.draw(screen, coords)  # draw object to screen
        wall1.draw(screen, coords)
        wall2.draw(screen, coords)

        textFont = pygame.font.Font(None, 72)
        mousePosSurface = textFont.render(
            "x: " + str(mouseCoordPos.x) + " y: " + str(mouseCoordPos.y), 0,
            WHITE)
        screen.blit(mousePosSurface, (500, 500))
        # --- Update the screen with what we've drawn.
        pygame.display.update()

        # This limits the loop to 60 frames per second
        clock.tick(frame_rate)

    pygame.quit()
예제 #3
0
def main():
    pygame.init()

    width = 1200
    height = 800

    levelLoader = LevelGenerator()  #Loads planet layouts into planet array

    screen = pygame.display.set_mode([width, height])
    screen_center = Vec2d(width / 2, height / 2)
    coords = Coords(screen_center.copy(), 1, True)
    # ^ Center of window is (0,0), scale is 1:1, and +y is up

    coords.zoom_at_coords(Vec2d(0, 0), 1)
    # ^Sets camera center

    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()

    planets = []
    planets = levelLoader.loadLevel(levelLoader.getLevel())
    arrow = Arrow(10, Vec2d(-565, 0), Vec2d(-540, 0), Vec2d(0, 0))

    #textFont = pygame.font.Font(None, 144)

    #Strength of arrow shot. Will be divided by 60, adding roughly 1 to force per second
    powerMeter = 0
    arrowShootingTime = 30  #Time to apply force of shooting arrow in frames
    arrowShootingStart = False
    originalThrustVector = Vec2d(0, 0)

    frame_rate = 60
    playback_speed = 4
    dt = playback_speed / frame_rate
    done = False
    while not done:
        gameMouse = pygame.mouse
        # --- Main event loop
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  # If user clicked close
                done = True
            if event.type == pygame.MOUSEBUTTONDOWN:
                if (not arrow.getActive()):
                    #Click and hold for power. Release to shoot
                    arrow.setCharging(True)
            if event.type == pygame.MOUSEBUTTONUP:
                if (not arrow.getActive()):
                    arrow.setActive(True)
                    arrow.setCharging(False)
                    arrowShootingStart = True
                    originalThrustVector = ForceCalculator.calculateThrust(
                        arrow.center, arrow.tip, powerMeter)
                    arrow.update_force(originalThrustVector)

        if (arrow.getActive()):
            if (arrowShootingTime > 0):
                arrowShootingTime -= 1
            #calculate all forces that would apply to arrow here
            forces = []
            for planet in planets:
                forces.append(
                    ForceCalculator.calculateGravity(arrow.center, arrow.mass,
                                                     planet.center,
                                                     planet.mass, -10))
            if (arrowShootingTime > 0):
                forces.append(originalThrustVector)
            else:
                powerMeter = 0
            forceSum = ForceCalculator.sumForces(forces)
            arrow.update_force(forceSum)
            print("Arrow is active")
        else:
            #Aim input here
            mouseTup = gameMouse.get_pos()
            mouseVec = Vec2d(mouseTup[0] - 1200, mouseTup[1])
            coordMouseVec = coords.pos_to_screen(mouseVec).int()
            arrow.rotateByMouse(coordMouseVec)
            if (arrow.getCharging()):
                powerMeter += 2
            print("Arrow is deactive")

        print("Power Meter:", powerMeter)
        # Drawing
        screen.fill(BLACK)  # wipe the screen
        for obj in planets:
            obj.draw(screen, coords)  # draw object to screen
            obj.update(dt)
        arrow.update(dt)
        arrow.draw(screen, coords)

        #mouseTup = gameMouse.get_pos()
        #mouseVec = Vec2d(mouseTup[0] - 1200, mouseTup[1])
        #coordMouseVec = coords.pos_to_screen(mouseVec).int()
        #arrow.rotateByMouse(coordMouseVec)
        #mousePosSurface = textFont.render("x: " + str(coordMouseVec[0]) + " y: " + str(coordMouseVec[1]), 0, WHITE)
        #screen.blit(mousePosSurface, (500,500))
        #print("Arrow is deactive")

        # --- Update the screen with what we've drawn.
        pygame.display.update()

        # This limits the loop to 60 frames per second
        clock.tick(frame_rate)

    pygame.quit()
예제 #4
0
def main():
    global objects, screen, coords, ballIndex
    
    pygame.init()
 
    width = 1200
    height = 600
    screen = pygame.display.set_mode([width,height])
    screen_center = Vec2d(width/2, height/2)
    coords = Coords(screen_center.copy(), 1, True)
    zoom = 100
    coords.zoom_at_coords(Vec2d(0,0), zoom) 
    
    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()
    
    # Text font
    basic_font = pygame.font.Font('freesansbold.ttf', 24)
    large_font = pygame.font.Font('freesansbold.ttf', 48)
    
    # Pause Text
    intro_surf = large_font.render('READY', True, GREEN)
    intro_rect = intro_surf.get_rect()
    intro_rect.center = (width / 2, (height * 0.4))
    
    # Strokes text
    stroke_surf = basic_font.render('Stroke: 0', True, WHITE)
    stroke_rect = stroke_surf.get_rect()
    stroke_rect.center = (width / 2, (height * 0.05))
    
    # Stage 1 Strokes Text
    stage1_surf = basic_font.render('Stage 1: 0 hits', True, RED)
    stage1_rect = stage1_surf.get_rect()
    stage1_rect.center = (100, height - 20)
    
    # Stage 2 Strokes Text
    stage2_surf = basic_font.render('Stage 2: 0 hits', True, RED)
    stage2_rect = stage2_surf.get_rect()
    stage2_rect.center = (250, height - 20) 
    
    # Stage 3 Strokes Text
    stage3_surf = basic_font.render('Stage 3: 0 hits', True, RED)
    stage3_rect = stage3_surf.get_rect()
    stage3_rect.center = (400, height - 20)     

    # Create initial objects to demonstrate
    objects = []

    # Goal
    goalRadius = 0.12
    objects.append(Polygon(Vec2d(-5,2), Vec2d(0,0), 1, make_polygon(goalRadius,36,0,1), BLACK, 0, 0))
    objects[-1].type = "goal"
    
    # Golf ball
    objects.append(Polygon(Vec2d(5,2), Vec2d(0,0), 1, make_polygon(0.1,36,0,1), WHITE, 0, 0))
    ballIndex = len(objects) - 1
    
    # Surrounding walls
    objects.append(Wall(coords.pos_to_coords(Vec2d(0, screen.get_height())), Vec2d(0, 1), BLACK)) # Bottom
    objects.append(Wall(coords.pos_to_coords(Vec2d(0, 0)), Vec2d(0, -1), BLACK)) # Top
    objects.append(Wall(coords.pos_to_coords(Vec2d(0, 0)), Vec2d(1, 0), BLACK)) # Left
    objects.append(Wall(coords.pos_to_coords(Vec2d(screen.get_width(), 0)), Vec2d(-1, 0), BLACK)) # Right
    
    # Triangle walls
    triangle1 = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.25, 0)), Vec2d(0,0), 999999, make_polygon(3,3,180,0.5), BLACK, 0, 0)
    triangle2 = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.50, screen.get_height())), Vec2d(0,0), 999999, make_polygon(3,3,0,0.5), BLACK, 0, 0)
    triangle3 = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.75, 0)), Vec2d(0,0), 999999, make_polygon(3,3,180,0.5), BLACK, 0, 0)
    
    triangle1.type = "obstacle"
    triangle2.type = "obstacle"
    triangle3.type = "obstacle"
    objects.append(triangle1)
    objects.append(triangle2)
    objects.append(triangle3)
    
    # Smaller spinning obstacle
    spinningLine1 = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.5, screen.get_height() * 0.25)), Vec2d(0, 0), 5, make_rectangle(1, 0.1), DARKBLUE, 0, 1)
    spinningLine1.type = "obstacle"
    objects.append(spinningLine1)
    
    # Larger spinning obstacle
    spinningLine2 = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.75, screen.get_height() * 0.75)), Vec2d(0, 0), 50, make_rectangle(2, 0.1), DARKBLUE, 0, 5)
    spinningLine2.type = "obstacle"
    objects.append(spinningLine2)
    
    # Small obstacles
    pentaObstacle = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.2, screen.get_height() * 0.4)), Vec2d(0, 0), 1, make_polygon(0.1, 5, 0, 1), DARKBLUE, 0, 0)
    pentaObstacle.type = "obstacle"
    objects.append(pentaObstacle)
    pentaObstacle = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.15, screen.get_height() * 0.4)), Vec2d(0, 0), 1, make_polygon(0.1, 5, 0, 1), DARKBLUE, 0, 0)
    pentaObstacle.type = "obstacle"
    objects.append(pentaObstacle)
    pentaObstacle = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.1, screen.get_height() * 0.4)), Vec2d(0, 0), 1, make_polygon(0.1, 5, 0, 1), DARKBLUE, 0, 0)
    pentaObstacle.type = "obstacle"
    objects.append(pentaObstacle)
    pentaObstacle = Polygon(coords.pos_to_coords(Vec2d(screen.get_width() * 0.05, screen.get_height() * 0.4)), Vec2d(0, 0), 1, make_polygon(0.1, 5, 0, 1), DARKBLUE, 0, 0)
    pentaObstacle.type = "obstacle"
    objects.append(pentaObstacle)
    
    # -------- Main Program Loop -----------\
    frame_rate = 60
    n_per_frame = 10
    playback_speed = 1 # 1 is real time, 10 is 10x real speed, etc.
    dt = playback_speed/frame_rate/n_per_frame
    done = False
    paused = True
    draw = False
    goalScored = False
    max_collisions = 1
    result = []
    
    # Strokes
    strokeNumber = 0
    stage1Stroke = 0
    stage2Stroke = 0
    stage3Stroke = 0
    
    # Stage completion
    winStage1 = False
    winStage2 = False
    winStage3 = False
    
    while not done:
        for event in pygame.event.get(): 
            if event.type == pygame.QUIT: # If user clicked close
                done = True
                paused = True
            #elif event.type == pygame.MOUSEBUTTONDOWN:
                #paused = False
            elif event.type == pygame.KEYDOWN: 
                if event.key == pygame.K_ESCAPE:
                    done = True
                    paused = True 
                elif event.key == pygame.K_SPACE:
                    paused = not paused

            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    pos = pygame.mouse.get_pos()
                    if (objects[ballIndex].draw(screen, coords)).collidepoint(pos):
                        draw = True
            
            # Mouse Button Down Inputs
            if event.type == pygame.MOUSEBUTTONDOWN and paused:
                # Assign mouse buttons
                (pressed1, pressed2, pressed3) = pygame.mouse.get_pressed()
                
            elif event.type == pygame.MOUSEBUTTONUP and paused:
                # Assign mouse buttons
                (pressed1, pressed2, pressed3) = pygame.mouse.get_pressed()
                
                # Mouse left press to draw a particle
                if pressed1 == 0 and paused == True:                    
                    # The velocity line can be drawn
                    if draw:
                        strokeNumber += 1
                    draw = False
                    paused = False

        if not paused:
            # Stroke Text
            # If the polygon ball has stopped, allow the user to hit it again
            if(objects[ballIndex].vel.mag() <= 0.05):
                paused = True
            for N in range(n_per_frame):
                # Physics
                # Calculate the force on each object
                for obj in objects:
                    obj.force.zero()
                    obj.force += -1 * obj.vel * obj.mass
                    
                    # Slow down the ball
                    if obj.type == "polygon":
                        obj.torque = -0.75 * obj.angvel
                        pass

                # Move each object according to physics
                for obj in objects:
                    obj.update(dt)
                    
                for i in range(max_collisions):
                    collided = False
                    for i1 in range(len(objects)):
                        for i2 in range(i1):
                            if check_collision(objects[i1], objects[i2], result):
                                resolve_collision(result)
                                collided = True
                    if not collided: # if all collisions resolved, then we're done
                        break
                
                # Check distance between ball and goal
                goalDistanceVec = objects[0].pos - objects[ballIndex].pos
                goalDistance = goalDistanceVec.mag()
                if goalDistance < goalRadius * 0.95 and objects[ballIndex].vel.mag() < 3:
                    objects[ballIndex].pos = Vec2d(5,2) # set ball position to start position
                    stage1Stroke = strokeNumber
                    strokeNumber = 0
                    winStage1 = True
            
            # Drawing
            screen.fill(WHITE) # wipe the screen
            for y in range (0, 10):
                for x in range (0, 10):
                    screen.blit(GRASS, (x * 346, y * 346))
                    
            for obj in objects:
                obj.draw(screen, coords) # draw object to screen
                
            # Show stroke text
            stroke_surf = basic_font.render('Stroke: ' + str(strokeNumber), True, WHITE)
            screen.blit(stroke_surf, stroke_rect)
            
            # Show each stages' stroke text
            if(winStage1):
                stage1_surf = basic_font.render('Stage 1: ' + str(stage1Stroke), True, WHITE)
                screen.blit(stage1_surf, stage1_rect)
            if(winStage2):
                stage2_surf = basic_font.render('Stage 2: ' + str(stage2Stroke), True, WHITE)
                screen.blit(stage2_surf, stage2_rect)
            if(winStage3):
                stage3_surf = basic_font.render('Stage 3: ' + str(stage3Stroke), True, WHITE)
                screen.blit(stage3_surf, stage3_rect)
            
            # --- Update the screen with what we've drawn.
            pygame.display.update()
            
            # This limits the loop to the specified frame rate
            clock.tick(frame_rate)
        elif paused:
            for N in range(n_per_frame):
                # Physics
                # Move each object according to physics
                for obj in objects:
                    if obj != objects[ballIndex]:
                        obj.update(dt)
            # Drawing
            screen.fill(WHITE) # wipe the screen
            for y in range (0, 10):
                for x in range (0, 10):
                    screen.blit(GRASS, (x * 346, y * 346))
            
            for obj in objects:
                obj.draw(screen, coords) # draw object to screen
            if draw:
                objects[ballIndex].set_vel(make_velocity_line() / 35)
            
            # Show the pause text
            screen.blit(intro_surf, intro_rect)
            
            # Show stroke text
            stroke_surf = basic_font.render('Stroke: ' + str(strokeNumber), True, WHITE)
            screen.blit(stroke_surf, stroke_rect)
            
           # Show each stages' stroke text
            if(winStage1):
                stage1_surf = basic_font.render('Stage 1: ' + str(stage1Stroke), True, WHITE)
                screen.blit(stage1_surf, stage1_rect)
            if(winStage2):
                stage2_surf = basic_font.render('Stage 2: ' + str(stage2Stroke), True, WHITE)
                screen.blit(stage2_surf, stage2_rect)
            if(winStage3):
                stage3_surf = basic_font.render('Stage 3: ' + str(stage3Stroke), True, WHITE)
                screen.blit(stage3_surf, stage3_rect)
    
            # --- Update the screen with what we've drawn.
            pygame.display.update()
            
            # This limits the loop to the specified frame rate
            clock.tick(frame_rate)

    pygame.quit()