Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import plus
- import Arenas
- import math
- ## CAMERA IDEAS ##
- #Follows bot that is recieving the most damage or is about to die
- #Overhead cam (like orbit but above instead of behind)
- #Follows soccer ball and stops short of goalie's net to gve a more horizontal view (but still angled)
- #Rounded Rectnagle (look below)
- #incorporate plus.getScreenSize() to make FOV more accurate
- #make efficienct cam
- class ActionCamera(object):
- """ Keeps a perpendicular angle to the fighting and avoids visual obstructions whenever possible """
- def __init__(self, name="Action Cam", fieldOfView=75, defeatedDelay=2):
- self.name = name
- self.defeatedDelay = defeatedDelay
- degrad = 0.01745
- self.prevCam = [[0,0,0], [0,0], fieldOfView*degrad]
- self.nextCam = [[0,0,0], [0,0], fieldOfView*degrad]
- self.players = None
- self.playerCount = 0
- self.expiration = {}
- def apply(self):
- self.updatePlayers()
- def updatePlayers(self):
- if self.players == None: #we had to update after the __init__ of the arena
- self.players = list(plus.getPlayers())
- self.playerCount = len(self.players)
- for p in self.players:
- if plus.isEliminated(p) or plus.isDefeated(p):
- if p in self.expiration:
- if self.expiration[p] <= plus.getTimeElapsed():
- self.players.remove(p)
- self.playerCount -= 1
- else:
- self.expiration[p] = plus.getTimeElapsed() + self.defeatedDelay
- def Tick(self):
- a = Arenas.currentArena #have to keep it local otherwise the arena doesn't close properly
- duration = a.__getattr__tickInterval__()
- self.updatePlayers()
- locs = [plus.getLocation(b) for b in self.players]
- highest = max([l[1] for l in locs])
- midpointBtwnBots = [0,0,0]
- distanceBtwnBots = 0
- outermost = None
- for i,loc1 in zip(xrange(self.playerCount), locs):
- midpointBtwnBots[0] += loc1[0]
- midpointBtwnBots[1] += loc1[1] #not really necessary but here for completeness
- midpointBtwnBots[2] += loc1[2]
- for loc2 in locs[i+1:]:
- dist = ((loc1[0]-loc2[0])**2 + (loc1[1]-loc2[1])**2 + (loc1[2]-loc2[2])**2)**0.5
- if dist > distanceBtwnBots:
- distanceBtwnBots = dist
- outermost = (loc1, loc2)
- midpointBtwnBots = map(lambda x: x/self.playerCount, midpointBtwnBots)
- distanceToCam = max(distanceBtwnBots, 10) * 0.6
- heightOfCam = max(distanceBtwnBots, 10) * 0.4
- # Use perpendicular of furthest bots to determine horizontal angle or spin around bot if there aren't any active bots
- if outermost != None: #more than one bot available
- self.nextCam[1][1] = -math.atan2(outermost[1][2]-outermost[0][2], outermost[1][0]-outermost[0][0])
- else: #only one bot available
- self.nextCam[1][1] = self.prevCam[1][1] + 0.6*math.pi*duration #less radians per tick means slower but also smoother circling
- # Avoid walls between bots and try to go shorter distance
- angle1 = -self.nextCam[1][1] - math.pi/2 #orbit angle from midpoint
- angle2 = -self.nextCam[1][1] + math.pi/2 #orbit angle from midpoint
- side1 = [midpointBtwnBots[0] + math.cos(angle1) * distanceToCam,
- highest + heightOfCam,
- midpointBtwnBots[2] + math.sin(angle1) * distanceToCam]
- side2 = [midpointBtwnBots[0] + math.cos(angle2) * distanceToCam,
- highest + heightOfCam,
- midpointBtwnBots[2] + math.sin(angle2) * distanceToCam]
- visible1 = self.playerCount
- visible2 = self.playerCount
- for loc in locs:
- if a.RayTest(tuple(side1),loc)[0]: visible1 -= 1
- if a.RayTest(tuple(side2),loc)[0]: visible2 -= 1
- if visible1 == visible2 or self.playerCount < 2:
- dist1 = ((self.prevCam[0][0]-side1[0])**2 + (self.prevCam[0][1]-side1[1])**2 + (self.prevCam[0][2]-side1[2])**2)**0.5
- dist2 = ((self.prevCam[0][0]-side2[0])**2 + (self.prevCam[0][1]-side2[1])**2 + (self.prevCam[0][2]-side2[2])**2)**0.5
- if dist1 < dist2:
- self.nextCam[0] = side1
- else:
- self.nextCam[1][1] += math.pi
- self.nextCam[0] = side2
- elif visible1 > visible2:
- self.nextCam[0] = side1
- elif visible1 < visible2:
- self.nextCam[1][1] += math.pi
- self.nextCam[0] = side2
- # No extra horizontal rotations (by keeping difference always less than math.pi even if we aren't within -math.pi to math.pi)
- diff = self.nextCam[1][1]-self.prevCam[1][1]
- if diff > math.pi:
- self.nextCam[1][1] -= math.pi*2
- elif diff < -math.pi:
- self.nextCam[1][1] += math.pi*2
- # Vertical angle of camera
- self.nextCam[1][0] = math.pi/2 - math.atan(distanceToCam/heightOfCam) #vertical
- # Move camera
- #plus.animateCamera(XYZ-StartingLocation, (V-DirectionOfView, H-DirectionOfView), Starting Zoom, XYZ-EndingLocation, (V-Swing, H-Swing), End Zoom, self.delay, self.duration)
- plus.animateCamera(tuple(self.prevCam[0]), tuple(self.prevCam[1]), self.prevCam[2],
- tuple(self.nextCam[0]), tuple(self.nextCam[1]), self.nextCam[2],
- 0, duration)
- # Prepare for next time
- if self.nextCam[1][1] > math.pi: self.nextCam[1][1] -= math.pi*2
- elif self.nextCam[1][1] <= -math.pi: self.nextCam[1][1] += math.pi*2
- self.prevCam = [self.nextCam[0][:], self.nextCam[1][:], self.nextCam[2]]
- ##################################################################################################################################
- class ActionCamDynamic(object):
- """ Keeps a perpendicular angle to the fighting and avoids visual obstructions whenever possible """
- def __init__(self, name="Action Cam 2", fieldOfView=75, defeatedDelay=2):
- self.name = name
- self.defeatedDelay = defeatedDelay
- degrad = 0.01745
- self.prevCam = [[0,0,0], [0,0], fieldOfView*degrad]
- self.nextCam = [[0,0,0], [0,0], fieldOfView*degrad]
- self.players = None
- self.playerCount = 0
- self.expiration = {}
- def apply(self):
- self.updatePlayers()
- def updatePlayers(self):
- if self.players == None: #we had to update after the __init__ of the arena
- self.players = list(plus.getPlayers())
- self.playerCount = len(self.players)
- for p in self.players:
- if plus.isEliminated(p) or plus.isDefeated(p):
- if p in self.expiration:
- if self.expiration[p] <= plus.getTimeElapsed():
- self.players.remove(p)
- self.playerCount -= 1
- else:
- self.expiration[p] = plus.getTimeElapsed() + self.defeatedDelay
- def optimalDistance(self):
- threshold = 0.1745 #10 degrees
- ready = 0
- #while ready != 1:
- # get midpoint+angle to all points and set highest absolute to angle (between pi/2 and -pi/2)
- # if (angle > FOV/2) or (angle+theshold < FOV/2):
- # moveOut = angle < FOV/2
- # ready = -1
- # A = (moveOut * math.pi) + ((not moveOut)*2*angle - angle)
- # C = ((not moveOut) * math.pi) + (moveOut*FOV - FOV/2)
- # B = math.pi/2 - A - C
- # c = distance to bot in this 2D
- # b = c/sin(C) * sin(B)
- # move back by b amount
- # else: ready += 1
- def Tick(self):
- a = Arenas.currentArena #have to keep it local otherwise the arena doesn't close properly
- duration = a.__getattr__tickInterval__()
- self.updatePlayers()
- locs = [plus.getLocation(b) for b in self.players]
- highest = max([l[1] for l in locs])
- midpointBtwnBots = [0,0,0]
- distanceBtwnBots = 0
- outermost = None
- for i,loc1 in zip(xrange(self.playerCount), locs):
- midpointBtwnBots[0] += loc1[0]
- midpointBtwnBots[1] += loc1[1] #not really necessary but here for completeness
- midpointBtwnBots[2] += loc1[2]
- for loc2 in locs[i+1:]:
- dist = ((loc1[0]-loc2[0])**2 + (loc1[1]-loc2[1])**2 + (loc1[2]-loc2[2])**2)**0.5
- if dist > distanceBtwnBots:
- distanceBtwnBots = dist
- outermost = (loc1, loc2)
- midpointBtwnBots = map(lambda x: x/self.playerCount, midpointBtwnBots)
- distanceToCam = max(distanceBtwnBots, 10) * 0.6
- heightOfCam = max(distanceBtwnBots, 10) * 0.4
- # Use perpendicular of furthest bots to determine horizontal angle or spin around bot if there aren't any active bots
- if outermost != None: #more than one bot available
- self.nextCam[1][1] = -math.atan2(outermost[1][2]-outermost[0][2], outermost[1][0]-outermost[0][0])
- else: #only one bot available
- self.nextCam[1][1] = self.prevCam[1][1] + 0.6*math.pi*duration #less radians per tick means slower but also smoother circling
- # Avoid walls between bots and try to go shorter distance
- angle1 = -self.nextCam[1][1] - math.pi/2 #orbit angle from midpoint
- angle2 = -self.nextCam[1][1] + math.pi/2 #orbit angle from midpoint
- side1 = [midpointBtwnBots[0] + math.cos(angle1) * distanceToCam,
- highest + heightOfCam,
- midpointBtwnBots[2] + math.sin(angle1) * distanceToCam]
- side2 = [midpointBtwnBots[0] + math.cos(angle2) * distanceToCam,
- highest + heightOfCam,
- midpointBtwnBots[2] + math.sin(angle2) * distanceToCam]
- visible1 = self.playerCount
- visible2 = self.playerCount
- for loc in locs:
- if a.RayTest(tuple(side1),loc)[0]: visible1 -= 1
- if a.RayTest(tuple(side2),loc)[0]: visible2 -= 1
- if visible1 == visible2 or self.playerCount < 2:
- dist1 = ((self.prevCam[0][0]-side1[0])**2 + (self.prevCam[0][1]-side1[1])**2 + (self.prevCam[0][2]-side1[2])**2)**0.5
- dist2 = ((self.prevCam[0][0]-side2[0])**2 + (self.prevCam[0][1]-side2[1])**2 + (self.prevCam[0][2]-side2[2])**2)**0.5
- if dist1 < dist2:
- self.nextCam[0] = side1
- else:
- self.nextCam[1][1] += math.pi
- self.nextCam[0] = side2
- elif visible1 > visible2:
- self.nextCam[0] = side1
- elif visible1 < visible2:
- self.nextCam[1][1] += math.pi
- self.nextCam[0] = side2
- # No extra horizontal rotations (by keeping difference always less than math.pi even if we aren't within -math.pi to math.pi)
- diff = self.nextCam[1][1]-self.prevCam[1][1]
- if diff > math.pi:
- self.nextCam[1][1] -= math.pi*2
- elif diff < -math.pi:
- self.nextCam[1][1] += math.pi*2
- # Vertical angle of camera
- self.nextCam[1][0] = math.pi/2 - math.atan(distanceToCam/heightOfCam) #vertical
- # Move camera
- #plus.animateCamera(XYZ-StartingLocation, (V-DirectionOfView, H-DirectionOfView), Starting Zoom, XYZ-EndingLocation, (V-Swing, H-Swing), End Zoom, self.delay, self.duration)
- plus.animateCamera(tuple(self.prevCam[0]), tuple(self.prevCam[1]), self.prevCam[2],
- tuple(self.nextCam[0]), tuple(self.nextCam[1]), self.nextCam[2],
- 0, duration)
- # Prepare for next time
- if self.nextCam[1][1] > math.pi: self.nextCam[1][1] -= math.pi*2
- elif self.nextCam[1][1] <= -math.pi: self.nextCam[1][1] += math.pi*2
- self.prevCam = [self.nextCam[0][:], self.nextCam[1][:], self.nextCam[2]]
- class CircularCamera(object):
- """ Rounds the corners as it circles each bot """
- def __init__(self, name="Circular Cam", fieldOfView=75, defeatedDelay=2):
- self.name = name
- self.defeatedDelay = defeatedDelay
- degrad = 0.01745
- self.prevCam = [[0,0,0], [0,0], fieldOfView*degrad]
- self.nextCam = [[0,0,0], [0,0], fieldOfView*degrad]
- self.players = None
- self.playerCount = 0
- self.expiration = {}
- def apply(self):
- self.updateArena()
- self.updatePlayers()
- self.targetOfView = None
- self.updateTarget(self.playerCount) #keeps rotating until we are certain
- def updatePlayers(self):
- if self.players == None: #we had to update after the __init__ of the arena
- self.players = list(plus.getPlayers())
- self.playerCount = len(self.players)
- for p in self.players:
- if plus.isEliminated(p) or plus.isDefeated(p):
- if p in self.expiration:
- if self.expiration[p] <= plus.getTimeElapsed():
- self.players.remove(p)
- self.playerCount -= 1
- else:
- self.expiration[p] = plus.getTimeElapsed() + self.defeatedDelay
- def updateTarget(self, times=1):
- # Get midpoint and locs
- midpointBtwnBots = [0,0,0]
- locs = []
- for b in self.players:
- loc = plus.getLocation(b)
- midpointBtwnBots[0] += loc[0]
- midpointBtwnBots[1] += loc[1]
- midpointBtwnBots[2] += loc[2]
- locs.append(loc)
- midpointBtwnBots = map(lambda x: x/self.playerCount, midpointBtwnBots)
- # Get angles
- angles = [math.atan2(loc[2]-midpointBtwnBots[2], loc[0]-midpointBtwnBots[0]) for loc in locs]
- # Sort by angles
- temp = zip(angles, locs, self.players)
- sort(temp)
- angles, locs, self.players = zip(*temp)
- if self.targetOfView == None:
- i1 = 0
- while angles[i1] < self.nextCam[1][1]:
- if i1 == self.playerCount:
- i1 = 0
- break
- i1 += 1
- self.targetOfView = self.players[i1]
- else:
- i1 = self.players.index(self.targetOfView)
- # Get index for next on rotation
- i2 = (i1+1) % self.playerCount #results in a counter clockwise rotation
- # Get switching angle
- switchingAngle = math.atan2(locs[i2][2]-locs[i1][2], locs[i2][0]-locs[i1][0])
- # Fix angular references so that we can compare angles
- if (self.nextCam[1][1] - switchingAngle) > math.pi: #since we're going counter clockwise
- switchingAngle += math.pi*2
- # Check to see if we've reached switching point
- if switchingAngle <= self.nextCam[1][1]:
- self.targetOfView = self.players[i2]
- def Tick(self):
- a = Arenas.currentArena
- duration = a.__getattr__tickInterval__()
- self.updatePlayers()
- self.nextCam[1][1] = (self.getTimeElapsed() * math.pi * 0.25)
- self.updateTarget()
- # No extra horizontal rotations (by keeping difference always less than math.pi even if we aren't within -math.pi to math.pi)
- diff = self.nextCam[1][1]-self.prevCam[1][1]
- if diff > math.pi:
- self.nextCam[1][1] -= math.pi*2
- elif diff < -math.pi:
- self.nextCam[1][1] += math.pi*2
- # Vertical angle of camera
- self.nextCam[1][0] = math.pi/4 #vertical
- # Move camera
- #plus.animateCamera(XYZ-StartingLocation, (V-DirectionOfView, H-DirectionOfView), Starting Zoom, XYZ-EndingLocation, (V-Swing, H-Swing), End Zoom, self.delay, self.duration)
- plus.animateCamera(tuple(self.prevCam[0]), tuple(self.prevCam[1]), self.prevCam[2],
- tuple(self.nextCam[0]), tuple(self.nextCam[1]), self.nextCam[2],
- 0, duration)
- # Prepare for next time
- if self.nextCam[1][1] > math.pi: self.nextCam[1][1] -= math.pi*2
- elif self.nextCam[1][1] <= -math.pi: self.nextCam[1][1] += math.pi*2
- self.prevCam = [self.nextCam[0][:], self.nextCam[1][:], self.nextCam[2]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement