class HostMenu(DirectObject): def __init__(self): self.defaultBtnMap = base.loader.loadModel("gui/button_map") self.buttonGeom = ( self.defaultBtnMap.find("**/button_ready"), self.defaultBtnMap.find("**/button_click"), self.defaultBtnMap.find("**/button_rollover"), self.defaultBtnMap.find("**/button_disabled")) defaultFont = loader.loadFont('gui/eufm10.ttf') self.logFrame = DirectScrolledFrame( canvasSize = (0, base.a2dRight * 2, -5, 0), frameSize = (0, base.a2dRight * 2, (base.a2dBottom+.2) * 2, 0), frameColor = (0.1, 0.1, 0.1, 1)) self.logFrame.reparentTo(base.a2dTopLeft) # create the info and server debug output self.textscale = 0.1 self.txtinfo = OnscreenText( scale = self.textscale, pos = (0.1, -0.1), text = "", align = TextNode.ALeft, fg = (0.1,1.0,0.15,1), bg = (0, 0, 0, 0), shadow = (0, 0, 0, 1), shadowOffset = (-0.02, -0.02)) self.txtinfo.setTransparency(1) self.txtinfo.reparentTo(self.logFrame.getCanvas()) # create a close Server button self.btnBackPos = Vec3(0.4, 0, 0.2) self.btnBackScale = 0.25 self.btnBack = DirectButton( # Scale and position scale = self.btnBackScale, pos = self.btnBackPos, # Text text = "Quit Server", text_scale = 0.45, text_pos = (0, -0.1), text_fg = (0.82,0.85,0.87,1), text_shadow = (0, 0, 0, 1), text_shadowOffset = (-0.02, -0.02), text_font = defaultFont, # Frame geom = self.buttonGeom, frameColor = (0, 0, 0, 0), relief = 0, pressEffect = False, # Functionality command = self.back, rolloverSound = None, clickSound = None) self.btnBack.setTransparency(1) self.btnBack.reparentTo(base.a2dBottomLeft) # catch window resizes and recalculate the aspectration self.accept("window-event", self.recalcAspectRatio) self.accept("addLog", self.addLog) def show(self): self.logFrame.show() self.btnBack.show() def hide(self): self.logFrame.hide() self.btnBack.hide() def back(self): self.hide() base.messenger.send("stop_server") self.addLog("Quit Server!") def addLog(self, text): self.txtinfo.appendText(text + "\n") textbounds = self.txtinfo.getTightBounds() self.logFrame["canvasSize"] = (0, textbounds[1].getX(), textbounds[0].getZ(), 0) def recalcAspectRatio(self, window): """get the new aspect ratio to resize the mainframe""" # set the mainframe size to the window borders again self.logFrame["frameSize"] = ( 0, base.a2dRight * 2, (base.a2dBottom+.2) * 2, 0)
class Server(DirectObject): def __init__(self): DirectObject.__init__(self) self.accept("escape", self.quit) self.lastConnection = None self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager,0) self.tcpSocket = self.cManager.openTCPServerRendezvous(SERVER_PORT, 1) self.cListener.addConnection(self.tcpSocket) taskMgr.add(self.listenTask, "serverListenTask", -40) taskMgr.add(self.readTask, "serverReadTask", -39) self.gameLogic = GameLogic() self.gameLogic.delegate = self; blackmaker = CardMaker("blackmaker") blackmaker.setColor(0,0,0,1) blackmaker.setFrame(-1.0, 1.0, -1.0, 1.0) instcard = NodePath(blackmaker.generate()) instcard.reparentTo(render2d) self.screenText = OnscreenText(text="Server started ...\n", style=1, fg=(1,1,1,1), pos=(-1.31, 0.925), scale = .06) self.screenText.setAlign(0) ###################################################################################### def listenTask(self, task): if self.cListener.newConnectionAvailable(): rendezvous = PointerToConnection() netAddress = NetAddress() newConnection = PointerToConnection() if self.cListener.getNewConnection(rendezvous, netAddress, newConnection): newConnection = newConnection.p() self.cReader.addConnection(newConnection) CLIENTS[newConnection] = netAddress.getIpString() self.lastConnection = newConnection self.screenText.appendText("New connection established.\n") else: self.screenText.appendText("getNewConnection returned false\n") return Task.cont ###################################################################################### def readTask(self, task): while 1: (datagram, data, msgID) = self.nonBlockingRead(self.cReader) if msgID is MSG_NONE: break else: self.handleDatagram(data, msgID, datagram.getConnection()) return Task.cont ###################################################################################### def nonBlockingRead(self, qcr): if self.cReader.dataAvailable(): datagram = NetDatagram() if self.cReader.getData(datagram): data = PyDatagramIterator(datagram) msgID = data.getUint16() else: data = None msgID = MSG_NONE else: datagram = None data = None msgID = MSG_NONE return (datagram, data, msgID) ###################################################################################### def handleDatagram(self, data, msgID, client): if msgID in Handlers.keys(): Handlers[msgID](msgID, data, client) else: self.screenText.appendText("Unknown msgID: ") self.screenText.appendText(msgID) self.screenText.appendText("\n") self.screenText.appendText(data) self.screenText.appendText("\n") return ###################################################################################### def msgAuth(self, msgID, data, client): name = data.getString() CLIENTS[client] = name self.gameLogic.addPlayer(name) pkg = PyDatagram() pkg.addUint16(SV_MSG_AUTH_RESPONSE) self.cWriter.send(pkg, client) self.screenText.appendText("Registered new client: ") self.screenText.appendText(name) self.screenText.appendText(" (") self.screenText.appendText(client.getAddress().getIpString()) self.screenText.appendText(")\n") ###################################################################################### def msgChat(self, msgID, data, senderClient): message = data.getString() self.screenText.appendText("Message: ") self.screenText.appendText(message) self.screenText.appendText("\n") pkg = PyDatagram() pkg.addUint16(SV_MSG_CHAT) pkg.addString(message) for receiverClient in CLIENTS: self.cWriter.send(pkg, receiverClient) ###################################################################################### def msgDisconnectReq(self, msgID, data, client): pkg = PyDatagram() pkg.addUint16(SV_MSG_DISCONNECT_ACK) self.cWriter.send(pkg, client) del CLIENTS[client] self.cReader.removeConnection(client) ###################################################################################### def handleCompleteSetup(self, msgID, data, senderClient): self.screenText.appendText("A new game will start... ") self.screenText.appendText(str(len(CLIENTS))) self.screenText.appendText(" pushies will fight to death.") setups = self.gameLogic.start() numberOfPlayers = len(setups) pkg = PyDatagram() pkg.addUint16(SV_MSG_START_GAME) pkg.addUint16(numberOfPlayers) for setup in setups: pkg.addString(setup["player"]) pkg.addFloat32(setup["position"][0]) pkg.addFloat32(setup["position"][1]) pkg.addFloat32(setup["position"][2]) for receiverClient in CLIENTS: self.cWriter.send(pkg, receiverClient) ###################################################################################### def handleMovementCommand(self, msgID, data, client): player = CLIENTS[client] movement = data.getUint8() status = data.getUint8() self.gameLogic.setPlayerMovement(player, movement, status) def handleJumpCommand(self, msgID, data, client): player = CLIENTS[client] status = data.getUint8() self.gameLogic.setPlayerJump(player, status) def handleChargeCommand(self, msgID, data, client): player = CLIENTS[client] status = data.getUint8() self.gameLogic.setPlayerCharge(player, status) ###################################################################################### def sendPositionUpdates(self, updates): pkg = PyDatagram() pkg.addUint16(SV_MSG_UPDATE_POSITIONS) pkg.addUint16(len(updates)) for update in updates: pkg.addString(update[0]) pkg.addFloat32(update[1][0]) pkg.addFloat32(update[1][1]) pkg.addFloat32(update[1][2]) pkg.addFloat32(update[2][0]) pkg.addFloat32(update[2][1]) pkg.addFloat32(update[2][2]) for client in CLIENTS: self.cWriter.send(pkg, client) def sendStatusUpdates(self, updates): pkg = PyDatagram() pkg.addUint16(SV_MSG_UPDATE_STATES) pkg.addUint16(len(updates)) for update in updates: pkg.addString(update["player"]) pkg.addUint8(update["status"]) pkg.addFloat32(update["health"]) pkg.addUint8(update["charge"]) pkg.addUint8(update["jump"]) for client in CLIENTS: self.cWriter.send(pkg, client) def quit(self): self.cManager.closeConnection(self.tcpSocket) sys.exit()
class HLevel(): def __init__(self, showbase, physicsDebug=True): """ :type self.Base: direct.showbase.ShowBase.ShowBase :type showbase: direct.showbase.ShowBase.ShowBase :type physicsDebug: bool """ print "Creating level" self.Base = showbase self.debugDrawing = physicsDebug self.pause = False self.bulletSubstep = 0.008 self.activeLog = False def loadAssets(self): print "Loading Assets" def renderAssets(self): print "Rendering assets" def setCamera(self): print "Setting camera" def setLights(self): print "Setting lights" def destroy(self): print "Destroying level" def loadEgg(self, egg): """ :type egg: str :rtype : panda3d.core.NodePath """ return self.Base.loader.loadModel(egg) def renderModel(self, model): """ :type model: str """ model.reparentTo(self.Base.render) def renderEgg(self, egg): """ :type egg: str :return pada3d.core.NodePath """ m = self.loadEgg(egg) self.renderModel(m) return m def setPhysics(self): print "Setting physics" self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -10)) self.Base.taskMgr.add(self.physicsUpdate, "physicsUpdate", priority=0) if self.debugDrawing: print "Debug drawing" self.debug = BulletDebugNode("debug") self.debug.showWireframe(True) self.debug.showBoundingBoxes(False) self.debug.showNormals(True) self.debugNP = self.Base.render.attachNewNode(self.debug) self.debugNP.show() self.world.setDebugNode(self.debug) def physicsUpdate(self, task): if not self.pause: dt = globalClock.getDt() self.world.doPhysics(dt, 2, self.bulletSubstep) # #0.009-0.008 # print "Physics step" return task.cont def cameraShake(self, amplitud=0.01, frecuencia=5): """ :type amplitud: float :type frecuencia: float """ self.Base.camera.setZ( self.Base.camera, sin(globalClock.getRealTime() * frecuencia) * amplitud) def eggToStatic(self, egg, parent, margin=0.01, name="static"): """ :type egg: str :type parent: panda3d.core.NodePath :type margin: float :type name: str :return: tuple(pada3d.bullet.BulletRigidBodyNode,panda3d.core.NodePath) """ m = self.Base.loader.loadModel(egg) sTuple = modelToShape(m) sTuple[0].setMargin(margin) static = BulletRigidBodyNode(name) # H static.addShape(sTuple[0], sTuple[1]) np = parent.attachNewNode(egg) self.world.attachRigidBody(static) return static, np def togglePause(self): """ """ if self.pause: self.pause = False else: self.pause = True print "Toggle pause", self.pause def activateLog(self): self.activeLog = True self.logText = OnscreenText("NO LOG", scale=0.07, fg=(1, 0, 0, 0.8), bg=(0, 0, 1, 0.2), frame=(0, 1, 0, 0.2), pos=(-1.05, .9), mayChange=True, align=0) self.__logTextLenght = 0 self.__logAbsoluteLenght = 0 self.__logText = "" self.logText.reparentTo(self.Base.aspect2d) def log(self, *args): if self.activeLog is False: return None s = str(self.__logAbsoluteLenght) + ":" for a in args: s += str(a) + " " if self.__logTextLenght < 10: self.logText.appendText("\n" + s) else: self.__logTextLenght = 0 self.logText.clearText() self.logText.setText(s) self.__logTextLenght += 1 self.__logAbsoluteLenght += 1 self.__logText.join(s) def loadFont(self, string): return self.Base.loader.loadFont(string) def drawLine(self, fromP, toP, thickness=2, color=(1, 0, 0, 1), autoClear=True): if autoClear: try: self.debugLineNP.removeNode() except: pass self.debugLine = LineSegs("DebugLine") self.debugLine.reset() self.debugLine.setThickness(thickness) self.debugLine.setColor(color) self.debugLine.moveTo(fromP) self.debugLine.drawTo(toP) self.debugLineNode = self.debugLine.create() self.debugLineNP = NodePath(self.debugLineNode) self.debugLineNP.reparentTo(self.Base.render) return self.debugLineNP
class WorldBase(DirectObject): """ Basic 3D world with logging and 2D display """ def __init__(self, controller, mem_logger, display_categories): self.display_categories = display_categories self.labels = OnscreenText( "", style = 1, fg = ( 1, 1, 1, 1 ), pos = ( -1.0, 0.9 ), scale = .05 ) self.txt = OnscreenText( "", style = 1, fg = ( 1, 1, 1, 1 ), pos = ( -0.5, 0.9 ), scale = .05 ) taskMgr.add( self.loop, "loop" ) self.enable_screen_updates = True self.log = KeplerLogger(mem_logger) self.logging = False self.accept("p", self.key_p) self.accept( "escape", self.quit ) self.accept("arrow_up", self.key_up) self.accept("arrow_down", self.key_down) self.accept("arrow_left", self.key_left) self.accept("arrow_right", self.key_right) self.accept("l", self.key_l) self.accept("s", self.key_s) self.accept("a", self.key_a) self.accept("f", self.key_f) self.accept("g", self.key_g) self.accept("d", self.key_d) self.accept("o", self.log_start_stop) self.accept("q", self.key_q) self.accept("w", self.key_w) self.accept("z", self.key_z) self.accept("x", self.key_x) self.accept("c", self.key_c) self.accept("v", self.key_v) self.accept("b", self.key_b) self.accept("n", self.key_n) self.controller = controller base.setFrameRateMeter(True) #self.txt = OnscreenText( "Nothing", style = 1, fg = ( 1, 1, 1, 1 ), shadow = ( .9, .9, .9, .5 ), pos = ( -1.0, 0.9 ), scale = .07 ) # task to be called every frame self.step = 0 self.last_time = time.time() self.text_refresh_band = 10 self.text_refresh_count = self.text_refresh_band self._set_title("Keplermatic") self.init_gui() def init_gui(self): x = -0.9 y = 0.7 inc_y = -0.1 cb = CallBack("Logging", self.display_categories, self) self.add_gui_checkbox("Logging", False, x, y, cb.callback) y += inc_y cb = CallBack("Update", self.display_categories,self) self.add_gui_checkbox("Update", True, x, y, cb.callback) y += inc_y y += inc_y keys = self.display_categories.keys() keys.sort() for k in keys: if k in ["axis1","axis2"]: cb = CallBack(k, self.display_categories,self) category_name = k enabled = self.display_categories[category_name] self.add_gui_checkbox(category_name, enabled, x, y, cb.callback) y += inc_y y += inc_y y += inc_y for k in keys: if k not in ["axis1","axis2"]: cb = CallBack(k, self.display_categories,self) category_name = k enabled = self.display_categories[category_name] self.add_gui_checkbox(category_name, enabled, x, y, cb.callback) y += inc_y def _set_title(self, title): from pandac.PandaModules import ConfigVariableString mygameserver = ConfigVariableString("window-title","Panda") mygameserver.setValue(title) def loop(self, task): #self.last_time = time.time() delta_time = task.time - self.last_time # avoid division by 0 if delta_time < 0.0001: delta_time = 0.0001 self.last_time = task.time self.step += 1 txt = "" self._refresh_text(txt) self.controller.loop(self.step, task.time, delta_time) if self.logging: data = self.controller.get_display_data() self.log.snapshot(get_data_logger(), self.step, task.time, data, ('self')) return Task.cont def _refresh_text(self, txt): if not self.enable_screen_updates: return self.text_refresh_count -=1 if self.text_refresh_count <0: self.text_refresh_count = self.text_refresh_band data = self.controller.get_display_data() st = str(self.last_time) data['Time'] = (st, "sim", 0) data['step'] = (self.step, "sim", 0) self.txt.clearText() self.txt.setAlign(TextNode.ALeft) keys = data.keys() keys.sort() txt += "logging: %s\n" % self.logging #print keys show_axis1 = self.display_categories['axis1'] show_axis2 = self.display_categories['axis2'] for name in keys: if name == 'self': continue display_data = data[name] #print display_data value, category, axis = display_data if category not in self.display_categories.keys(): category = "other" show_category = self.display_categories[category] show_it = show_category if not show_it: #print " %s hidden (category %s hidden)" % (name, category) pass if axis == 1: if show_axis1 == False: #print " %s hidden (axis 1)" % name show_it = False if axis == 2: if show_axis2 == False: #print " %s hidden (axis 2)" % name show_it = False if show_it: #print "**** name %s, cat %s [%s], axis %s, value %s show1 %s, show2 %s" %(name, category, show_it, axis, value, show_axis1, show_axis2) value_str = "%s" % value if type(value) == type(0.): # float value_str = "%.10f" % value txt += "%s: %s\n" % (name, value_str) else: pass #print "XXXX name %s, cat %s [%s], axis %s, value %s show1 %s, show2 %s" %(name, category, show_it, axis, value, show_axis1, show_axis2) self.txt.appendText(txt) def add_gui_checkbox(self, text, value, x, y, callback): b = DirectCheckButton(text = text ,scale=.05, pos=(x,0,y), command=callback) b["indicatorValue"] = value return b def quit(self): self.controller.stop() if len(self.log.data) >0: self.log.dump(get_data_logger()) sys.exit() def log_start_stop(self): if self.logging: # stopping self.controller.stop() self.log.dump(get_data_logger()) self.log.data = [] self.logging = not self.logging print "Logging %s" % self.logging def key_p(self): self.enable_screen_updates = not self.enable_screen_updates print "enable_screen_updates=", self.enable_screen_updates def key_right(self): self.controller.key_right() def key_left(self): self.controller.key_left() def key_l(self): self.controller.key_l() def key_s(self): self.controller.key_s() def key_a(self): self.controller.key_a() def key_f(self): self.controller.key_f() def key_g(self): self.controller.key_g() def key_d(self): self.controller.key_d() def key_up(self): self.controller.key_up() def key_down(self): self.controller.key_down() def key_q(self): self.controller.key_q() def key_w(self): self.controller.key_w() def key_z(self): self.controller.key_z() def key_x(self): self.controller.key_x() def key_c(self): self.controller.key_c() def key_v(self): self.controller.key_v() def key_b(self): self.controller.key_b() def key_n(self): self.controller.key_n()
class HostMenu(DirectObject): def __init__(self): self.defaultBtnMap = base.loader.loadModel("gui/button_map") self.buttonGeom = (self.defaultBtnMap.find("**/button_ready"), self.defaultBtnMap.find("**/button_click"), self.defaultBtnMap.find("**/button_rollover"), self.defaultBtnMap.find("**/button_disabled")) defaultFont = loader.loadFont('gui/eufm10.ttf') self.logFrame = DirectScrolledFrame( canvasSize=(0, base.a2dRight * 2, -5, 0), frameSize=(0, base.a2dRight * 2, (base.a2dBottom + .2) * 2, 0), frameColor=(0.1, 0.1, 0.1, 1)) self.logFrame.reparentTo(base.a2dTopLeft) # create the info and server debug output self.textscale = 0.1 self.txtinfo = OnscreenText(scale=self.textscale, pos=(0.1, -0.1), text="", align=TextNode.ALeft, fg=(0.1, 1.0, 0.15, 1), bg=(0, 0, 0, 0), shadow=(0, 0, 0, 1), shadowOffset=(-0.02, -0.02)) self.txtinfo.setTransparency(1) self.txtinfo.reparentTo(self.logFrame.getCanvas()) # create a close Server button self.btnBackPos = Vec3(0.4, 0, 0.2) self.btnBackScale = 0.25 self.btnBack = DirectButton( # Scale and position scale=self.btnBackScale, pos=self.btnBackPos, # Text text="Quit Server", text_scale=0.45, text_pos=(0, -0.1), text_fg=(0.82, 0.85, 0.87, 1), text_shadow=(0, 0, 0, 1), text_shadowOffset=(-0.02, -0.02), text_font=defaultFont, # Frame geom=self.buttonGeom, frameColor=(0, 0, 0, 0), relief=0, pressEffect=False, # Functionality command=self.back, rolloverSound=None, clickSound=None) self.btnBack.setTransparency(1) self.btnBack.reparentTo(base.a2dBottomLeft) # catch window resizes and recalculate the aspectration self.accept("window-event", self.recalcAspectRatio) self.accept("addLog", self.addLog) def show(self): self.logFrame.show() self.btnBack.show() def hide(self): self.logFrame.hide() self.btnBack.hide() def back(self): self.hide() base.messenger.send("stop_server") self.addLog("Quit Server!") def addLog(self, text): self.txtinfo.appendText(text + "\n") textbounds = self.txtinfo.getTightBounds() self.logFrame["canvasSize"] = (0, textbounds[1].getX(), textbounds[0].getZ(), 0) def recalcAspectRatio(self, window): """get the new aspect ratio to resize the mainframe""" # set the mainframe size to the window borders again self.logFrame["frameSize"] = (0, base.a2dRight * 2, (base.a2dBottom + .2) * 2, 0)