def easier(self): """Make a new maze that is easier than the current one.""" # both width and height must be odd newHeight = max(self.maze.height - 2, 5) newWidth = int(newHeight * self.aspectRatio) if newWidth % 2 == 0: newWidth -= 1 self.maze = Maze(self.maze.seed + 1, newWidth, newHeight) self.reset() # tell everyone which maze we are playing, so they can sync up if len(self.remoteplayers) > 0: # but fudge it a little so that we can be sure they'll use our maze self.game_start_time -= 10 mesh.broadcast("maze:%d,%d,%d,%d" % (self.game_running_time(), self.maze.seed, self.maze.width, self.maze.height))
def easier(self): """Make a new maze that is easier than the current one.""" # both width and height must be odd newHeight = max(self.maze.height - 2, 5) newWidth = int(newHeight * self.aspectRatio) if newWidth % 2 == 0: newWidth -= 1 self.maze = Maze(self.maze.seed + 1, newWidth, newHeight) self.reset() # tell everyone which maze we are playing, so they can sync up if len(self.remoteplayers) > 0: # but fudge it a little so that we can be sure they'll use our maze self.game_start_time -= 10 mesh.broadcast( "maze:%d,%d,%d,%d" % (self.game_running_time(), self.maze.seed, self.maze.width, self.maze.height) )
def requestInstrument(self, name): "instrument selections should go through this first. To request an instrument, you need to give one up" if name in self.occupiedInstruments: log.info( 'failed instrument selection, as instrument currently occupied' ) else: if self.connected and (self.sharer != self.myself): releasename = self.selectedInstrument.name iparams = getInstrumentParameters(self.scene, releasename) requestname = name mesh.send_to( self.sharer, 'JammerRequest|%s|%s|%s' % (releasename, requestname, iparams)) else: self.reselectInstruments(name) if self.connected: mesh.broadcast('Occupied|%s' % self.occupiedInstruments)
def withBuddy(buddy): if event.handle == mesh.my_handle(): log.debug("Me: %s - %s", buddy.props.nick, buddy.props.color) # README: this is a workaround to use an unique # identifier instead the nick of the buddy # http://dev.laptop.org/ticket/10750 count = "" for i, player in enumerate(self.localplayers): if i > 0: count = "-%d" % i player.uid = mesh.my_handle() + count else: log.debug("Join: %s - %s", buddy.props.nick, buddy.props.color) player = Player(buddy) player.uid = event.handle self.remoteplayers[event.handle] = player self.allplayers.append(player) self.allplayers.extend(player.bonusPlayers()) self.markPointDirty(player.position) # send a test message to the new player mesh.broadcast("Welcome %s" % player.nick) # tell them which maze we are playing, so they can sync up mesh.send_to( event.handle, "maze:%d,%d,%d,%d" % (self.game_running_time(), self.maze.seed, self.maze.width, self.maze.height), ) for player in self.localplayers: if not player.hidden: mesh.send_to( event.handle, "move:%s,%d,%d,%d,%d" % ( player.uid, player.position[0], player.position[1], player.direction[0], player.direction[1], ), )
def broadcast_msg(msg_content): print 'in game_sharing.broadcast_msg' mesh.broadcast(msg_content)
def finish(self, player): self.finish_time = time.time() player.elapsed = self.finish_time - self.level_start_time if len(self.remoteplayers) > 0: mesh.broadcast("finish:%s,%.2f" % (player.nick, player.elapsed))
def processEvent(self, event): """Process a single pygame event. This includes keystrokes as well as multiplayer events from the mesh.""" if event.type == pygame.QUIT: self.running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.running = False elif event.key in (pygame.K_PLUS, pygame.K_EQUALS): self.harder() elif event.key == pygame.K_MINUS: self.easier() elif self.arrowkeys.has_key(event.key): playernum, direction = self.arrowkeys[event.key] player = self.localplayers[playernum] player.hidden = False if direction == pygame.K_UP: player.direction = (0, -1) elif direction == pygame.K_DOWN: player.direction = (0, 1) elif direction == pygame.K_LEFT: player.direction = (-1, 0) elif direction == pygame.K_RIGHT: player.direction = (1, 0) if len(self.remoteplayers) > 0: mesh.broadcast( "move:%s,%d,%d,%d,%d" % (player.nick, player.position[0], player.position[1], player.direction[0], player.direction[1])) elif event.type == pygame.KEYUP: pass elif event.type in (pygame.MOUSEMOTION, pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP): pass elif event.type == mesh.CONNECT: print "Connected to the mesh." elif event.type == mesh.PARTICIPANT_ADD: buddy = mesh.get_buddy(event.handle) if event.handle == mesh.my_handle(): print "Me:", buddy.props.nick, buddy.props.color else: print "Join:", buddy.props.nick, buddy.props.color player = Player(buddy) self.remoteplayers[event.handle] = player self.allplayers.append(player) self.allplayers.extend(player.bonusPlayers()) self.markPointDirty(player.position) # send a test message to the new player mesh.broadcast("Welcome %s" % player.nick) # tell them which maze we are playing, so they can sync up mesh.send_to( event.handle, "maze:%d,%d,%d,%d" % (self.game_running_time(), self.maze.seed, self.maze.width, self.maze.height)) for player in self.localplayers: if not player.hidden: mesh.send_to( event.handle, "move:%s,%d,%d,%d,%d" % (player.nick, player.position[0], player.position[1], player.direction[0], player.direction[1])) elif event.type == mesh.PARTICIPANT_REMOVE: if self.remoteplayers.has_key(event.handle): player = self.remoteplayers[event.handle] print "Leave:", player.nick self.markPointDirty(player.position) self.allplayers.remove(player) for bonusplayer in player.bonusPlayers(): self.markPointDirty(bonusplayer.position) self.allplayers.remove(bonusplayer) del self.remoteplayers[event.handle] elif event.type == mesh.MESSAGE_UNI or event.type == mesh.MESSAGE_MULTI: buddy = mesh.get_buddy(event.handle) #print "Message from %s / %s: %s" % (buddy.props.nick, event.handle, event.content) if event.handle == mesh.my_handle(): # ignore messages from ourself pass elif self.remoteplayers.has_key(event.handle): player = self.remoteplayers[event.handle] try: self.handleMessage(player, event.content) except: print "Error handling message: %s\n%s" % (event, sys.exc_info()) else: print "Message from unknown buddy?" else: print "Unknown event:", event
def attemptBroadcast(msg): if EN_RED != False: mesh.broadcast(msg)
def receiveMessage(self, instruction, handle): if instruction.startswith("Welcome"): messages = instruction.split("|") self.sharer = handle jam_scene = messages[1] self.pending_instrument_assignment = [messages[2], messages[3]] self.select_activity_scene(jam_scene) if self.sharer != self.myself: olpcgames.ACTIVITY.J2JToolbar.deactivate_scene_change() elif instruction.startswith("Beat"): splitvals = instruction.split('|') receivedBeat = int(splitvals[1]) time_now = now() self.beatEstimator.addBeat(receivedBeat, time_now) if abs(receivedBeat - self.beatEstimator.beat_match(time_now)) > 0.17: pass else: latency = (sum(self.latency) / len(self.latency)) tmult = self.music_player.tempoMult latency = latency * 0.25 + 0.04 #this might be XO 1.0 specific beatadvance = int(ceil(latency * 1 / tmult)) scheduled_time = now() + ((beatadvance * tmult) - latency) self.music_player.Cease() self.music_player.playLoop(scheduled_time, (receivedBeat + beatadvance) % self.music_player.beatlimit) elif instruction.startswith("JammerRequest"): "In theory only the sharer ever gets this message" split = instruction.split('|') releasename = split[1] requestname = split[2] iparams = eval(split[3]) stealresult = self.stealInstrument(requestname, releasename, handle) if stealresult: setInstrumentParameters(self.scene, releasename, iparams) rqparams = getInstrumentParameters(self.scene, requestname) mesh.send_to( handle, "AuthorisedInstrument|%s|%s" % (requestname, rqparams)) mesh.broadcast('Occupied|%s' % self.occupiedInstruments) else: mesh.send_to(handle, "DeniedInstrument|%s") elif instruction.startswith("AuthorisedInstrument"): "In theory only a 'joiner' receives this message" msg = instruction.split('|') ai = msg[1] params = eval(msg[2]) setInstrumentParameters(self.scene, ai, params) self.reselectInstruments(ai) elif instruction.startswith("DeniedInstrument"): di = instruction.split('|')[1] log.info("Instrument request for %s was denied by sharer." % di) elif instruction.startswith("Occupied"): insdict = eval(instruction.split('|')[1]) self.occupiedInstruments = insdict for pni in self.PanelInstruments: if pni.name in insdict: pni.deactivate() else: pni.activate() elif instruction.startswith("LateReq"): id = instruction.split('|')[1] mesh.send_to(handle, "LateResp|%s" % id) elif instruction.startswith("LateResp"): id = int(instruction.split('|')[1]) try: t = self.latency_time_ID[id] del self.latency_time_ID[id] result = (now() - t) / 2 avglat = sum(self.latency) / len(self.latency) diffs = [(val - avglat)**2 for val in self.latency] stddev = sqrt(sum(diffs) / len(diffs)) if id == 0: del self.latency[0] self.latency.append(result) elif result > (avglat + stddev): pass elif result < (avglat - stddev) and len(self.latency) > 6: pass elif len(self.latency) > 12: del self.latency[0] self.latency.append(result) else: self.latency.append(result) except KeyError: log.info('Unmatched time ID %s' % id) else: log.debug("UNKNOWN INSTRUCTION RECEIVED :%s", instruction)
def eventAction(self, event): "detect events, and select action" if event.type == pygame.QUIT: self.music_player.freeze() self.running = False elif event.type == pygame.USEREVENT: if hasattr(event, "action"): if event.action.startswith("Parameter"): args = event.action.split('|') if args[1] == "Horizontal": self.Hparam = args[2] self.selectedInstrument.Touch = True elif args[1] == "Vertical": self.Vparam = args[2] self.selectedInstrument.Touch = True else: raise ValueError, 'Unknown Parameter Action %s' % args elif event.action.startswith('Reload'): #should look always like this: "Reload|name|key:mode|tempo|defaults" args = event.action.split('|') name = args[1] key = ('E' if args[2] == 'None' else args[2]) mode = ('minor' if args[3] == 'None' else args[3]) tempo = (117 if args[4] == 'None' else int(args[4])) d = eval(args[5]) defaults = (d if d else {}) self.load_scene(name, key, mode, tempo, defaults) #this call blocks if self.pending_instrument_assignment: #now check if we are waiting to assign instruments and params. self.receiveMessage( "AuthorisedInstrument|%s|%s" % (self.pending_instrument_assignment[0], self.pending_instrument_assignment[1]), self.myself) elif event.action.startswith("Shared"): self.sharer = "Pending" log.info("Sharing activity") elif event.action.startswith("Joined"): log.info("Joined Activity") else: log.debug("unknown parameter change: %s", event.action) else: log.debug("ignoring USEREVENT %s", event) elif event.type == pygame.MOUSEBUTTONDOWN: x, y = event.pos Ins = self.selectedInstrument if Ins.Rect.collidepoint(x, y): self.movingInstrument = Ins else: for Panndx in range(len(self.PanelInstruments)): Pan = self.PanelInstruments[Panndx] if Pan.Rect.collidepoint(x, y): if Pan.active: self.requestInstrument(Pan.name) break elif event.type == pygame.MOUSEMOTION: if self.movingInstrument: insname = self.movingInstrument.name self.scene.Params.setValue( self.Hparam, insname, rescale(event.pos[0], self.playArea.left, self.playArea.right, 0, 1)) self.scene.Params.setValue( self.Vparam, insname, limit( rescale(event.pos[1], self.playArea.bottom, self.playArea.top, 0, 1), 0, 1)) self.movingInstrument.Touch = True elif event.type == pygame.MOUSEBUTTONUP: self.movingInstrument = False elif platform == 'Sugar' and event.type == mesh.CONNECT: log.info("""Connected to the mesh!| %s""", event) self.connected = True self.music_player.resetBeat() elif event.type == pygame.KEYDOWN: try: iaction = self.keycode[event.key] self.keyActions.append(iaction) except KeyError: pass elif event.type == pygame.KEYUP: try: self.keyActions.remove(self.keycode[event.key]) except ValueError: pass except KeyError: pass elif self.connected and event.type == mesh.PARTICIPANT_ADD: if not self.myself: self.myself = mesh.my_handle() if event.handle == self.myself: if self.sharer == "Pending": self.sharer = self.myself elif len(self.occupiedInstruments) == 4: pass else: if self.sharer == self.myself: giveupInstrument = [ p for p in self.PanelInstruments if p.active ][0].name giveupparameters = getInstrumentParameters( self.scene, giveupInstrument) mesh.send_to( event.handle, "Welcome|%s|%s|%s" % (self.scene.scene_name, giveupInstrument, giveupparameters)) self.stealInstrument(giveupInstrument, handle=event.handle) if self.connected: mesh.broadcast('Occupied|%s' % self.occupiedInstruments) olpcgames.ACTIVITY.J2JToolbar.deactivate_scene_change() if len(self.occupiedInstruments ) >= 2 and not self._syncloop_running: self._syncloop_running = True self.sendSync() else: self.latency_checker() log.info("Waiting to be assigned instrument from sharer") elif self.connected and event.type == mesh.PARTICIPANT_REMOVE: "return instrument to the sharer if a jammer leaves." try: relname = [ n for n in self.occupiedInstruments if self.occupiedInstruments[n] == str(event.handle) ][0] relpanel = [ p for p in self.PanelInstruments if p.name == relname ][0] del self.occupiedInstruments[relname] relpanel.Touch = True if self.sharer == self.myself: self.music_player.mutelist.remove(relname) if len(self.occupiedInstruments) == 1: olpcgames.ACTIVITY.J2JToolbar.reactivate_scene_change() if len(self.occupiedInstruments) <= 1: self._syncloop_running = False except IndexError: log.debug("Index error while removing jammer %s occ = %s" % (str(event.handle), self.occupiedInstruments)) except KeyError: pass except ValueError: pass if self.sharer == self.myself: mesh.broadcast('Occupied|%s' % self.occupiedInstruments) log.info("""Removed jammer| %s""", event) elif self.connected and (event.type == mesh.MESSAGE_MULTI or event.type == mesh.MESSAGE_UNI): if event.handle == self.myself: pass else: self.receiveMessage(event.content, event.handle)
def processEvent(self, event): """Process a single pygame event. This includes keystrokes as well as multiplayer events from the mesh.""" if event.type == pygame.QUIT: self.running = False elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_PLUS, pygame.K_EQUALS): self.harder() elif event.key == pygame.K_MINUS: self.easier() elif event.key in self.arrowkeys: playernum, direction = self.arrowkeys[event.key] player = self.localplayers[playernum] player.hidden = False if direction == pygame.K_UP: player.direction = (0, -1) elif direction == pygame.K_DOWN: player.direction = (0, 1) elif direction == pygame.K_LEFT: player.direction = (-1, 0) elif direction == pygame.K_RIGHT: player.direction = (1, 0) if len(self.remoteplayers) > 0: mesh.broadcast( "move:%s,%d,%d,%d,%d" % (player.uid, player.position[0], player.position[1], player.direction[0], player.direction[1]) ) elif event.type == pygame.KEYUP: pass elif event.type == pygame.MOUSEMOTION: pass elif event.type == pygame.MOUSEBUTTONDOWN: self.mouse_in_use = 1 self.prev_mouse_pos = pygame.mouse.get_pos() elif event.type == pygame.MOUSEBUTTONUP: if self.mouse_in_use: new_mouse_pos = pygame.mouse.get_pos() mouse_movement = (new_mouse_pos[0] - self.prev_mouse_pos[0], new_mouse_pos[1] - self.prev_mouse_pos[1]) if (abs(mouse_movement[0]) > 10) or (abs(mouse_movement[1]) > 10): player = self.localplayers[0] player.hidden = False # x movement larger if abs(mouse_movement[0]) > abs(mouse_movement[1]): # direction == pygame.K_RIGHT if mouse_movement[0] > 0: player.direction = (1, 0) else: # direction == pygame.K_LEFT player.direction = (-1, 0) else: if mouse_movement[1] < 0: # direction == pygame.K_UP player.direction = (0, -1) else: # direction == pygame.K_DOWN player.direction = (0, 1) if len(self.remoteplayers) > 0: mesh.broadcast( "move:%s,%d,%d,%d,%d" % ( player.nick, player.position[0], player.position[1], player.direction[0], player.direction[1], ) ) self.mouse_in_use = 0 elif event.type == mesh.CONNECT: log.debug("Connected to the mesh") elif event.type == mesh.PARTICIPANT_ADD: log.debug("mesh.PARTICIPANT_ADD") def withBuddy(buddy): if event.handle == mesh.my_handle(): log.debug("Me: %s - %s", buddy.props.nick, buddy.props.color) # README: this is a workaround to use an unique # identifier instead the nick of the buddy # http://dev.laptop.org/ticket/10750 count = "" for i, player in enumerate(self.localplayers): if i > 0: count = "-%d" % i player.uid = mesh.my_handle() + count else: log.debug("Join: %s - %s", buddy.props.nick, buddy.props.color) player = Player(buddy) player.uid = event.handle self.remoteplayers[event.handle] = player self.allplayers.append(player) self.allplayers.extend(player.bonusPlayers()) self.markPointDirty(player.position) # send a test message to the new player mesh.broadcast("Welcome %s" % player.nick) # tell them which maze we are playing, so they can sync up mesh.send_to( event.handle, "maze:%d,%d,%d,%d" % (self.game_running_time(), self.maze.seed, self.maze.width, self.maze.height), ) for player in self.localplayers: if not player.hidden: mesh.send_to( event.handle, "move:%s,%d,%d,%d,%d" % ( player.uid, player.position[0], player.position[1], player.direction[0], player.direction[1], ), ) mesh.lookup_buddy(event.handle, callback=withBuddy) elif event.type == mesh.PARTICIPANT_REMOVE: log.debug("mesh.PARTICIPANT_REMOVE") if event.handle in self.remoteplayers: player = self.remoteplayers[event.handle] log.debug("Leave: %s", player.nick) self.markPointDirty(player.position) self.allplayers.remove(player) for bonusplayer in player.bonusPlayers(): self.markPointDirty(bonusplayer.position) self.allplayers.remove(bonusplayer) del self.remoteplayers[event.handle] elif event.type == mesh.MESSAGE_UNI or event.type == mesh.MESSAGE_MULTI: log.debug("mesh.MESSAGE_UNI or mesh.MESSAGE_MULTI") if event.handle == mesh.my_handle(): # ignore messages from ourself pass elif event.handle in self.remoteplayers: player = self.remoteplayers[event.handle] try: self.handleMessage(player, event.content) except: log.debug("Error handling message: %s\n%s", event, sys.exc_info()) else: log.debug("Message from unknown buddy?") elif event.type == pygame.USEREVENT: # process our buttons if hasattr(event, "action") and event.action == "harder_button": self.harder() elif hasattr(event, "action") and event.action == "easier_button": self.easier() # process file save / restore events elif event.code == olpcgames.FILE_READ_REQUEST: log.debug("Loading the state of the game...") state = json.loads(event.metadata["state"]) log.debug("Loaded data: %s", state) self.maze = Maze(**state) self.reset() return True elif event.code == olpcgames.FILE_WRITE_REQUEST: log.debug("Saving the state of the game...") data = {"seed": self.maze.seed, "width": self.maze.width, "height": self.maze.height} log.debug("Saving data: %s", data) event.metadata["state"] = json.dumps(data) f = open(event.filename, "w") try: f.write(str(time.time())) finally: f.close() log.debug("Done saving.") return True else: log.debug("Unknown event: %r", event)