def __init__(self,player_id,team,serverIP,serverPort): '''State: Players,Buildings, Time, Resourse Pool''' LoopingThread.__init__(self) self.players = {} self.buildings = {} self.TimeLeft = 15*60 self.width = 80.0 self.height = 48.0 self.view =None self.GameOver =False self.playerID =player_id self.player = None self.action = 0 self.attemptedAction = 0 self.lastAction = 0 self.ActionTimeout = 1 self.team =team self.otherTeam = 2 if self.team==1 else 1 self.scores =[0,0] self.IsServer = False self.ResourcePool = ResourcePool() self.client = UDPClient(self) self.serverIP =serverIP self.serverPort = serverPort self.Tick = 0 self.Position = (0,0) self.lastUpdate = 0 self.controller = None
class Environment(LoopingThread): #in an MVC system , this would be a controller ''' The environment class contains the state of the game. The server has the master version, the clients have slave versions (updated through the network) ''' ATTACK_RADIUS = 3 SCAN_RADIUS = 3 FPS=30 def __init__(self,player_id,team,serverIP,serverPort): '''State: Players,Buildings, Time, Resourse Pool''' LoopingThread.__init__(self) self.players = {} self.buildings = {} self.TimeLeft = 15*60 self.width = 80.0 self.height = 48.0 self.view =None self.GameOver =False self.playerID =player_id self.player = None self.action = 0 self.attemptedAction = 0 self.lastAction = 0 self.ActionTimeout = 1 self.team =team self.otherTeam = 2 if self.team==1 else 1 self.scores =[0,0] self.IsServer = False self.ResourcePool = ResourcePool() self.client = UDPClient(self) self.serverIP =serverIP self.serverPort = serverPort self.Tick = 0 self.Position = (0,0) self.lastUpdate = 0 self.controller = None def createPlayer(self, player_id,team): '''add a player to the given team''' player = Player() player.team = team playerId = id(player) player.player_id = player_id self.players[playerId] = player return player def createBuilding(self, team,pos): '''add a building to the given team''' building = Building() building.team = team building.position =pos bid = id(building) building.building_id = 0 self.buildings[bid] = building return building def readGestures(self): self.controller._handleInput() if(self.player<>None): #print self.player.action if(self.player.action == Player.ATTACK): #ATTACK self.handleAttack() elif(self.player.action == Player.BUILD): #building self.handleBuild() elif(self.player.action == Player.UPGRADE): #building self.handleUpgrade() elif(self.player.action == Player.SCAN): #building self.handleScan() elif(self.player.action == Player.IDLE): self.handleIdle() def handleAttack(self): if(self.player.sides>=3): self.player.performAttack(self.Tick) def handleBuild(self): ACTION = "BUILD" if((self.ResourcePool.getPosition()-self.player.getPosition()).length< self.ResourcePool.size): ACTION ="MINE" else: for b in self.buildings.itervalues(): if(b.team == self.player.team and b.isPolyFactory() and b.resources == 5 and (b.getPosition()- player.getPosition()).length <b.size): ACTION ="MINE" break if( ACTION =="MINE"): self.player.performBuild(self.Tick) else: if(self.player.resources>0): BUILDING =None for b in self.buildings.itervalues(): if (b.getPosition() - self.player.getPosition()).length < b.size: BUILDING =b break if BUILDING.team ==self.player.team: self.player.performBuild(self.Tick) def handleUpgrade(self): allowedUpgradeLoc = False if((self.ResourcePool.getPosition()-self.player.getPosition()).length< self.ResourcePool.size): allowedUpgradeLoc=True else: for b in self.buildings.itervalues(): if(b.team == self.player.team and b.isPolyFactory() and b.resources == 5 and (b.getPosition()- self.player.getPosition()).length <b.size): allowedUpgradeLoc=True break if(allowedUpgradeLoc): self.player.upgrade(self.Tick) def handleScan(self): self.player.scan(self.Tick) def handleIdle(self): pass def updateTime(self): self.Tick+= 1.0/Environment.FPS #if( self.TimeLeft<=0): # self.GameOver =True def task(self): #self.deSerialize() self.readGestures() self.updateTime() self.updatePositions() self.makeRequest() self.view.paint(self.Tick ) for event in pygame.event.get(): if event.type == pygame.QUIT: self.Exit() def Exit(self): self.shutdown() pygame.quit() def makeRequest(self): #print self.action self.client.MakeRequest(self.playerID,self.team,self.action,self.Position) self.action = 0 def updatePositions(self): for playerId in self.players: if self.players[playerId].player_id <> self.playerID: self.players[playerId].updatePosition( 1.0/Environment.FPS) def start(self): '''controls the environment by initiating the looping calls''' self.lastUpdate =time.time() self.view.start('client-'+str(self.playerID)) self.client.start(self.serverIP,int(self.serverPort),self.playerID) #if os.path.exists(CLIENTLOCALDATA.split('.')[0]+str(self.playerID)+'.'+CLIENTLOCALDATA.split('.')[1]): # os.remove(CLIENTLOCALDATA.split('.')[0]+str(self.playerID)+'.'+CLIENTLOCALDATA.split('.')[1]) self.setInterval(1.0/Environment.FPS) self.run() #self._renderCall = LoopingCall(self.Update) #self._requestCall = LoopingCall(self.makeRequest) #self._renderCall.start(1.0/Environment.FPS) #self._requestCall.start(1.0/Environment.FPS) #FUNCTIONS FOR NETWORKING def deSerialize(self,state): try: ''' assume the following message structure players$buildings$resourcepool$scores$timeleft$gameover players->player1@player2@..@playern player1->id&Team&sides&resources&partialResources&pos_x^pos_y&anim1^anim2^anim3&action ''' if(state<>None): t = state.split('$') if(len(t)>0): players = t[0].split('@') #update players players.remove('') for p in players: found =False pkey = 0 player = p.split('&') pId = int(player[0]) pTeam = int (player[1]) pSides = int(player[2]) pResources = int(player[3]) pPartialResources = int(player[4]) pPosition = Vector2D( (float(player[5].split('^')[0]),(float(player[5].split('^')[1])))) AnimationList = player[6].split('^') AnimationList.remove('') pAnimations=[] for a in AnimationList: a = a.split('#') pAnimations.append( (int(a[0]),bool(a[1]),float(a[2]))) pAction = int(player[7]) for ep in self.players.itervalues(): if ep.player_id == pId: found = True pkey = id(ep) break if found: self.players[pkey].sides = pSides self.players[pkey].resources = pResources self.players[pkey].partialResources = pPartialResources if pId == self.playerID: self.players[pkey].position = Vector2D(self.Position) self.players[pkey].action = self.action else: self.players[pkey].animations.extend(pAnimations) self.players[pkey].targetPosition = pPosition self.players[pkey].action = pAction else: newplayer = self.createPlayer(pId,pTeam) if(pId == self.playerID): self.player=newplayer newplayer.targetPosition=pPosition newplayer.sides = pSides newplayer.resources = pResources newplayer.partialResources = pPartialResources newplayer.animations.extend(pAnimations) newplayer.action = pAction ''' assume the following message structure players$buildings$resourcepool$scores$timeleft$gameover buildings->buildings@buildings@..@buildings buildings->id&Team&sides&resources&partialResources&pos_x^pos_y&anim1^anim2^anim3 ''' if(t[1]<>''): buildings = t[1].split('@') self.buildings.clear() for b in buildings: building = b.split('&') bId = int(building[0]) bTeam = int(building[1]) bSides = int(building[2]) bResources = int(building[3]) bPartialResources = int(building[4]) AnimationList = building[6].split('^') AnimationList.remove('') bAnimations=[] for a in AnimationList: a = a.split('#') bAnimations.append( (int(a[0]),bool(a[1]),float(a[2]))) bPosition = Vector2D( (float(building[5].split('^')[0]),(float(building[5].split('^')[1])))) newbuilding = self.createBuilding(bTeam,bPosition) newbuilding.building_id = bId newbuilding.sides = bSides newbuilding.resources = bResources newbuilding.animations.extend(bAnimations) if(t[2]<>''): self.scores =(int(t[2].split('^')[0]),int(t[2].split('^')[1])) if(t[3]<>''): self.TimeLeft =int(t[3]) if(t[4]<>''): self.GameOver = not bool(t[4]) except: print "Unexpected error:", sys.exc_info()[0]