Example #1
0
 def getDistToBall(self, ball):
     '''This function returns the distance from the ball to each foot and
     to the body.'''
     lFoot = line.getParams(ball.getCenterPos(), self.getCenterPos()[0])[2]
     rFoot = line.getParams(ball.getCenterPos(), self.getCenterPos()[1])[2]
     body = line.getParams(ball.getCenterPos(), self.getCenterPos()[2])[2]
     return lFoot, rFoot, body
 def getFootAngle(self, target):
     '''This function returns the angles (measured in degrees) of the feet
     with respect to the y-axis pointing down from a point.
     target is either the coordinates of the target point or the coordinates
     of the center of an object (e.g., the ball).'''
     lFootAngle = line.getParams(target, self.getCenterPos()[0])[3]
     rFootAngle = line.getParams(target, self.getCenterPos()[1])[3]
     return lFootAngle, rFootAngle
def kickBall():
    '''This function makes the player kick the ball.'''
    global lFoot, rFoot
    # direction the body is currently facing (angle measured in degrees)
    currentRot = getRotation()[0]
    # distance from each foot to ball
    lFootToBall = line.getParams(ballCenterPos, lFootCenterPos)[2]
    rFootToBall = line.getParams(ballCenterPos, rFootCenterPos)[2]
    # the foot closer to the ball will be the one that kicks the ball
    if lFootToBall < rFootToBall:
        oldFootCenterPos = lFootCenterPos
    elif lFootToBall > rFootToBall:
        oldFootCenterPos = rFootCenterPos
    else:
        # ball is equidistant from both feet --> randomly pick the kicking foot
        oldFootCenterPos = random.choice([lFootCenterPos, rFootCenterPos])
    # distance from foot to ball when the foot touches the ball
    finalDist = footOrigCenter[1] + ballCenter[1] - 3
    # point to which the foot will move
    endPoint = getEndPoint(oldFootCenterPos, finalDist)[0]
    # move foot to ball
    newFootCenterPos, rotate = move.moveToPoint(endPoint,
                                                oldFootCenterPos,
                                                endAngle=currentRot)
    if oldFootCenterPos == lFootCenterPos:
        # left foot has changed both position and rotation
        newCenterPos = newFootCenterPos, rFootCenterPos
        rotate = rotate, currentRot
    else:
        # right foot has changed both position and rotation
        newCenterPos = lFootCenterPos, newFootCenterPos
        rotate = currentRot, rotate
    # update display to show movement
    update((lFoot, rFoot, foot, foot), newCenterPos, rotate=rotate)
    pygame.time.wait(100)  # pause program for 100 ms
    ######################################################################
    # bring foot back to the position and rotation before the kick
    moved = things[-4], things[-3], foot, foot
    if oldFootCenterPos == lFootCenterPos:
        # left foot has changed position
        newCenterPos = oldFootCenterPos, rFootCenterPos
    else:
        # right foot has changed position
        newCenterPos = lFootCenterPos, oldFootCenterPos
    # update display to show movement
    update(moved, newCenterPos, rotate=(currentRot, ) * 2)
    lFoot, rFoot = things[-4], things[-3]
    ######################################################################
    # check if the foot has touched the ball
    if newFootCenterPos == endPoint:
        # current angle (measured in degrees) of the body with respect to the
        # y-axis pointing down from the ball
        bodyAngle = line.getParams(ballCenterPos, bodyCenterPos)[3]
        moveBall(bodyAngle)  # move ball
Example #4
0
def rotate(direction,
           centerPos,
           rotCenter,
           step=10,
           maxRot=None,
           screenSize=None,
           objCenter=None):
    '''This function rotates an object around a point.
    step is the step size, or the number of degrees in each movement.
    centerPos is the coordinates of the object's center point.
    rotCenter is the point around which the object moves.
    maxRot is the maximum angle (measured in degrees) to which the
    object is allowed to move.
    objCenter is the object's center point, only specified if
    screenSize is specified.'''
    r, angle, quarter = line.getParams(rotCenter, centerPos)[2:]
    if direction == 'clockwise' or direction == 'left':
        step *= -1
        if maxRot != None:
            step = setMaxRotStep(direction, maxRot, angle, step)
    elif direction == 'counterclockwise' or direction == 'right':
        if maxRot != None:
            step = setMaxRotStep(direction, maxRot, angle, step)
    newCenterPos, rotate = setNewPos(rotCenter, r, angle, step)
    if screenSize != None:
        boundaries = setBoundaries(objCenter, screenSize)
        # final step size before reaching boundary
        while reachedBoundaries2(boundaries, direction, newCenterPos, quarter):
            step = setFinalStep2(direction, step)
            newCenterPos, rotate = setNewPos(rotCenter, r, angle, step)
        if reachedBoundaries2(boundaries, direction, centerPos, quarter):
            newCenterPos, rotate = centerPos, angle
    return newCenterPos, rotate
def moveToPoint(endPoint, currentCenterPos, endAngle=0, speedBoost=1):
    '''This function moves an object to a specified end point.
    currentCenterPos refers to the current coordinates of the object's center.
    endAngle refers to the direction the front of the object will face after the
    object has reached the end point. The default has the object facing upward.
    speedBoost adjusts the step size and must not be negative.'''
    if endPoint == currentCenterPos:
        # object has reached end point --> stop moving and rotate to end angle
        stepX = 0
        stepY = 0
        rotate = endAngle   # measured in degrees
    else:
        # distance from end point and current angle (measured in degrees)
        Xdiff, Ydiff, dist, currentAngle = line.getParams(endPoint,
                                                          currentCenterPos)[:4]
        # step size
        stepX = Xdiff
        stepY = Ydiff
        stepDiag = dist   # total travel distance per step
        while stepDiag > 10.001:
            stepX /= 1.0001
            stepY /= 1.0001
            stepDiag = math.sqrt(stepX**2 + stepY**2)
        stepX *= abs(speedBoost)
        stepY *= abs(speedBoost)
        rotate = currentAngle   # angle not changed
        if abs(Xdiff) <= abs(stepX) or abs(Ydiff) <= abs(stepY):
            # final step before reaching the end point
            stepX = Xdiff
            stepY = Ydiff
            rotate = endAngle
    # new coordinates of object center
    newCenterPos = currentCenterPos[0]+stepX, currentCenterPos[1]+stepY
    return newCenterPos, rotate
def feetToFront(target):
    '''This function moves the player's feet to the front of the player's body.
    target is either the point around which the player rotates or the point
    toward which the player moves.'''
    global lFootCenterPos, rFootCenterPos
    # direction the player is currently facing (angle measured in degrees)
    currentRot = getRotation()[0]
    if target != bodyCenterPos:
        # angle (measured in degrees) of the body with respect to the y-axis
        # pointing down from the target point
        bodyAngle = line.getParams(target, bodyCenterPos)[3]
        if bodyAngle != currentRot:
            lFootCenterPos = (move.moveCircle(bodyCenterPos,
                                              lFootCenterPos,
                                              'right',
                                              step=bodyAngle - currentRot)[0])
            rFootCenterPos = (move.moveCircle(bodyCenterPos,
                                              rFootCenterPos,
                                              'right',
                                              step=bodyAngle - currentRot)[0])
    else:
        # player is already at the target point
        lFootCenterPos = (move.moveCircle(bodyCenterPos,
                                          lFootCenterPos,
                                          'right',
                                          step=rotate - currentRot)[0])
        rFootCenterPos = (move.moveCircle(bodyCenterPos,
                                          rFootCenterPos,
                                          'right',
                                          step=rotate - currentRot)[0])
Example #7
0
 def bounceOffPl(self, player, sideHit):
     '''This function sets new parameters (moving angle, speed, and
     step size) for the movement of the ball when it bounces off either
     a player's back (sideHit = 2) or a player's flank (sideHit = 3 for
     left or sideHit = 4 for right).'''
     pCenterPos = player.getCenterPos()[2]  # player's body center position
     pCorners = player.getCorners()  # player's body corners
     # player's back, left, and right sides
     pSides = ([pCorners[2],
                pCorners[3]], [pCorners[0],
                               pCorners[2]], [pCorners[1], pCorners[3]])
     # the leftmost, rightmost, top, and bottom points on the ball
     leftP = self.getExtremes()[0], self.getExtremes()[2] + self.center[1]
     rightP = self.getExtremes()[1], leftP[1]
     topP = self.getExtremes()[0] + self.center[0], self.getExtremes()[2]
     bottomP = topP[0], self.getExtremes()[3]
     # set new parameters (might not be the final values)
     bounceType = random.choice([1, 2])
     self.bounceOff(bounceType)
     speed = self.speed
     for p in (leftP, rightP, topP, bottomP):
         newp = p[0] - self.stepX, p[1] - self.stepY
         checkSide = line.checkSide(newp, pCenterPos,
                                    pSides[sideHit - 2][0],
                                    pSides[sideHit - 2][1])
         if checkSide == 1:
             # ball would be going inside the player's body
             self.bounceOff(3 - bounceType)  # set new parameters again
             self.speed = speed  # reset
             break
 def getRotation(self):
     '''This function returns the current rotation of the player, i.e., the
     direction the player is currently facing. It is an angle, measured in
     degrees, formed by two lines: (1) the line connecting the body center
     and the midpoint (the point at the middle of the line connecting the 
     two feet at their centers), and (2) the y-axis pointing down from
     the midpoint.'''
     self.currentRot = line.getParams(self.getMidpoint(),
                                      self.getCenterPos()[2])[3]
     return self.currentRot
def getEndPoint(centerPos, finalDist):
    '''This function determines the point to which an object (either the player
    or one of the feet) will move.
    centerPos is the current coordinates of the center of the object.
    finalDist is the distance from the body to the ball when the object is at
    the target end point.'''
    # angle (measured in degrees) of the moved object (player or foot) with
    # respect to the y-axis pointing down from the ball
    angle = line.getParams(ballCenterPos, centerPos)[3]
    # angle measured in radians
    angle *= math.pi / 180
    # point to which the foot will move
    endPointX = ballCenterPos[0] + finalDist * math.sin(angle)
    endPointY = ballCenterPos[1] + finalDist * math.cos(angle)
    endPoint = endPointX, endPointY
    # direction object will be facing when it has reached end point
    endAngle = line.getParams(ballCenterPos,
                              endPoint)[3]  # measured in degrees
    return endPoint, endAngle
Example #10
0
 def apprPlayers(self, players):
     '''This function checks if the ball is about to hit a player.
     players is an array listing the players in the game.'''
     approaching = False,
     if sum(self.apprPlayer) == 0:
         for player in players:
             if player.touchedBall:  # this player just kicked the ball
                 continue  # skip the rest of the loop
             # the leftmost, rightmost, top, and bottom points on the ball
             leftP = (self.getExtremes()[0],
                      self.getExtremes()[2] + self.center[1])
             rightP = self.getExtremes()[1], leftP[1]
             topP = (self.getExtremes()[0] + self.center[0],
                     self.getExtremes()[2])
             bottomP = topP[0], self.getExtremes()[3]
             approachingPlayer = [False] * 4  # front, back, left, right
             apprPts = {}
             # player's body center position and body corners
             pCenterPos = player.getCenterPos()[2]
             pCorners = player.getCorners()
             # player's front, back, left, and right sides
             pSides = ([pCorners[0],
                        pCorners[1]], [pCorners[2], pCorners[3]],
                       [pCorners[0],
                        pCorners[2]], [pCorners[1], pCorners[3]])
             for p in (leftP, rightP, topP, bottomP):
                 newp = p[0] - self.stepX, p[1] - self.stepY
                 # points at which the line connecting p and newp
                 # intersects the player's sides
                 ints = []
                 for side in pSides:
                     ints += [line.getIntersect(p, newp, side[0], side[1])]
                 # check which side of the player the ball is approaching
                 for i in range(len(ints)):
                     if line.isBetween(ints[i], p, newp) and \
                        line.isBetween(ints[i], pSides[i][0], pSides[i][1]):
                         d1 = line.getParams(ints[i], pSides[i][0])[2]
                         d2 = line.getParams(ints[i], pSides[i][1])[2]
                         if min(d1, d2) > 1:
                             approachingPlayer[i] = True
                             apprPts[p] = ints[i]
             if 1 in approachingPlayer:
                 # find the point on the ball that will hit the player first
                 count = 0
                 for p in apprPts:
                     count += 1
                     if count == 1:
                         minDist = line.getParams(p, apprPts[p])[2]
                         closestp = p
                     else:
                         dist = line.getParams(p, apprPts[p])[2]
                         if dist < minDist:
                             minDist, closestp = dist, p
                 approaching = approachingPlayer.index(
                     1) + 1, minDist, player
                 break
     return approaching
def getRotation():
    '''This function returns the current rotation of the player, i.e., the
    direction the player is currently facing, with respect to the y-axis pointing
    down from the midpoint of the line connecting the two feet at their centers.
    The function also returns that midpoint.'''
    # midpoint of the line connecting the two feet at their centers
    midPoint = ((lFootCenterPos[0] + rFootCenterPos[0]) / 2,
                (lFootCenterPos[1] + rFootCenterPos[1]) / 2)
    # direction the player is currently facing (angle measured in degrees)
    currentRot = line.getParams(midPoint, bodyCenterPos)[3]
    return currentRot, midPoint
Example #12
0
 def getRotation(self):
     '''This function returns the player's current rotation, i.e., the
     direction the player is currently facing. It is an angle (measured in
     degrees) formed by two lines: (1) the line connecting the body center
     and the midpoint between the two foot centers, and (2) the y-axis
     pointing downward from the midpoint.'''
     # coordinates of the midpoint between the two foot centers
     midpoint = ((self.getCenterPos()[0][0] + self.getCenterPos()[1][0]) /
                 2,
                 (self.getCenterPos()[0][1] + self.getCenterPos()[1][1]) /
                 2)
     # current rotation
     currentRot = line.getParams(midpoint, self.getCenterPos()[2])[3]
     return currentRot
 def getEnding(self, ballCenterPos, finalDist, angle):
     '''This function returns the point to which the body/foot will move when
     it's headed for the ball, along with the direction the body/foot will 
     face  when it reaches the endpoint (angle measured in degrees).
     ballCenterPos is the coordinates of the ball center.
     finalDist is the distance from the body to the ball when the body is at
     the target end point.
     angle is the current angle (measured in degrees) of the body/foot with
     respect to the y-axis pointing down from the ball.'''
     # point to which the body will move
     endPointX = ballCenterPos[0] + finalDist * self.getSinCos(angle)[0]
     endPointY = ballCenterPos[1] + finalDist * self.getSinCos(angle)[1]
     endPoint = endPointX, endPointY
     # final rotation, i.e., direction the body will face when it reaches
     # the endpoint (angle measured in degrees)
     endAngle = line.getParams(ballCenterPos, endPoint)[3]
     return endPoint, endAngle
Example #14
0
def toPoint(centerPos, endPoint, endAngle, speedBoost=1):
    '''This function moves an object to a specified end point.
    centerPos is the coordinates of the object's center point.
    endAngle is the direction the front of the object will face
    after the object has reached the end point. 
    speedBoost adjusts the step size and must not be negative.'''
    if endPoint == centerPos:  # object has reached end point
        stepX, stepY = 0, 0
    else:
        Xdiff, Ydiff, dist = line.getParams(centerPos, endPoint)[:3]
        stepX = setDiagStep(Xdiff, Ydiff)[0] * abs(speedBoost)
        stepY = setDiagStep(Xdiff, Ydiff)[1] * abs(speedBoost)
        speed = math.sqrt(stepX**2 + stepY**2)
        # final step size before reaching the end point
        if dist < speed:
            stepX, stepY = Xdiff, Ydiff
    newCenterPos = centerPos[0] + stepX, centerPos[1] + stepY
    rotate = endAngle  # measured in degrees
    return newCenterPos, rotate
Example #15
0
 def getEnding(self, bodyPart, ball, finalDist):
     '''This function returns the point to which the body/foot will move
     when it's headed for the ball, along with the direction the body/foot
     will face when it reaches the endpoint (angle measured in degrees).
     finalDist is the distance between the center of the body/foot and
     the ball center when the body/foot is at the target point.'''
     if 'Foot' in bodyPart:
         if bodyPart == 'lFoot':
             angle = self.getFootAngle(ball)[0]
         else:
             angle = self.getFootAngle(ball)[1]
     else:
         angle = self.getBodyAngle(ball)
     # point to which the body will move
     endPointX = ball.getCenterPos()[0] + finalDist * np.getTrig(angle)[0]
     endPointY = ball.getCenterPos()[1] + finalDist * np.getTrig(angle)[1]
     endPoint = endPointX, endPointY
     # final rotation, i.e., direction the body will face when it reaches
     # the endpoint (measured in degrees)
     endAngle = line.getParams(ball.getCenterPos(), endPoint)[3]
     return endPoint, endAngle
 def hitPlayer(self, playerRot, feetMidpoint, minDist):
     '''This function handles ball movements when it runs into the player.
     The ball will stop moving if it hits the player from the front, but will
     bounce back if it hits the player from the back.
     playerRot is the current rotation of the player (angle measured 
     in degrees).
     feetMidpoint is the midpoint of the line connecting the player's feet
     at their centers.
     minDist is the nearest distance to the player that the ball can get.'''
     # distance from ball to the midpoint, and angle (measured in degrees) of
     # the ball with respect to the y-axis pointing down from the midpoint
     dist, angle = line.getParams(feetMidpoint, self.getCenterPos())[2:4]
     # difference between the current rotation of the player and the angle
     # just computed
     angleDiff = abs(playerRot - angle)
     if dist <= minDist:
         if angleDiff >= 100 and angleDiff <= 260:
             # ball reaches the front of the player's body --> stop moving
             self.stepX = 0
             self.stepY = 0
         else:
             # ball reaches the back of the player's body --> bounce back
             self.bounceBack(random.choice(['x', 'y']))
 def getDistanceToBall(self, ballCenterPos):
     '''This function returns the distance between each foot and the ball.'''
     lFootToBall = line.getParams(ballCenterPos, self.getCenterPos()[0])[2]
     rFootToBall = line.getParams(ballCenterPos, self.getCenterPos()[1])[2]
     return lFootToBall, rFootToBall
def movePlayer(moveType, direction=False, step=10):
    '''This function moves the player's body and feet at the same time.
    moveType is the type of movement (circle, straight, or to point).
    For circle movements, step is the change in the angle (measured in degrees) by which the object
    will move at each keypress.
    For straight movements, step is the number of pixels by which the object will
    move either horizontally or vertically at each keypress.'''
    global bodyCenterPos, lFootCenterPos, rFootCenterPos, rotate, playerMoved
    oldCenterPos = bodyCenterPos  # body position before moving
    if moveType == 'circle':
        # current angle (measured in degrees) of the body with respect to the
        # y-axis pointing down from the ball
        bodyAngle = line.getParams(ballCenterPos, oldCenterPos)[3]
        # rotate body and feet around ball
        bodyCenterPos, rotate = move.moveCircle(ballCenterPos,
                                                oldCenterPos,
                                                direction,
                                                step=step,
                                                boundaryX=[0, screenWidth],
                                                boundaryY=[0, screenHeight],
                                                objCenter=bodyCenter)
        if rotate != bodyAngle:
            # body still moving, so feet still move too
            # set step size; make sure it's between 0 and 180 degrees
            if rotate - bodyAngle > 180:
                step = abs(rotate - bodyAngle - 360)
            elif rotate - bodyAngle < -180:
                step = abs(rotate - bodyAngle + 360)
            else:
                step = abs(rotate - bodyAngle)
            # move feet
            lFootCenterPos = move.moveCircle(ballCenterPos,
                                             lFootCenterPos,
                                             direction,
                                             step=step)[0]
            rFootCenterPos = move.moveCircle(ballCenterPos,
                                             rFootCenterPos,
                                             direction,
                                             step=step)[0]
        feetToFront(ballCenterPos)  # move feet to front of body
    elif moveType == 'straight':
        # move body
        bodyCenterPos, rotate = move.moveStraight(
            bodyCenter,
            oldCenterPos,
            direction,
            stepX=step,
            stepY=step,
            boundaryX=[feetOut, screenWidth - feetOut],
            boundaryY=[feetOut, screenHeight - feetOut])
        # distance moved
        moveX, moveY = line.getParams(bodyCenterPos, oldCenterPos)[:2]
        # move feet at the same distance as body
        lFootCenterPos = lFootCenterPos[0] + moveX, lFootCenterPos[1] + moveY
        rFootCenterPos = rFootCenterPos[0] + moveX, rFootCenterPos[1] + moveY
        # direction the player is currently facing (angle measured in degrees)
        currentRot = getRotation()[0]
        if currentRot != rotate:
            # player is facing the wrong direction --> move feet around body
            feetToFront(bodyCenterPos)
    elif 'to ' in moveType:
        # distance from body to ball when player is at target end point
        finalDist = bodyOrigCenter[1] + feetOut + ballCenter[1]
        # point to which body will move
        endPoint, endAngle = getEndPoint(bodyCenterPos, finalDist)
        feetToFront(endPoint)  # move feet to front of body
        # distance left to go
        dist = line.getParams(endPoint, oldCenterPos)[2]
        # move body to end point
        bodyCenterPos, rotate = move.moveToPoint(endPoint,
                                                 bodyCenterPos,
                                                 endAngle=endAngle,
                                                 speedBoost=2)
        # distance moved
        moveX, moveY, moveDist = line.getParams(bodyCenterPos,
                                                oldCenterPos)[:3]
        # move feet at the same distance as body
        lFootCenterPos = lFootCenterPos[0] + moveX, lFootCenterPos[1] + moveY
        rFootCenterPos = rFootCenterPos[0] + moveX, rFootCenterPos[1] + moveY
        if dist != 0 and moveDist == dist:
            # final step has been made --> move feet to front of body
            feetToFront(endPoint)
    if bodyCenterPos != oldCenterPos:
        playerMoved = True
 def getDistanceMoved(self, newCenterPos):
     '''This function returns the change in the position of the body
     after a movement.
     newCenterPos is the new coordinates of the center of the body.'''
     moveX, moveY = line.getParams(newCenterPos, self.getCenterPos()[2])[:2]
     return moveX, moveY
def moveBall(bodyAngle):
    '''This function handles ball movements when the ball is kicked.
    bodyAngle is the angle (measured in degrees) of the body with respect to the
    y-axis pointing down from the ball.'''
    global ballCenterPos
    scored = False
    # angle (measured in radians) at which ball will move, with respect to
    # the negative y-axis pointing up from the ball at the current position
    ballAngle = random.uniform(bodyAngle - 1, bodyAngle + 1) * math.pi / 180
    # initial step size
    stepDiag = random.uniform(28, 32)
    stepX = stepDiag * math.sin(ballAngle)
    stepY = stepDiag * math.cos(ballAngle)
    while round(stepDiag) > 0:
        speed = stepX, stepY
        # the leftmost, rightmost, top, and bottom points on the ball
        ballLeft, ballRight, ballTop, ballBottom = getBallExtremes()
        # size of the final step before the ball reaches screen boundaries
        # or before it reaches the goal posts
        if stepX > ballLeft:
            # ball reaching left side of the screen
            stepX, stepY = setFinalStep('x', ballLeft, ballAngle)
        if stepX < ballRight - screenWidth:
            # ball reaching right side of the screen
            stepX, stepY = setFinalStep('x', ballRight - screenWidth,
                                        ballAngle)
        if stepY > ballTop:
            # ball reaching top side of the screen
            stepX, stepY = setFinalStep('y', ballTop, ballAngle)
        if stepY < ballBottom - screenHeight:
            # ball reaching bottom side of the screen
            stepX, stepY = setFinalStep('y', ballBottom - screenHeight,
                                        ballAngle)
        goalPosts = goalLeftPos[0], goalRightPos[0] + goalLeftWidth
        if ballTop < goalHeight:
            if ballRight < goalPosts[0] and stepX < ballRight - goalPosts[0]:
                # ball reaching the outside of the left post
                stepX, stepY = setFinalStep('x', ballRight - goalPosts[0],
                                            ballAngle)
            if ballLeft > goalPosts[1] and stepX > ballLeft - goalPosts[1]:
                # ball reaching the outside of the right post
                stepX, stepY = setFinalStep('x', ballLeft - goalPosts[1],
                                            ballAngle)
            if ballLeft > goalPosts[0]+postWidth and \
               stepX > ballLeft-(goalPosts[0]+postWidth):
                # ball reaching the inside of the left post
                stepX, stepY = setFinalStep(
                    'x', ballLeft - (goalPosts[0] + postWidth), ballAngle)
            if ballRight < goalPosts[1]-postWidth and \
               stepX < ballRight-(goalPosts[1]-postWidth):
                stepX, stepY = setFinalStep(
                    'x', ballRight - (goalPosts[1] - postWidth), ballAngle)
        # move ball and update display to show movement
        ballCenterPos = ballCenterPos[0] - stepX, ballCenterPos[1] - stepY
        update((ball, ballOrig), (ballCenterPos, ))
        ######################################################################
        # new leftmost, rightmost, top, and bottom points on the ball
        ballLeft, ballRight, ballTop, ballBottom = getBallExtremes()
        # After reaching the screen boundaries, the ball will bounce back
        # and continue moving at a reduced speed.
        if ballLeft == 0 or ballRight == screenWidth or \
           ballTop == 0 or ballBottom == screenHeight:
            if ballLeft == 0 or ballRight == screenWidth:
                stepX, stepY, ballAngle = bounceBack(speed, ballAngle, 'x')
            else:
                stepX, stepY, ballAngle = bounceBack(speed, ballAngle, 'y')
        # Ball will stop moving if it comes back to the front of the player, but
        # will bounce back if it hits the back of the player.
        # direction the player is currently facing (angle measured in degrees),
        # and midpoint of the line connecting the two feet at their centers
        currentRot, midPoint = getRotation()
        # distance from ball to the midpoint, and angle (measured in degrees) of
        # the ball with respect to the y-axis pointing down from the midpoint
        ballToMP_dist, ballToMP_angle = \
                       line.getParams(midPoint, ballCenterPos)[2:4]
        angleDiff = abs(ballToMP_angle - currentRot)  # angle difference
        if ballToMP_dist <= ballCenter[1] + bodyOrigCenter[1] + feetOut - 5:
            if angleDiff >= 100 and angleDiff <= 260:
                # ball stops moving
                stepX = 0
                stepY = 0
                break
            else:
                # ball bouncing back
                stepX, stepY, ballAngle = bounceBack(speed, ballAngle,
                                                     random.choice(['x', 'y']))
        # Ball will also bounce back if it hits the goal posts.
        # conditions for hitting the outside of the posts
        hitLPFromOut = ballTop < goalHeight and \
                       ballLeft < goalPosts[0] and \
                       ballRight >= goalPosts[0] and \
                       ballAngle < 0 and ballAngle > -math.pi
        hitRPFromOut = ballTop < goalHeight and \
                       ballRight > goalPosts[1] and \
                       ballLeft <= goalPosts[1] and \
                       ballAngle > 0 and ballAngle < math.pi
        # conditions for hitting the inside of the posts
        hitLPFromIn = ballTop < goalHeight and \
                      ballRight > goalPosts[0]+postWidth and \
                      ballLeft <= goalPosts[0]+postWidth and \
                      ballAngle > 0 and ballAngle < math.pi
        hitRPFromIn = ballTop < goalHeight and \
                      ballLeft < goalPosts[1]-postWidth and \
                      ballRight >= goalPosts[1]-postWidth and \
                      ballAngle < 0 and ballAngle > -math.pi
        if hitLPFromOut or hitRPFromOut:
            if ballCenterPos[1] > goalHeight and abs(ballAngle) < math.pi / 2:
                # ball bouncing back in the y direction
                stepX, stepY, ballAngle = bounceBack(speed, ballAngle, 'y')
            else:
                # ball bouncing back in the x direction
                stepX, stepY, ballAngle = bounceBack(speed, ballAngle, 'x')
        if hitLPFromIn or hitRPFromIn:
            # ball bouncing back in the x direction
            stepX, stepY, ballAngle = bounceBack(speed, ballAngle, 'x')
        # Player scores if the ball is between the goal posts.
        if ballBottom <= goalHeight and ballLeft >= goalPosts[0] and \
           ballRight <= goalPosts[1]:
            scored = True
    ######################################################################
    # decrement step size
        factor = random.uniform(1.03, 1.05)
        stepX /= factor
        stepY /= factor
        stepDiag = math.sqrt(stepX**2 + stepY**2)
    # If the player scores, the ball will be placed at a random position
    # after it has stopped moving.
    if scored == True:
        ballPosX = random.uniform(0, screenWidth - ballWidth)
        ballPosY = random.uniform(screenHeight / 2, screenHeight - ballWidth)
        # move ball and update display to show movement
        ballCenterPos = ballPosX + ballCenter[0], ballPosY + ballCenter[1]
        update((ball, ballOrig), (ballCenterPos, ), update=False)
def moveCircle(rotCenter, currentCenterPos, direction, step=10,
               maxRotation=None, boundaryX=None, boundaryY=None, objCenter=None):
    '''This function rotates an object around a point or around another object.
    rotCenter is the point or the center of the object around which the moving
    object rotates.
    currentCenterPos refers to the current coordinates of the object's center.
    step is the change in the angle (measured in degrees) by which the object
    will move at each keypress. A positive value must be given.
    maxRotation is the maximum angle (measured in degrees) to which the object
    is allowed to move. If specified, the angle must be between 0 & 180 degrees.
    boundaryX and boundaryY are lists representing the vertical and lateral
    ranges, respectively, of the area in which the object is allowed to move.
    objCenter is the object's center point.'''
    # radius, current angle (measured in degrees), and current quarter
    r, currentAngle, quarter = line.getParams(rotCenter, currentCenterPos)[2:]
    # set screen boundaries
    if boundaryX != None and objCenter != None:
        boundaryX[0] += objCenter[0]   # smallest possible x (left boundary)
        boundaryX[1] -= objCenter[0]   # largest possible x (right boundary)
    if boundaryY != None and objCenter != None:
        boundaryY[0] += objCenter[1]   # smallest possible y (upper boundary)
        boundaryY[1] -= objCenter[1]   # largest possible y (lower boundary)
    # stop moving if object has reached one of the screen boundaries
    if reachedBound2(boundaryX,boundaryY, currentCenterPos, direction, quarter):
        step = 0
    # check direction
    elif direction == 'counterclockwise' or direction == 'right':
        # check maximum rotation
        if maxRotation != None:
            if currentAngle >= maxRotation:
                # object has reached maximum rotation --> stop moving
                step = 0
            if step >= maxRotation - currentAngle:
                # final step before reaching maximum rotation
                step = maxRotation - currentAngle
    else:
        step *= -1   # negative step size
        # check maximum rotation
        if maxRotation != None:
            maxRotation *= -1   # negative rotation
            if currentAngle <= maxRotation:
                # object has reached maximum rotation --> stop moving
                step = 0
            if step <= maxRotation - currentAngle:
                # final step before reaching maximum rotation
                step = maxRotation - currentAngle
    rotate = currentAngle + step   # new angle (measured in degrees)
    # make sure the angle is between -180 and 180 degrees
    if rotate > 180:
        rotate -= 360
    elif rotate < -180:
        rotate += 360
    # new coordinates of object center
    newX = rotCenter[0] + r * math.sin(rotate*math.pi/180)
    newY = rotCenter[1] + r * math.cos(rotate*math.pi/180)
    # check if the new point is outside the boundaries, in which case the step 
    # size needs to be decreased until the new point is inside the boundaries
    if step != 0:
        while reachedBound2(boundaryX,boundaryY,(newX,newY),direction,quarter):
            if direction == 'counterclockwise' or direction == 'right':
                step -= .01
            else:
                step += .01
            rotate = currentAngle + step   # new angle (measured in degrees)
            # make sure the angle is between -180 and 180 degrees
            if rotate > 180:
                rotate -= 360
            elif rotate < -180:
                rotate += 360
            # new coordinates of object center
            newX = rotCenter[0] + r * math.sin(rotate*math.pi/180)
            newY = rotCenter[1] + r * math.cos(rotate*math.pi/180)
    newCenterPos = newX, newY
    return newCenterPos, rotate
Example #22
0
 def getBodyAngle(self, ball):
     '''This function returns the angle (measured in degrees) of the body
     with respect to the y-axis pointing downward from the ball.'''
     return line.getParams(ball.getCenterPos(), self.getCenterPos()[2])[3]
Example #23
0
 def getDistMoved(self, newCenterPos):
     '''This function returns the change in the position of
     the body after a movement.
     newCenterPos is the new coordinates of the body center.'''
     return line.getParams(self.getCenterPos()[2], newCenterPos)[:2]
Example #24
0
 def getFootAngle(self, ball):
     '''This function returns the angles (measured in degrees) of the feet
     with respect to the y-axis pointing downward from the ball.'''
     left = line.getParams(ball.getCenterPos(), self.getCenterPos()[0])[3]
     right = line.getParams(ball.getCenterPos(), self.getCenterPos()[1])[3]
     return left, right