class Settings(object): ''' This class represents a joystick and holds the pygame data ''' def __init__(self): ''' this class is able to load and save the application's settings ''' self._notify = DirectNotify().newCategory("Settings") self._notify.info("New Settings-Object created: %s" % (self)) self.width = 800 self.height = 600 self.antialias = False self.fullscreen = False self._input_settings = {"keyboard": {}, "joysticks": {}} # --------------------------------------------------------- def saveSettings(self, filename): ''' ''' config = ConfigObj() config.filename = filename config["application"] = {} #config["application"]["resolution"] = "%dx%d"%(self.width, self.height) config["application"]["resolution"] = [ str(self.width), str(self.height) ] config["application"]["fullscreen"] = str(int(self.fullscreen)) config["application"]["antialias"] = str(int(self.antialias)) config["joysticks"] = {} config["keyboard"] = {} config.write() # --------------------------------------------------------- def loadSettings(self, filename): ''' ''' config = ConfigObj(filename) # self.width = int(config["application"]["resolution"][0]) self.height = int(config["application"]["resolution"][1]) self.fullscreen = bool(int(config["application"]["fullscreen"])) self.antialias = bool(int(config["application"]["antialias"])) self._input_settings = { "joysticks": config["joysticks"], "keyboard": config["keyboard"] } # --------------------------------------------------------- def getInputSettings(self): ''' ''' return self._input_settings
class Logger: """ Prints messages to the consol and/or file and or gui element """ def __init__(self, gui=None, out_file=None): self.notify = DirectNotify().newCategory('a4p') self.gui = gui self.out_file = None if out_file: self.out_file = open(path + out_file, 'a') self.out_file.write('---<Opening file on: ' + str(datetime.now()) + ' >---\n') self.debug('Logger is now logging') self.debug('Logger gui is ' + str(gui)) self.debug('Logger out_file is ' + str(out_file)) def error(self, msg): if self.gui: self.gui.showMsg('Error: ' + msg) if self.out_file: self.out_file.write('Error:' + msg + '\n') self.notify.warning('Error: ' + msg) def warning(self, msg): self.notify.warning(msg) if self.gui: self.gui.showMsg('Warning: ' + msg) if self.out_file: self.out_file.write('Warning: ' + msg + '\n') def info(self, msg): self.notify.info(msg) if self.gui: self.gui.showMsg(msg) if self.out_file: self.out_file.write(msg) def debug(self, msg): self.notify.debug(msg) if self.gui: self.gui.showMsg('Debug: ' + msg) if self.out_file: self.out_file.write('Debug: ' + msg + '\n') def exception(self, msg): if self.gui: self.gui.showMsg('Exception: ' + msg) if self.out_file: self.out_file.write('Exception: ' + msg + '\n') self.notify.error(msg) def closeLogFile(self): if self.out_file: self.out_file.write('---<Closing file on: ' + str(datetime.now()) + ' >---\n') self.out_file.close() self.out_file = None
def setup(name='Server Name'): log = DirectNotify().newCategory("Allegiance-Server-" + name) log.debug("Loading space drive") spacedrive.init(run_server=True, run_client=False, log_level='debug', window_title='Allegiance 2') log.info("Setting up server network") spacedrive.init_server_net(NetworkSystem, port=47624)
class Logging(object): def __init__(self): #create a new notify category self._notify = DirectNotify().newCategory("CamMovement") self._notify.info("Put some informational text here.") self._notify.debug("Put some informational text here.") self._notify.warning("Put some informational text here.") self._notify.error( "Put some informational text here.") #raise an exeption
class PlayerCam(object): ''' ''' def __init__(self, camera): ''' ''' self._notify = DirectNotify().newCategory("PlayerCam") self._notify.info("New PlayerCam-Object created: %s" % (self)) self._position = Vec3(0, -20, 5) self._camera = camera self._vehicle_direction = Vec3(0, 0, 0) # the direction the object is moving self._nodepath = None self._distance = 0.7 self._cam_node = NodePath() self._vehicle = None # filters = CommonFilters(base.win, self._camera) # filters.setBloom(blend=(0,1,0,0) ,desat=10, intensity=1, size='medium') # --------------------------------------------------------- def followVehicle(self, direction, vehicle=None): ''' Let the camera follow the node path. ''' if vehicle is not None: self._nodepath = vehicle.model else: self._nodepath = None self._vehicle = vehicle self._vehicle_direction = direction # --------------------------------------------------------- def updateCam(self): ''' Needs to get executed every frame that gets displayed on the screen ''' if self._nodepath is not None: x, y, z = self._nodepath.getX(), self._nodepath.getY( ), self._nodepath.getZ() self._camera.setPos( (self._nodepath.getQuat().xform(Vec3(0, -10, 6)) + self._nodepath.getPos() - (self._vehicle_direction * 0.05))) self._camera.lookAt(x, y, z) self._camera.setR(self._nodepath.getR()) else: pass # --------------------------------------------------------- def getCamera(self): return self._camera def setCamera(self, value): self._camera = value camera = property(fget=getCamera, fset=setCamera)
class Logger: """ Prints messages to the consol and/or file and or gui element """ def __init__(self, gui=None, out_file=None): self.notify = DirectNotify().newCategory('a4p') self.gui=gui self.out_file=None if out_file: self.out_file=open(path+out_file,'a') self.out_file.write('---<Opening file on: '+str(datetime.now())+' >---\n') self.debug('Logger is now logging') self.debug('Logger gui is '+str(gui)) self.debug('Logger out_file is '+str(out_file)) def error(self, msg): if self.gui: self.gui.showMsg('Error: '+msg) if self.out_file: self.out_file.write('Error:'+msg+'\n') self.notify.warning('Error: '+msg) def warning(self, msg): self.notify.warning(msg) if self.gui: self.gui.showMsg('Warning: '+msg) if self.out_file: self.out_file.write('Warning: '+msg+'\n') def info(self, msg): self.notify.info(msg) if self.gui: self.gui.showMsg(msg) if self.out_file: self.out_file.write(msg) def debug(self, msg): self.notify.debug(msg) if self.gui: self.gui.showMsg('Debug: '+msg) if self.out_file: self.out_file.write('Debug: '+msg+'\n') def exception(self, msg): if self.gui: self.gui.showMsg('Exception: '+msg) if self.out_file: self.out_file.write('Exception: '+msg+'\n') self.notify.error(msg) def closeLogFile(self): if self.out_file: self.out_file.write('---<Closing file on: '+str(datetime.now())+' >---\n') self.out_file.close() self.out_file=None
class JoystickDevice(object): ''' This class represents a joystick and holds the pygame data ''' def __init__(self, joystick): ''' @param joystick: the pygame joystick object ''' self._notify = DirectNotify().newCategory("Input") self._notify.info("New Joystick-Object created: %s" % (self)) # the pygame joysick object self.joystick = joystick self.joystick.init() #print self.joystick.get_name() # initialize the buttons axes, and cooliehats self.buttons = [] self.axes = [] self.hats = [] for i in range(self.joystick.get_numaxes()): self.axes.append(0.0) for i in range(self.joystick.get_numbuttons()): self.buttons.append(False) for i in range(self.joystick.get_numhats()): self.hats.append((0, 0)) # --------------------------------------------------------- def getAxisCount(self): ''' ''' return len(self.axes) # --------------------------------------------------------- def getHatCount(self): ''' ''' return len(self.hats) # --------------------------------------------------------- def getButtonCount(self): ''' ''' return len(self.buttons) # --------------------------------------------------------- def getName(self): ''' ''' return self.joystick.get_name()
class Logger: def __init__(self): self.notify = DirectNotify().newCategory("core") def error(self, msg): self.notify.warning(msg) def warning(self, msg): self.notify.warning(msg) def info(self, msg): self.notify.info(msg) def debug(self, msg): self.notify.debug(msg) def exception(self, msg): self.notify.error(msg)
class Logger: def __init__(self): self.notify = DirectNotify().newCategory("core") def error(self, msg): self.notify.warning(msg) def warning(self, msg): self.notify.warning(msg) def info(self, msg): self.notify.info(msg) def debug(self, msg): self.notify.debug(msg) def exception(self, msg): self.notify.error(msg)
class KeyboardDevice(object): ''' This class holds data about the keyboard ''' def __init__(self): ''' ''' self._notify = DirectNotify().newCategory("Input") self._notify.info("New Keyboard-Object created: %s" % (self)) base.buttonThrowers[0].node().setButtonUpEvent("button-up") base.buttonThrowers[0].node().setButtonDownEvent("button") base.accept("button-up", self.setKey, [False]) base.accept("button", self.setKey, [True]) self.keys = {} # --------------------------------------------------------- def setKey(self, value, key): ''' ''' self.keys[key] = value
class LogMgrBase(object): __metaclass__ = Singleton @staticmethod def init_cls(): return LogMgr if eng.base.win else LogMgrBase def __init__(self): self.__notify = DirectNotify().newCategory('ya2') self.log_conf() @staticmethod def configure(): # TODO: in __new__? loadPrcFileData('', 'notify-level-ya2 info') def log(self, msg): time = datetime.now().strftime("%H:%M:%S") self.__notify.info('{time} {msg}'.format(time=time, msg=msg)) def log_conf(self): self.log('version: ' + eng.logic.version) self.log('operative system: ' + system() + ' ' + release() + ' ' + version()) self.log('architecture: ' + str(architecture())) self.log('machine: ' + machine()) self.log('platform: ' + platform()) self.log('processor: ' + processor()) try: self.log('cores: ' + str(cpu_count())) except NotImplementedError: # on Windows self.log('cores: not implemented') self.log('panda version: ' + PandaSystem.get_version_string() + ' ' + PandaSystem.get_git_commit()) self.log('bullet version: ' + str(get_bullet_version())) self.log('appdata: ' + str(Filename.get_user_appdata_directory()))
def setup(): log = DirectNotify().newCategory("Allegiance-Client") log.debug("Loading space drive") spacedrive.init(run_server=False, run_client=True, log_level='debug', window_title='Allegiance 2') log.info('Setting up graphics') #spacedrive.init_graphics(debug_mouse=False) log.info("Setting up client gui") spacedrive.init_gui() spacedrive.base.wireframe = False spacedrive.base.accept("f3", toggleSceneWireframe) spacedrive.gui_system.setup_screen(MainMenu()) log.info("Setting up client network") spacedrive.init_server_net(NetworkSystem)
def setup(): log = DirectNotify().newCategory("Allegiance-Client") log.debug("Loading space drive") spacedrive.init(run_server=False, run_client=True, log_level='debug', window_title='Allegiance 2') log.info('Setting up graphics') #spacedrive.init_graphics(debug_mouse=False) log.info("Setting up client gui") spacedrive.init_gui() spacedrive.base.wireframe = False spacedrive.base.accept("f3", toggleSceneWireframe) spacedrive.gui_system.setup_screen(MainMenu()) log.info("Setting up client network") spacedrive.init_server_net(NetworkSystem)
class Menu(object): ''' ''' def __init__(self, parent): self._notify = DirectNotify().newCategory("Menu") self._notify.info("New Menu-Object created: %s" %(self)) #Font self.font = DynamicTextFont(FONT) self.font.setRenderMode(TextFont.RMSolid) self.KEY_DELAY = 0.15 self.player_buttonpressed = [] self._parent = parent self._players = parent.players self._devices = parent.devices taskMgr.add(self.fetchAnyKey, "fetchAnyKey") def showStartScreen(self): ''' the first screen with "press any Key" the device with the first key press will be the first player ''' self._notify.info("Initializing StartScreen") self.wii = [] #StartScreen Node self.startNode = NodePath("StartNode") self.startNode.reparentTo(render) self.startNode.setPos(-5,15,3) #Headline model headline = loader.loadModel("data/models/logo.egg") headline.setX(4.7) headline.setY(-4) headline.setZ(-2) headline.setP(90) headline.reparentTo(self.startNode) #Press any key text presskey = TextNode("PressAnyKey") presskey.setFont(self.font) presskey.setText(_("Press any key!!")) textNodePath = NodePath("PressAnyNode") textNodePath.attachNewNode(presskey) textNodePath.setPos(0,10,-9.5) textNodePath.reparentTo(self.startNode) #Show the start screen self.startNode.show() #LICHT plight = PointLight('plight') plight.setColor(VBase4(10, 10, 10, 1)) plnp = self.startNode.attachNewNode(plight) plnp.setPos(20, -800, 30) self.startNode.setLight(plnp) #Camera self.camera = base.makeCamera(base.win) self._notify.info("StarScreen initialized") # ----------------------------------------------------------------- def fetchAnyKey(self, task): ''' Return the first device with the first key stroke ''' for i in xrange(len(self._devices.devices)): if self._devices.devices[i].boost: #Kill Camera self.camera.node().setActive(False) #Kill Node self.startNode.removeNode() #Start the menu self.menu = MainMenu(self._parent, self.newGame, self._devices.devices[i], self._devices) self.menu.menuMain() return task.done return task.cont # ----------------------------------------------------------------- def newGame(self): ''' The select vehicle screen ''' base.enableParticles() self.countdown = COUNTDOWN_START #the countdown, when its over the game can be started self._notify.info("Initializing new game") #GlobPattern if we need a Panda Class self.vehicle_list = glob.glob("data/models/vehicles/*.egg") for index in range(len(self.vehicle_list)): self.vehicle_list[index] = Filename.fromOsSpecific(self.vehicle_list[index]).getFullpath() self._notify.debug("Vehicle list: %s" %(self.vehicle_list)) self.platform = loader.loadModel("data/models/platform.egg") #Loading-Text that gets displayed when loading a model text = TextNode("Loading") text.setFont(self.font) text.setText(_("Loading...")) text.setAlign(TextProperties.ACenter) self.loading = NodePath("LoadingNode") self.loading.attachNewNode(text) self.loading.setPos(0,0,2) #The countdown, its possible to start the game when its 0 text = TextNode("Countdown") text.setFont(self.font) text.setAlign(TextProperties.ACenter) text.setText(_(str(COUNTDOWN_START))) self.countdown_node = NodePath("Countdown") self.countdown_node.attachNewNode(text) self.countdown_node.setPos(0,0,4) #PreLoad the description that gets displayed when loading a model text = TextNode("name") text.setFont(self.font) text.setText(_("Loading...")) text.setAlign(TextProperties.ACenter) self.attributes = NodePath("AttributeNode") self.attributes.attachNewNode(text) self.unusedDevices = self._devices.devices[:] taskMgr.add(self.collectPlayer, "collectPlayer") #taskMgr.add(self.collectWii, "collectWii") self.screens = [] taskMgr.add(self.selectVehicle, "selectVehicle") self.color_red = Vec4(1,0,0,0) self.color_green = Vec4(0,1,0,0) self._notify.info("New game initialized") # ----------------------------------------------------------------- def selectVehicle(self, task): ''' The vehicle select and rotate task ''' #Set the countdown and hide, if > 3 self.countdown -= globalClock.getDt() if self.countdown <=0: self.countdown_node.getChild(0).node().setText(_("Go")) self.countdown_node.setColor(self.color_green) elif self.countdown <=3: self.countdown_node.getChild(0).node().setText(str(int(round((self.countdown+0.5))))) self.countdown_node.setColor(self.color_red) self.countdown_node.show() else: self.countdown_node.hide() heading = self.loading.getH() -(30 * globalClock.getDt()) self.loading.setH(heading) for player in self._players: if player.vehicle.model != None: player.vehicle.model.setH(heading) if self.player_buttonpressed[self._players.index(player)] < task.time and not player.vehicle.model_loading: if player.device.directions[0] < -0.8: self._parent.menuselect.play() self.countdown = COUNTDOWN_START self.player_buttonpressed[self._players.index(player)] = task.time + self.KEY_DELAY index = self.vehicle_list.index("data/models/vehicles/%s" %(player.vehicle.model.getName()))-1 self._notify.debug("Previous vehicle selected: %s" %(index)) player.vehicle.model_loading = True player.vehicle.model.hide() player.camera.camera.getParent().find("AttributeNode").hide()#Hide the attributes self.loading.instanceTo(player.camera.camera.getParent()) loader.loadModel(self.vehicle_list[index], callback = player.setVehicle) elif player.device.directions[0] > 0.8: self._parent.menuselect.play() self.countdown = COUNTDOWN_START self.player_buttonpressed[self._players.index(player)] = task.time + self.KEY_DELAY index = self.vehicle_list.index("data/models/vehicles/%s" %(player.vehicle.model.getName()))+1 self._notify.debug("Next vehicle selected: %s" %(index)) if index >= len(self.vehicle_list): index = 0 player.vehicle.model_loading = True player.vehicle.model.hide() player.camera.camera.getParent().find("AttributeNode").hide()#Hide the attributes self.loading.instanceTo(player.camera.camera.getParent()) loader.loadModel(self.vehicle_list[index], callback = player.setVehicle) if player.device.directions[1] > 0.8: self.countdown = COUNTDOWN_START self._parent.menuselect.play() self.player_buttonpressed[self._players.index(player)] = task.time + self.KEY_DELAY self._notify.debug("Next color selected") a = player.vehicle.model.findAllTextures() tex = a.findTexture(player.vehicle.model.getName()[:-4]) self.rotateHue(tex, 0.1) elif player.device.directions[1] < -0.8: self._parent.menuselect.play() self.countdown = COUNTDOWN_START self.player_buttonpressed[self._players.index(player)] = task.time + self.KEY_DELAY self._notify.debug("Next color selected") a = player.vehicle.model.findAllTextures() tex = a.findTexture(player.vehicle.model.getName()[:-4]) self.rotateHue(tex, -0.1) return task.cont # ----------------------------------------------------------------- def rotateHue(self, tex, value=0.1): ''' ''' img = PNMImage() tex.store(img) for y in xrange(img.getReadYSize()): for x in xrange(img.getReadXSize()): r, g, b = img.getXel(x,y) h, s, v = colorsys.rgb_to_hsv(r, g, b) h += value if h < 0: h += 360 r, g, b = colorsys.hsv_to_rgb(h, s, v) img.setXel(x,y,r,g,b) tex.load(img) # ----------------------------------------------------------------- def collectWii(self, task): ''' Collect wiimotes task ''' try: print 'Put Wiimote in discoverable mode now (press 1+2)...' wiimote = cwiid.Wiimote() self.wiimoteX.append(wiimote) print len(self.wiimoteX) except: pass return task.cont # ----------------------------------------------------------------- def collectPlayer(self, task): ''' Wait until all players are ready ''' if len(self._players) > 0 and self.player_buttonpressed[0] < task.time: if self._players[0].device.boost and self.countdown <= 0: loading = False for player in self._players: if player.vehicle.model_loading: loading = True break self._notify.debug("Loading vehicle: %s" %(loading)) if not loading: taskMgr.remove("selectVehicle") self.track = trackgen3d.Track3d(1000, 1800, 1600, 1200, 5)#len(self._players)) self.streetPath = render.attachNewNode(self.track.createRoadMesh()) #self.borderleftPath = render.attachNewNode(self.track.createBorderLeftMesh()) self.borderleftPath = render.attachNewNode(self.track.createBorderLeftMesh()) self.borderrightPath = render.attachNewNode(self.track.createBorderRightMesh()) self.borderleftcollisionPath = NodePath(self.track.createBorderLeftCollisionMesh()) self.borderrightcollisionPath = NodePath(self.track.createBorderRightCollisionMesh()) ##self.borderPath = render.attachNewNode(self.track.createBorderMesh()) textures = ["tube", "tube2", "street"] tex = textures[random.randint(0, len(textures)-1)] roadtex = loader.loadTexture('data/textures/'+tex+'.png') bordertex = loader.loadTexture('data/textures/border.png') self.streetPath.setTexture(roadtex) self.borderleftPath.setTexture(bordertex) self.borderrightPath.setTexture(bordertex) #self.streetPath = loader.loadModel('data/models/Street.egg') ##self.streetPath = loader.loadModel('data/models/Street.egg') #tex = loader.loadTexture('data/models/StreetTex.png') #self.nodePath.setTexture(tex) self._parent.startGame(self.streetPath,self.borderleftPath,self.borderrightPath, self.track.trackpoints, self.borderleftcollisionPath, self.borderrightcollisionPath) return task.done for device in self.unusedDevices: if device.boost: self.countdown = COUNTDOWN_START self.player_buttonpressed.append(0) self._parent.addPlayer(device) #Set the PlayerCam to the Vehicle select menu Node vehicleSelectNode = NodePath("VehicleSelectNode") self._players[-1].camera.camera.reparentTo(vehicleSelectNode) #Light, that casts shadows plight = Spotlight('plight') plight.setColor(VBase4(10.0, 10.0, 10.0, 1)) if (base.win.getGsg().getSupportsBasicShaders() != 0): pass ##plight.setShadowCaster(True, 2048, 2048)#enable shadows for this light ##TODO wegen Linux #Light plight.getLens().setFov(80) plnp = vehicleSelectNode.attachNewNode(plight) plnp.setPos(2, -10, 10) plnp.lookAt(0,0,0) vehicleSelectNode.setLight(plnp) ## vehicleSelectNode.setShaderAuto()#enable autoshader so we can use shadows #Light ambilight = AmbientLight('ambilight') ambilight.setColor(VBase4(0.2, 0.2, 0.2, 1)) vehicleSelectNode.setLight(vehicleSelectNode.attachNewNode(ambilight)) self.platform.instanceTo(vehicleSelectNode) #Load the platform #instance shown text self.countdown_node.instanceTo(vehicleSelectNode) #Instance the Countdown self.loading.instanceTo(vehicleSelectNode) #Show the Loading-Text self.attributes.copyTo(vehicleSelectNode).hide() self._players[-1].vehicle.model_loading = True #start loading the model loader.loadModel(self.vehicle_list[0], callback = self._players[-1].setVehicle) self._notify.debug("Loading initial vehicle: %s" %(self.vehicle_list[0])) self.unusedDevices.remove(device) self.player_buttonpressed[-1] = task.time + self.KEY_DELAY #Add the Skybox skybox = loader.loadModel("data/models/skybox.egg") t = Texture() t.load(PNMImage("data/textures/skybox_hangar.png")) skybox.setTexture(t) skybox.setBin("background", 1) skybox.setDepthWrite(0) skybox.setDepthTest(0) skybox.setLightOff() skybox.setScale(10000) skybox.reparentTo(vehicleSelectNode) for player in self._players: if self.player_buttonpressed[self._players.index(player)] < task.time: if player.device.use_item: self.countdown = COUNTDOWN_START self._notify.debug("Removing player: %s" %(player)) self.unusedDevices.append(player.device) self.player_buttonpressed.pop(self._players.index(player)) self._parent.removePlayer(player) return task.cont
class MainMenu(object): def __init__(self, parent, newGame, device, devices): self._parent = parent self._notify = DirectNotify().newCategory("Menu") self._notify.info("New Menu-Object created: %s" %(self)) self.device = device #The keybord self.devices = devices #For Wii time.sleep(1) #Bad Hack to make sure that the Key isn't pressed. self.device.boost = False #Bad Hack to make sure that the Key isn't .setColor(self.colorA)pressed. self.newGame = newGame self.track = [] #Wiimotes self.wiimoteX = [] #Font self.font = DynamicTextFont(FONT) self.font.setRenderMode(TextFont.RMSolid) self.CONF_PATH = "user/config.ini" self._conf = settings.Settings() self._conf.loadSettings(self.CONF_PATH) taskMgr.add(self.input, 'input') # ----------------------------------------------------------------- def initNode(self): ''' Create a clear menu ''' self.camera = None self.selected = 0 self.options = [] self.optionsModells = [] self.menuNode = NodePath("menuNode") self.menuNode.reparentTo(render) self.menuNode.setPos(-4.5,15,3) self.menuNode.setH(40) self.colorA = Vec4(1,1,0,0) self.colorB = Vec4(0,1,1,0) #LICHT plight = PointLight('plight') plight.setColor(VBase4(10, 10, 10, 1)) plnp = self.menuNode.attachNewNode(plight) plnp.setPos(-10, -800, 20) self.menuNode.setLight(plnp) def menuMain(self): ''' The content for the main menu ''' self.initNode() self.addOption(_("New Game"), self.newGame) self.addOption(_("Options"), self.option) self.addOption(_("Wiimote"), self.addWii) self.addOption(_("Credits"), self.newGame) self.addOption(_("Exit"), self.exit) self.road = loader.loadModel("data/models/road01.egg") self.road.reparentTo(self.menuNode) self.road.setPos(26,20,-7) self.road.setHpr(-50,10,30) #self.text = Text3D(_("NewGame")) self.showMenu() # ----------------------------------------------------------------- def menuOption(self): ''' The content for the option menu ''' self.initNode() self.addOption(_("Resolution"), self.newGame) self.addOption(_("Full Screen"), self.fullscreen) self.addOption(_("Shader"), self.newGame) self.addOption(_("Back"), self.backToMain) self.showMenu() # ----------------------------------------------------------------- def option(self): ''' Start a option menu ''' self.menuOption() taskMgr.doMethodLater(0.5, self.input, 'input') # ----------------------------------------------------------------- def backToMain(self): ''' Start a main menu ''' self.menuMain() taskMgr.doMethodLater(0.5, self.input, 'input') # ----------------------------------------------------------------- def exit(self): ''' Save the config And Exit the Game ''' self._conf.saveSettings(self.CONF_PATH) sys.exit() # ----------------------------------------------------------------- def addWii(self): pass#self.devices.wiis.getWiimotes() # try: # print 'Put Wiimote in discoverable mode now (press 1+2)...' # wiimote = cwiid.Wiimote() # self.wiimoteX.append(wiimote) # print "Wii", len(self.wiimoteX) # except: # pass self.backToMain() self._parent.menuselect.play() def fullscreen(self): ''' Witch between Fullscreen and window mode ''' self._conf.fullscreen = not self._conf.fullscreen wp = WindowProperties() wp.setFullscreen(self._conf.fullscreen) wp.setOrigin(0,0) wp.setSize(int(base.pipe.getDisplayWidth()),int(base.pipe.getDisplayHeight())) base.win.requestProperties(wp) self.option() ##TODO Save the config???? # ----------------------------------------------------------------- def input(self, task): ''' Getting the keys from all devices ''' #self._notify.debug( self.device.directions ) if self.device.directions == [1,0]: task.delayTime = 0.2 return task.again if self.device.directions == [-1,0]: task.delayTime = 0.2 return task.again if self.device.directions == [0,1]: task.delayTime = 0.2 self.selectPrev() return task.again if self.device.directions == [0,-1]: task.delayTime = 0.2 self.selectNext() return task.again if self.device.boost == True: self.chooseOption() return task.done return task.cont # ----------------------------------------------------------------- def addOption(self, name, function): ''' Add one option to the menu Node ''' text = TextNode(name) text.setFont(self.font) text.setText(name) self.options.append((name, function)) self.optionsModells.append(NodePath("test").attachNewNode(text)) #setPos fehlt self.optionsModells[-1].setColor(self.colorA) self.optionsModells[-1].setPos(0, 0, -len(self.optionsModells)) self.menuNode.attachNewNode(text) # ----------------------------------------------------------------- def hideMenu(self): ''' Remove the aktiv menu Node ''' self.menuNode.removeNode() self.camera.node().setActive(False) # ----------------------------------------------------------------- def showMenu(self): ''' Show the menu Node ''' if len(self.optionsModells) == 0: return self.optionsModells[self.selected].setColor(self.colorB) #Create a camera if there is none if self.camera is None: self.camera = base.makeCamera(base.win) else: self.camera.node().setActive(True) # ----------------------------------------------------------------- def selectNext(self): ''' Bring out the next menu option ''' self._parent.menuselect.play() old = self.selected self.selected += 1 if self.selected == len(self.options): self.selected = 0 self.optionsModells[old].setColor(self.colorA) self.optionsModells[self.selected].setColor(self.colorB) # ----------------------------------------------------------------- def selectPrev(self): ''' Bring out the previous menu option ''' self._parent.menuselect.play() old = self.selected self.selected -= 1 if self.selected == -1: self.selected = len(self.options)-1 self.optionsModells[old].setColor(self.colorA) self.optionsModells[self.selected].setColor(self.colorB) # ----------------------------------------------------------------- def chooseOption(self): ''' call the function behind the selected option ''' self._parent.menuselect.play() self.hideMenu() self.options[self.selected][1]()
class Track(object): ''' This class represents a Track ''' def __init__(self, size_x, size_y, max_height=2300): ''' the constructor creates an empty track @param size_x: (int) maximum x-coordinates @param size_y: (int) maximum y-coordinates @param max_height: (int) maximum z-coordinates ''' # self.setSize(size_x, size_y, max_height) # self.setSize(8000, 8000, 1000) self.setSize(1600, 1600, 800) self.points = [] self.curve = None self._notify = DirectNotify().newCategory("TrackGen") self._notify.info("New Track-Object created: %s" % (self)) self.prefabs = glob.glob("data/road/parts/*.xml") # ------------------------------------------------------------------------------------- def setSize(self, size_x, size_y, max_height=1000): ''' sets the size of the map. This only works if the map is not generated, yet. @param size_x: (int) maximum x-coordinates of the map @param size_y: (int) maximum y-coordinates of the map @param max_height: (int) maximum z-coordinates of the map ''' # check for the right type if type(size_x) != type(size_y) != type(max_height) != int: raise TypeError( "size_x, size_y and max_height have to be of type 'int'") # set the size self.size = Vec3(size_x, size_y, max_height) # ------------------------------------------------------------------------------------- def getSize(self): ''' returns the map size @return: (size_x, size_y, max_height) - all of type integer ''' return self.size # ------------------------------------------------------------------------- def generateTestTrack(self, player_count): # the track rand = random.randint(0, 1) # rand = 5 if rand == 0: self.trackpoints = [[0, 0, 0], [0, 500, 0], [200, 500, 0], [250, 250, 0], [300, 0, 200], [400, -500, 0], [0, -500, 0], [0, -1, 0]] scale = 2 for i in range(len(self.trackpoints)): self.trackpoints[i][0] *= scale self.trackpoints[i][1] *= scale self.trackpoints[i][2] *= scale elif rand == 5: self.trackpoints = [[0, 0, 0], [0, 500, 100], [200, 700, 200], [500, 600, 250], [300, 0, 350], [-300, -300, 350], [-700, -200, 200], [-500, -100, 100], [0, -500, -100], [100, -300, 0], [0, -1, 0]] elif rand == 2: self.trackpoints = [[0, 0, 0], [0, 500, 0], [0, 500, 100], [0, 0, 100]] elif rand == 3: self.trackpoints = [[0, 0, 0], [0, 500, 0], [200, 500, 0], [200, -500, 0], [0, -500, 0], [0, -1, 0]] elif rand == 4: prefab = Prefab(filename="data/road/parts/helix01.xml" ) # load the looping from file prefab *= 100 # scale it by 100 self.trackpoints = [] for point in prefab: # add them to the list self.trackpoints.append(point) elif rand == 1: # self.trackpoints = [Vec3(0, 0, 0), Vec3(0, 250, 0), Vec3(0, 250.559, 0), Vec3(-0.326736, 949.546, 0.00861993), Vec3(-0.671355, 949.067, 0.0177116), # Vec3(-795.452, -155.79, 21.062), Vec3(-794.946, -155.595, 21.1194), Vec3(572.476, 370.148, 175.959), Vec3(571.923, 370.304, 175.915), Vec3(-745.631, 741.556, 72.0065), Vec3(328, -550, 91), Vec3(0, -700, 0), Vec3(0, -10, 0)] self.trackpoints = [ Vec3(0, 0, 0), Vec3(0, 250, 0), Vec3(0, 949.067, 0.0177116), Vec3(-1005.452, 500.79, 21.062), Vec3(-795.452, -210, 21.062), Vec3(572.476, 370.148, 75.959), Vec3(-745.631, 741.556, 72.0065), Vec3(328, -550, 91), Vec3(0, -700, 0), Vec3(0, -100, 0) ] for i in range(len(self.trackpoints)): self.trackpoints[i][2] *= 5 self.curve = HermiteCurve() # make the list with points self.points = [] for point in self.trackpoints: self.points.append(Vec3(point[0], point[1], point[2])) for point in self.points: self.curve.appendCv(HCFREE, point[0], point[1], point[2]) for i in range(len(self.points) - 1): self.curve.setCvIn(i, Vec3(self.points[i + 1] - self.points[i - 1])) self.curve.setCvOut(i, Vec3(self.points[i + 1] - self.points[i - 1])) # self.curve.setCvIn(i, Vec3(self.points[i+1]-self.points[i-1])*.5) # self.curve.setCvOut(i, Vec3(self.points[i+1]-self.points[i-1])*.5) last = len(self.points) - 1 self.curve.setCvIn(last, Vec3(self.points[0] - self.points[-2])) self.curve.setCvOut(last, Vec3(self.points[0] - self.points[-2])) # ------------------------------------------------------------------------- def generateTrack(self, player_count): ''' ''' y = player_count * VEHICLE_DIST y_addition = 700 points = [Vec3(0, 0, 0), Vec3(0, y, 0), Vec3(0, y + y_addition, 0)] x = self.size.getX() / 2 y = self.size.getY() / 2 quadrants = [(-x, -y, 0, 0), (0, -y, x, 0), (-x, 0, 0, y), (0, 0, x, y)] # random.shuffle(quadrants) pointcloud = [] for q in quadrants: for i in range(20): point = Vec3(random.randint(q[0], q[2]), random.randint(q[1], q[3]), random.randint(0, self.size.getZ())) pointcloud.append(point) random.shuffle(pointcloud) for num_points in range(4): i = 0 while i < len(pointcloud): point = pointcloud[i] line1 = Line(points[-2], points[-1]) line2 = Line(points[-1], point) angle = line1.getAngle(line2) is_good = True print(("Angle:", angle)) if angle > 90 and angle < 270: is_good = False if line1.crossesLine(line2): is_good = False if len(line2) < 30: is_good = False if is_good: points.append(point) pointcloud.remove(point) break i += 1 points.append(Vec3(0, -y_addition, 0)) points.append(Vec3(0, -100, 0)) # print points # - - - - - - - - - - - - - - - - - - self.points = points self.curve = HermiteCurve() # HCCUT, #HCFREE , #HCG1, #HCSMOOTH for point in self.points: self.curve.appendCv(HCFREE, point[0], point[1], point[2]) for i in range(len(self.points) - 1): self.curve.setCvIn(i, Vec3(self.points[i + 1] - self.points[i - 1])) # *.5) self.curve.setCvOut(i, Vec3(self.points[i + 1] - self.points[i - 1])) # *.5) # ------------------------------------------------------------------------------------- def getInterpolatedPoints(self, resolution): ''' ''' pointlist = [] point = Vec3(0, 0, 0) length = self.curve.getMaxT() xres = length / resolution for i in range(0, resolution): self.curve.getPoint(i * xres, point) pointlist.append(Vec3(point)) return pointlist # ------------------------------------------------------------------------------------- def getLength(self): ''' ''' a = self.curve.calcLength() return a # ------------------------------------------------------------------------------------- def getPoints(self): ''' ''' return self.points
class Player(object): ''' ''' def __init__(self, number, ode_world, ode_space, device=None, camera=None): ''' ''' self._notify = DirectNotify().newCategory("Player") self._notify.info("New Player-Object created: %s" % (self)) self._ode_world = ode_world self._ode_space = ode_space self._number = number self._camera = camera self._vehicle = vehicle.Vehicle(self._ode_world, self._ode_space) # the properties of the vehicle self._device = device # The input device # self._osd_health = OnscreenText(text = "100", pos = ((self._number*0.2)-1,0.9)) self._position = 0 self._pre_position = 0 self._rank = 0 self._lap = 1 self._time = 0 # --------------------------------------------------------- def activateGameCam(self): self._camera.followVehicle(self._vehicle.boost_direction, self._vehicle) self._camera.camera.reparentTo(render) self._vehicle.model.reparentTo(render) # --------------------------------------------------------- def setPosition(self, position): ''' ''' self._position = position def getPosition(self): ''' ''' return self._position position = property(fget=getPosition, fset=setPosition) # --------------------------------------------------------- def setTime(self, time): ''' ''' self._time = time def getTime(self): ''' ''' return self._time time = property(fget=getTime, fset=setTime) # --------------------------------------------------------- def setNumber(self, number): ''' ''' self._number = number def getNumber(self): ''' ''' return self._number number = property(fget=getNumber, fset=setNumber) # --------------------------------------------------------- def setPrePosition(self, pre_position): ''' ''' self._pre_position = pre_position def getPrePosition(self): ''' ''' return self._pre_position pre_position = property(fget=getPrePosition, fset=setPrePosition) # --------------------------------------------------------- def setLap(self, lap): ''' ''' self._lap = lap def getLap(self): ''' ''' return self._lap lap = property(fget=getLap, fset=setLap) # --------------------------------------------------------- def setRank(self, rank): ''' ''' self._rank = rank def getRank(self): ''' ''' return self._rank rank = property(fget=getRank, fset=setRank) # --------------------------------------------------------- def setCamera(self, camera): ''' ''' self._camera = camera def getCamera(self): ''' ''' return self._camera camera = property(fget=getCamera, fset=setCamera) # --------------------------------------------------------- def updateOSD(self): ''' update the osd-information ''' # self._osd_health.setText(str(round(self._vehicle.energy))) def recalculateOSD(self): ''' recalculate positions of the osd ''' pass # --------------------------------------------------------- def setVehicle(self, vehicle): ''' ''' loading = self.camera.camera.getParent().find("LoadingNode") # loading.detachNode() if loading: loading.removeNode() else: self._notify.warning("Could not remove the loading node") vehicle.hide() vehicle.reparentTo(self.camera.camera.getParent()) self._vehicle.setVehicle(vehicle) vehicle.show() def getVehicle(self): ''' ''' return self._vehicle vehicle = property(fget=getVehicle, fset=setVehicle) # --------------------------------------------------------- def setDevice(self, device): ''' ''' self._device = device def getDevice(self): ''' ''' return self._device device = property(fget=getDevice, fset=setDevice) # --------------------------------------------------------- def doStep(self): ''' Needs to get executed every Ode-Step ''' self._vehicle.doStep() # --------------------------------------------------------- def updatePlayer(self): ''' Needs to get executed every Ode-Step ''' self._vehicle.model.setPosQuat(render, self._vehicle.physics_model.getPosition(), Quat(self._vehicle.physics_model.getQuaternion())) # set new position self._camera.updateCam() # --------------------------------------------------------- def __del__(self): ''' destroys all objects of the player-object ''' # Del one Camera self._camera.camera.removeNode() # node() self._notify.info("Player-Object deleted: %s" % (self))
def toggleSceneWireframe(): base.wireframe = not base.wireframe if base.wireframe: base.render.setRenderModeWireframe() else: base.render.clearRenderMode() def start_sp_game(): log.info("Starting SP Game") start_server() start_client() log.info("Setting up Solar System Body Simulator") spacedrive.init_orbits() log.info("TODO: Setting up dynamic physics") # sandbox.add_system(physics.PhysicsSystem(ships.BulletPhysicsComponent)) log.info("TODO: Setting up player-ship interface system") # sandbox.add_system(playerShipSystem.PlayerShipsSystem(ships.PilotComponent)) if run_server: start_server() if run_client or run_menu: log.info("TODO: Setting up graphics translators") spacedrive.init_graphics(debug_mouse=False)
def get_logs(task): '''Yanks Panda3D's log pipe and pumps it to logOutput''' #if line_stream.hasNewline(): while line_stream.isTextAvailable(): logOutput.contents.append(urwid.Text(line_stream.getLine())) logOutput.set_focus(len(logOutput) - 1) return task.cont if __name__ == '__main__': from direct.showbase.ShowBase import ShowBase from math import pi, sin, cos from direct.task import Task log = DirectNotify().newCategory("SandBox") log.info("Sweet") def spinCameraTask(task): angleDegrees = task.time * 6.0 angleRadians = angleDegrees * (pi / 180.0) app.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3) app.camera.setHpr(angleDegrees, 0, 0) return Task.cont class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) self.environ = self.loader.loadModel("models/environment") self.environ.reparentTo(self.render) self.environ.setScale(0.25, 0.25, 0.25) self.environ.setPos(-8, 42, 0)
class PlaneCamera(FSM, DirectObject): """Give this class a plane as argument and it will create some nodes around it which you can parent the camera to (if there are no such nodes yet). Keep in mind, that it only uses base.camera the whole time - no other cams are involved. Usage: plane_camera = PlaneCamera(aeroplane) plane_camera.setView("ThirdPerson") plane_camera.setView("Next") """ def __init__(self, parent): """Arguments: parent -- Aeroplane which the camera should follow """ # Used for debugging. Verbosity is set in config file. # Usually this is called self.notify, but in this case it would # override FSM's own. self.notifier = DirectNotify().newCategory("azure-camera") self.parent = parent # Replaced by a NodePath with all available cameras as children and # plane node as parent. self.cameras = None #if parent.__class__.__name__ is not "Aeroplane": if not isinstance(self.parent, Aeroplane): raise ParamError, "Parent must be an Aeroplane instance, " + \ "but is %s" % type(self.parent) FSM.__init__(self, "PlaneCamera: %s" % self.parent.name) DirectObject.__init__(self) try: self.camera = base.camera except: raise BaseMissing self.cameras = self.parent.node.find("cameras") if self.cameras.isEmpty(): self.createCamNodes() self.updateCamArray() self.sideview_direction = 0 # Set up the default camera self.setView("ThirdPerson") def createCamNodes(self): """Creates a few empty nodes around a plane which the camera might be parented to. It looks if there are cameras inside the model file and uses those if possible. Where everything named "camera CamType" is considered a camera. At least ThirdPerson, FirstPerson and Cockpit should be defined inside the egg file, otherwise some guessed defaults are taken. """ # Look for cameras inside the model (loaded egg file) self.cameras = NodePath("cameras") found_cams = self.parent.node.findAllMatches("**/camera ?*") found_cams.removeDuplicatePaths() found_cams.reparentTo(self.cameras) if not found_cams.isEmpty(): self.notifier.info("Cameras found under model:\n%s" % found_cams) else: self.notifier.info("No cameras found under model.") # FirstPerson camera is a must-have. Set up a guessed one if none # defined yet. if self.cameras.find("camera FirstPerson").isEmpty(): assert self.notifier.debug("No first person camera found in %s. " "Guessing best position." % self.parent.name) first_person = NodePath("camera FirstPerson") # TODO: Guess best position based on bounding box. first_person.setY(5) first_person.reparentTo(cameras) # ThirdPerson camera is a must-have. Set up a guessed one if none # defined yet. if self.cameras.find("camera ThirdPerson").isEmpty(): assert self.notifier.debug("No third person camera found in %s. " "Guessing best position." % self.parent.name) third_person = NodePath("camera ThirdPerson") # TODO: Guess best position based on bounding box. third_person.setPos(0, -30, 5) #third_person.setP(-80) third_person.reparentTo(cameras) # Cockpit needs to be accurate. Don't try to guess it. if self.cameras.find("camera Cockpit").isEmpty(): assert self.notifier.debug("No cockpit camera found in " "%s. Cockpit camera disabled." % self.parent.name) self.sideview_cam = NodePath("camera Sideview") self.sideview_cam.reparentTo(render) # Store the cams at parent node.. # You can edit the camera nodes from outside as well. # If you attach new camera nodes, though, you'll have to call this # function again. self.cameras.reparentTo(self.parent.node) def updateCamArray(self, cameramodes=None): """Set the cameras which next and previous will switch to. Expects a list or tuple. Defaults to all available cameras.""" a = [] if not cameramodes: for c in self.cameras.getChildren(): if c.getName().startswith("camera "): a.append(c.getName().strip("camera ")) self.setStateArray(a) else: self.setStateArray(cameramodes) def getView(self): """Returns the current view mode.""" return self.getCurrentOrNextState() def setView(self, mode, *args): """Convenience function.""" return self.request(mode, args) def defaultEnter(self, *args): """Executed by the FSM every time an undefined state is entered. Note: this function is called AFTER the responsible filter.""" assert self.notifier.debug("Changing state from %s to %s with args: %s." % (self.oldState, self.newState, args)) request = self.newState target_cam = self.cameras.find("camera " + request) if not target_cam.isEmpty(): try: self.camera.reparentTo(target_cam) self.camera.setPosHpr(0, 0, 0, 0, 0, 0) except: self.notifier.warning( "Ok, now this really shouldn't happen! Filter said the " "camera is there and enter can't find it...") def defaultFilter(self, request, args): """Executed by the FSM every time an undefined state is requested.""" assert self.notifier.debug("Requested %s with args: %s" % (request, args)) self.camera.setPosHpr(0, 0, 0, 0, 0, 0) # Always available. if request == "Off": # implemented in FSM.py return (request,) + args if request == "Next": # implemented in FSM.py return self.requestNext(args) if request == "Prev": # implemented in FSM.py return self.requestPrev(args) if request == "Detached": return (request,) + args if request == "Sideview": return (request,) + args # Depending on airplane. if not self.cameras.find("camera " + request).isEmpty(): # TODO(Nemesis13, 26.10.09): add some nice camera transition return (request,) + args assert self.notifier.info("Sorry, no %s camera found." % request) return None def enterOff(self, *args): """Clean up everything by reparenting the camera to the airplane.""" self.camera.reparentTo(self.parent.node) self.camera.setPosHpr(0, 0, 0, 0, 0, 0) def enterSideview(self, *args): self.sideview_direction += 90 self.camera.reparentTo(self.sideview_cam) self.camera.setY(-30) self.sideview_cam.setH(self.sideview_direction) self.addTask(self.updateSideview, "sideview camera", taskChain="world") def exitSideview(self, *args): self.removeTask("sideview camera") def updateSideview(self, task): self.sideview_cam.setPos(self.parent.node.getPos()) return Task.cont def enterDetached(self, *args): """Lets the camera view the plane from far away.""" self.camera.reparentTo(render) self.camera.setPosHpr(0, 0, 10, 0, 0, 0) self.addTask(self.updateDetachedCam, "detached camera", taskChain="world") def exitDetached(self, *args): self.removeTask("detached camera") def updateDetachedCam(self, task): """Updates camera position and rotation for Detached camera.""" try: self.camera.lookAt(self.parent.node) except: self.notifier.warning("Error on detached cam task. Exit.") return Task.done return Task.cont def enterThirdPerson(self, *args): """Lets the camera view the plane from far away.""" self._hist = [] self.camera.reparentTo(self.cameras.find("camera ThirdPerson")) self.addTask(self.updateThirdPersonCam, "third person camera", taskChain="world") #print "entering third person" def exitThirdPerson(self, *args): self.removeTask("third person camera") del self._hist #print "third person exited" def updateThirdPersonCam(self, task): """Updates camera position and rotation for ThirdPerson camera.""" #speed = self.parent.speed() #plane = self.parent.node #self._hist.insert(0, [task.time, camera.getPos(plane)]) #while len(self._hist) > 50: # self._hist.pop() # #for snapshot in self._hist: # if snapshot[0] > task.time: # break #time_delta = snapshot[0] - task.time #self.camera.setPos(plane, snapshot[1]) #print snapshot #self.camera.setPos(render, snapshot[1]) #self.camera.lookAt(plane, (0, 20+1*speed, 0)) #self.camera.setY(5+0.1*speed) #self.camera.setZ(5-0.1*speed) return Task.cont def destroy(self): self.removeAllTasks() self.demand("Off")
class Track3d(object): ''' Generate the 3d Mesh out of the StreetData and the 2dTrack ''' def __init__(self, res, x, y, z=200, player_count=1, street_data=""): ''' ''' self._notify = DirectNotify().newCategory("TrackGen3D") self._notify.info("New Track3D-Object created: %s" % (self)) # street_data = (Vec2(4.0,4.0), Vec2(10.0,10.0), Vec2(10.0,0.0), Vec2(4.0,0.0), Vec2(0.0,-1.0)) # street_data = StreetData(Vec2(15.0,1.0), Vec2(15.0,-5.0), Vec2(0.0,-5.0), mirrored=True) #, Vec2(15.0,0.0) self.street_data = StreetData() # self.street_data.readFile("data/road/road01.xml") # self.street_data.readFile("data/road/tube.xml") if street_data == "": datas = ["road01", "tube"] street_data = datas[random.randint(0, len(datas) - 1)] self.street_data.readFile("data/road/" + street_data + ".xml") self.streetTextrange = 0.0 self.track = Track(x, y, z) self.track.generateTestTrack(player_count) # self.track.generateTrack(player_count) self.track_points = self.track.getInterpolatedPoints(res) self.varthickness = [] # Generate the Vector for thickness of the road self.generateNormals() # for i in range(len(self.track_points)-1): # if i == 0: # self.varthickness.append(self.calcTheVector(self.track_points[i],self.track_points[i],self.track_points[i+1])) #First # continue # self.varthickness.append(self.calcTheVector(self.track_points[i-1],self.track_points[i],self.track_points[i+1])) # self.varthickness.append(self.calcTheVector(self.track_points[len(self.track_points)-2],self.track_points[len(self.track_points)-1],self.track_points[len(self.track_points)-1])) #Last ## # Normalizing the Vector # for i in self.varthickness: # i.normalize() ## # print self.varthickness[-1] # print self.varthickness[0] # print self.varthickness[1] # print self.varthickness[2] # Spin the last 100 Points a litte bit to Vec3(-1,0,0) for i in range(-100, 1): # print self.varthickness[i] * (-i / 100), self.varthickness[i] , ((i* -1) / 100.0), i # print ((i* -1) / 100.0), self.varthickness[i], self.varthickness[i] * ((i* -1) / 100.0) self.varthickness[i] = self.varthickness[i] * (((i + 1) * -1) / 100.0) + Vec3(-1, 0, 0) self.normals[i] = self.normals[i] * (((i + 1) * -1) / 100.0) + Vec3(0, 0, 1) self.varthickness[i].normalize() self.normals[i].normalize() # print self.varthickness[i] # print self.varthickness[-1] # print self.varthickness[0] # print self.varthickness[1] # print self.varthickness[2] # print self.varthickness # for i in range(len(self.varthickness)): # if self.varthickness[i-1].almostEqual(self.varthickness[i], 0.3): # pass # else: # print "varthickness", self.varthickness[i-1], self.varthickness[i] # ------------------------------------------------------------------------------------- def resetWriters(self): ''' ''' self.vdata = GeomVertexData('street', GeomVertexFormat.getV3n3c4t2(), Geom.UHStatic) self.vertex = GeomVertexWriter(self.vdata, 'vertex') self.normal = GeomVertexWriter(self.vdata, 'normal') self.color = GeomVertexWriter(self.vdata, 'color') self.texcoord = GeomVertexWriter(self.vdata, 'texcoord') self.prim = GeomTriangles(Geom.UHStatic) # ------------------------------------------------------------------------------------- def calcTheVector(self, pre, now, past): vector1 = (pre[0] - now[0], pre[1] - now[1]) vector2 = (now[0] - past[0], now[1] - past[1]) high = pre[2] - past[2] return Vec3(((vector1[1] + vector2[1]) / 2.0), ((vector1[0] + vector2[0]) / 2.0), high) # ------------------------------------------------------------------------------------- def getVarthickness(self): return self.varthickness # ------------------------------------------------------------------------------------- def setTrackPoints(self, track_points): ''' ''' self.track_points = track_points def getTrackPoints(self): ''' ''' return self.track_points trackpoints = property(fget=getTrackPoints, fset=setTrackPoints) # ------------------------------------------------------------------------------------- def generateNormals(self): ''' ''' self.varthickness = [] self.normals = [] last_normal = Vec3(0, 0, 1) # last_vec = Vec3(0, 1, 0) for i in range(len(self.track_points)): if i == 0: vec = self.track_points[0] - self.track_points[1] elif i + 1 == len(self.track_points): vec = self.track_points[i - 1] - self.track_points[0] else: vec = self.track_points[i - 1] - self.track_points[i + 1] # calculate here the direction out of the street vector and the last normal last_normal.normalize() vec.normalize() mat = Mat3() mat.setRotateMat(-90, last_normal) # turn the direction around the last_normal turned_vec = mat.xform(vec) turned_vec.normalize() last_normal = turned_vec.cross(vec) # calculate the new normal turned_vec.normalize() self.varthickness.append(turned_vec) self.normals.append(last_normal) # ------------------------------------------------------------------------------------- def createVertices(self, track_points=None, street_data=None): ''' ''' if track_points is None: track_points = self.track_points if street_data is None: street_data = self.street_data self.resetWriters() texcoordinates = [] # street_data_length = len(street_data) texcoordinates = street_data.getTexCoordinates() tracklength = self.track.getLength() tex_step = 0.006 * (0.0002 * tracklength) for i in range(len(track_points)): turned_vec = self.varthickness[i] last_normal = self.normals[i] j = 0 for shapedot in street_data: # this is like a layer in 3d [Ebenengleichung] # vec = vec + vec*scalar + vec*scalar # this is used to transform the 2d-Streetshape to 3d point = track_points[i] + (turned_vec * shapedot[0]) + (last_normal * shapedot[1]) self.vertex.addData3f(point[0], point[1], point[2]) self.normal.addData3f(0, 0, 1) # KA how to calc self.streetTextrange += tex_step self.texcoord.addData2f(texcoordinates[j], self.streetTextrange) j += 1 # ------------------------------------------------------------------------------------- def connectVertices(self, street_data): # param j = len(street_Data) j = len(street_data) for i in range(self.vdata.getNumRows() - (j)): # -j?????? oder +-1 if (i + 1) % j != 0: self.prim.addVertex(i) self.prim.addVertex(i + 1) self.prim.addVertex(i + j + 1) self.prim.closePrimitive() self.prim.addVertex(i) self.prim.addVertex(i + j + 1) self.prim.addVertex(i + j) self.prim.closePrimitive() else: # close mesh's bottom side self.prim.addVertex(i + 1 - j) self.prim.addVertex(i + 1) self.prim.addVertex(i) self.prim.closePrimitive() self.prim.addVertex(i) self.prim.addVertex(i + 1) self.prim.addVertex(i + j) self.prim.closePrimitive() # close start and end k = self.vdata.getNumRows() - j for i in range(j): if (i + 1) % j != 0: self.prim.addVertex(i) self.prim.addVertex(i + k + 1) self.prim.addVertex(i + 1) self.prim.closePrimitive() self.prim.addVertex(i) self.prim.addVertex(i + k) self.prim.addVertex(i + k + 1) self.prim.closePrimitive() else: # close mesh's bottom side self.prim.addVertex(i) self.prim.addVertex(i + k - j + 1) self.prim.addVertex(i - j + 1) self.prim.closePrimitive() self.prim.addVertex(i) self.prim.addVertex(i + k) self.prim.addVertex(i + k - j + 1) self.prim.closePrimitive() # ------------------------------------------------------------------------------------- def createRoadMesh(self): ''' ''' # Creating the Vertex self.createVertices() # Connect the Vertex self.connectVertices(self.street_data) geom = Geom(self.vdata) geom.addPrimitive(self.prim) node = GeomNode('street') node.addGeom(geom) # nodePath = self.render.attachNewNode(node) return node # ------------------------------------------------------------------------------------- def createUninterpolatedRoadMesh(self): ''' ''' # Creating the Vertex self.createVertices(self.track.getPoints(), self.street_data) # Connect the Vertex self.connectVertices(self.street_data) geom = Geom(self.vdata) geom.addPrimitive(self.prim) node = GeomNode('street') node.addGeom(geom) # nodePath = self.render.attachNewNode(node) return node # ------------------------------------------------------------------------------------- def createBorderLeftMesh(self): ''' ''' # Creating the Vertex self.createVertices(self.track_points, self.street_data.border_l) # Connect the Vertex self.connectVertices(self.street_data.border_l) geom = Geom(self.vdata) geom.addPrimitive(self.prim) node = GeomNode('border_l') node.addGeom(geom) # nodePath = self.render.attachNewNode(node) return node # ------------------------------------------------------------------------------------- def createBorderRightMesh(self): ''' ''' # Creating the Vertex self.createVertices(self.track_points, self.street_data.border_r) # Connect the Vertex self.connectVertices(self.street_data.border_r) geom = Geom(self.vdata) geom.addPrimitive(self.prim) node = GeomNode('border_r') node.addGeom(geom) # nodePath = self.render.attachNewNode(node) return node # ------------------------------------------------------------------------------------- def createBorderLeftCollisionMesh(self): ''' ''' # Creating the Vertex self.createVertices(self.track_points, self.street_data.border_l_coll) # Connect the Vertex self.connectVertices(self.street_data.border_l_coll) geom = Geom(self.vdata) geom.addPrimitive(self.prim) node = GeomNode('border_l_coll') node.addGeom(geom) # nodePath = self.render.attachNewNode(node) return node # ------------------------------------------------------------------------------------- def createBorderRightCollisionMesh(self): ''' ''' # Creating the Vertex self.createVertices(self.track_points, self.street_data.border_r_coll) # Connect the Vertex self.connectVertices(self.street_data.border_r_coll) geom = Geom(self.vdata) geom.addPrimitive(self.prim) node = GeomNode('border_r_coll') node.addGeom(geom) # nodePath = self.render.attachNewNode(node) return node
class Vehicle(object): ''' ''' def __init__(self, ode_world, ode_space, name="standard"): ''' ''' self._notify = DirectNotify().newCategory("Vehicle") self._notify.info("New Vehicle-Object created: %s" % (self)) self._ode_world = ode_world self._ode_space = ode_space self._model = None self._physics_model = None self._physics_mass = None self._collision_model = None self._speed = 0.0 # the actual speed of the vehicle (forward direction) self._direction = Vec3(0, 0, 0) # the direction the car is heading self._boost_direction = Vec3(0, 0, 0) self._boost_strength = 10.0 # the boost propertys of the vehicle self._control_strength = 1.5 # impact on the steering behaviour self._grip_strength = 0.5 # impact on the steering behaviour self._track_grip = 0.8 # impact on the steering behaviour self._energy = 100.0 self._armor = 100.0 self._max_energy = 100.0 self._max_armor = 100.0 self._weight = 10.0 self._description = "The best vehicle ever" self._name = "The flying egg" self._brake_strength = 10.0 self._hit_ground = True self._model_loading = False self._blowout = [] self._blowout_on = False self._streetnormal = Vec3(0, 0, 1) # set up the propertys of the vehicle that schould be loaded # the methods get called because the data is immutable and # wouldnt get updated when calling the objects directly # the last entry is the function to convert the string self._tags = [["name", self.setName, str], ["description", self.setDescription, str], ["control_strength", self.setControlStrength, float], ["grip_strength", self.setGripStrength, float], ["track_grip", self.setTrackGrip, float], ["max_energy", self.setMaxEnergy, float], ["max_armor", self.setMaxArmor, float], ["weight", self.setWeight, float], ["brake_strength", self.setBrakeStrength, float], ["boost_strength", self.setBoostStrength, float]] # --------------------------------------------------------- def setVehicle(self, model): ''' Choose what vehicle the player has chosen. This method initializes all data of this vehicle ''' self.cleanResources() self._notify.debug("Set new vehicle: %s" % model) # Load the attributes of the vehicle attributes = model.find("**/Attributes") if attributes.isEmpty(): self._notify.warning("No Attribute-Node found") for tag in self._tags: value = attributes.getNetTag(tag[0]) if value: self._notify.debug("%s: %s" % (tag[0], value)) # translate the value if its a string if type(tag[2](value)) == str: tag[1](_(tag[2](value))) else: tag[1](tag[2](value)) else: self._notify.warning("No value defined for tag: %s" % (tag[0])) self._weight = 10 # for testing purposes blowout = model.find("**/Blowout") if not blowout.isEmpty(): self._notify.debug("Loading Blowout-Particles") for node in blowout.getChildren(): particle = ParticleEffect() self._blowout.append(particle) particle.loadConfig('./data/particles/blowout_test.ptf') try: # try to read out the particle scale scale = float(node.getTag("scale")) except Exception: # default is 0.5 scale = .5 renderer = particle.getParticlesList()[0].getRenderer() renderer.setInitialXScale(scale) renderer.setInitialYScale(scale) particle.setLightOff() particle.start(node) particle.softStop() else: self._notify.warning("No Blowout-Node found") if self._model is not None: heading = self._model.getH() self._model.removeNode() else: heading = 160 # display the attributes text = model.getParent().find("AttributeNode") if not text.isEmpty(): node = text.find("name") if not node.isEmpty(): node = node.node() node.setText(self._name) node.update() text.show() node = text.find("description") if not node.isEmpty(): node = node.node() node.setText(self._name) node.update() text.show() self._model = model self._model.setPos(0, 0, 2) self._model.setHpr(heading, 0, 0) # #Test # plightCenter = NodePath( 'plightCenter' ) # plightCenter.reparentTo( render ) # self.interval = plightCenter.hprInterval(12, Vec3(360, 0, 0)) # self.interval.loop() # # plight = PointLight('plight') # plight.setColor(VBase4(0.8, 0.8, 0.8, 1)) # plight.setAttenuation(Vec3(1,0,0)) # plnp = plightCenter.attachNewNode(plight) # plnp.setPos(5, 5, 10) # render.setLight(plnp) # # alight = AmbientLight('alight') # alight.setColor(VBase4(0,0,0, 1)) # alnp = render.attachNewNode(alight) # render.setLight(alnp) # GlowTextur # self.glowSize=10 # self.filters = CommonFilters(base.win, self._model) # self.filters.setBloom(blend=(0,self.glowSize,0,0) ,desat=1, intensity=1, size='medium') # tex = loader.loadTexture( 'data/textures/glowmap.png' ) # ts = TextureStage('ts') # ts.setMode(TextureStage.MGlow) # self._model.setTexture(ts, tex) # Initialize the physics-simulation for the vehicle self._physics_model = OdeBody(self._ode_world) self._physics_model.setPosition(self._model.getPos(render)) self._physics_model.setQuaternion(self._model.getQuat(render)) # Initialize the mass of the vehicle physics_mass = OdeMass() physics_mass.setBoxTotal(self._weight, 1, 1, 1) self._physics_model.setMass(physics_mass) # Initialize the collision-model of the vehicle # for use with blender models # try: # col_model = loader.loadModel("data/models/vehicles/%s.collision" %(self._model.getName())) # self.collision_model = OdeTriMeshGeom(self._ode_space, OdeTriMeshData(col_model, True)) # self._notify.info("Loading collision-file: %s" %("data/models/vehicles/%s.collision" %(self._model.getName()))) # for fast collisions # except: # self._notify.warning("Could not load collision-file. Using standard collision-box") # self.collision_model = OdeTriMeshGeom(self._ode_space, OdeTriMeshData(model, False)) # self._collision_model = OdeBoxGeom(self._ode_space, 3,3,2) self._collision_model = OdeBoxGeom(self._ode_space, 3, 3, 2) self._collision_model.setBody(self._physics_model) self._collision_model.setCollideBits(7) self._collision_model.setCategoryBits(2) # Add collision-rays for the floating effect self._ray = CollisionRay(Vec3(5, 0, 0), Vec3(0, 0, -1), self._ode_space, parent=self._collision_model, collide_bits=0, length=20.0) # This one is used for the floating effect but also for slipstream self._frontray = CollisionRay(Vec3(0, 0, 0), Vec3(1, 0, 0), self._ode_space, parent=self._collision_model, collide_bits=0, length=15.0) # Overwrite variables for testing purposes self._grip_strength = 0.9 self._track_grip = 0.2 self._boost_strength = 1400 self._control_strength = 2.5 # Loading finished self._model_loading = False def toggleGlow(self): self.glowSize += .1 print((self.glowSize)) if (self.glowSize == 4): self.glowSize = 0 self.filters.setBloom(blend=(0, self.glowSize, 0, 0), desat=-2, intensity=3, size='medium') def boggleGlow(self): self.glowSize -= .1 print((self.glowSize)) if (self.glowSize == 4): self.glowSize = 0 self.filters.setBloom(blend=(0, self.glowSize, 0, 0), desat=-2, intensity=3.0, size='medium') # --------------------------------------------------------- def setPos(self, x, y, z): ''' ''' self._model.setPos(x, y, z) def getPos(self): ''' ''' return self._model.getPos() position = property(fget=getPos, fset=setPos) # --------------------------------------------------------- def startBlowout(self): ''' ''' if not self._blowout_on: self._blowout_on = True for particle in self._blowout: particle.softStart() def stopBlowout(self): ''' ''' if self._blowout_on: self._blowout_on = False for particle in self._blowout: particle.softStop() # --------------------------------------------------------- def setModel(self, model): ''' ''' self._model = model def getModel(self): ''' ''' return self._model model = property(fget=getModel, fset=setModel) # --------------------------------------------------------- def setCollisionModel(self, model): ''' ''' self._collision_model = model def getCollisionModel(self): ''' ''' return self._collision_model collision_model = property(fget=getCollisionModel, fset=setCollisionModel) # --------------------------------------------------------- def setPhysicsModel(self, model): ''' ''' self._physics_model = model def getPhysicsModel(self): ''' ''' return self._physics_model physics_model = property(fget=getPhysicsModel, fset=setPhysicsModel) # --------------------------------------------------------- def setBoost(self, strength=1): ''' Boosts the vehicle by indicated strength ''' self.startBlowout() if self._hit_ground: direction = self._streetnormal.cross( self._collision_model.getQuaternion().xform(Vec3(1, 0, 0))) self._physics_model.addForce( direction * ((self._boost_strength * self.physics_model.getMass().getMagnitude() * strength))) self._hit_ground = False self._collision_model.setCollideBits(7) else: direction = self._streetnormal.cross( self._collision_model.getQuaternion().xform(Vec3(1, 0, 0))) self._physics_model.addForce( direction * self._boost_strength * 0.5 * self.physics_model.getMass().getMagnitude() * strength) # --------------------------------------------------------- def setDirection(self, dir): ''' Steers the vehicle into the target-direction ''' rel_direction = self._collision_model.getQuaternion().xform( Vec3(dir[1], 0, dir[0])) # rel_position = self._collision_model.getQuaternion().xform(Vec3(5,0,0)) # force = Vec3(rel_direction[0]*self.direction[0]*self._control_strength*self.speed,rel_direction[1]*self.direction[1]*self._control_strength*self.speed,rel_direction[2]*self.direction[2]*self._control_strength*self.speed) self._physics_model.addTorque( -rel_direction * self._control_strength * self.physics_model.getMass().getMagnitude()) def getDirection(self): return self._direction direction = property(fget=getDirection, fset=setDirection) # --------------------------------------------------------- def getBoostDirection(self): return self._boost_direction boost_direction = property(fget=getBoostDirection) # --------------------------------------------------------- def getSpeed(self): return self._speed speed = property(fget=getSpeed) # --------------------------------------------------------- def setEnergy(self, energy): ''' Boosts the vehicle by indicated strength ''' self._energy = energy def getEnergy(self): return self._energy energy = property(fget=getEnergy, fset=setEnergy) # --------------------------------------------------------- def setModelLoading(self, bool): ''' ''' self._model_loading = bool def getModelLoading(self): return self._model_loading model_loading = property(fget=getModelLoading, fset=setModelLoading) # --------------------------------------------------------- def doStep(self): ''' Needs to get executed every Ode-Step ''' # refresh variables linear_velocity = self._physics_model.getLinearVel() direction = self._streetnormal.cross( self._collision_model.getQuaternion().xform(Vec3(1, 0, 0))) self._boost_direction[0], self._boost_direction[ 1], self._boost_direction[2] = self.physics_model.getLinearVel( )[0], self.physics_model.getLinearVel( )[1], self.physics_model.getLinearVel()[2] # This needs to be done, so we dont create a new object but only change the existing one. else the camera wont update self._direction[0], self._direction[1], self._direction[2] = direction[ 0], direction[1], direction[2] xy_direction = self.collision_model.getQuaternion().xform(Vec3( 1, 1, 0)) self._speed = Vec3(linear_velocity[0] * xy_direction[0], linear_velocity[1] * xy_direction[1], linear_velocity[2] * xy_direction[2]).length() # calculate air resistance self._physics_model.addForce( -linear_velocity * linear_velocity.length() / 10) # *((self._speed/2)*(self._speed/2)))#+linear_velocity) # calculate delayed velocity changes linear_velocity.normalize() self._direction.normalize() self._physics_model.addForce( self._direction * (self._speed * self._grip_strength * self.physics_model.getMass().getMagnitude())) # +linear_velocity) self._physics_model.addForce( -linear_velocity * (self._speed * self._grip_strength * self.physics_model.getMass().getMagnitude())) # +linear_velocity) # calculate the grip self._physics_model.addTorque( self._physics_model.getAngularVel() * -self._track_grip * self.physics_model.getMass().getMagnitude()) # refresh the positions of the collisionrays self._ray.doStep() self._frontray.doStep() self._physics_model.setGravityMode(1) # --------------------------------------------------------- def getRay(self): return self._ray ray = property(fget=getRay) # --------------------------------------------------------- def getFrontRay(self): return self._frontray frontray = property(fget=getFrontRay) # ----------------------------------------------------------------- def getHitGround(self): return self._hit_ground def setHitGround(self, value): if type(value) != bool: raise TypeError("Type should be %s not %s" % (bool, type(value))) self._hit_ground = value hit_ground = property(fget=getHitGround, fset=setHitGround) # ----------------------------------------------------------------- def getControlStrength(self): return self._control_strength def setControlStrength(self, value): self._control_strength = value control_strength = property(fget=getControlStrength, fset=setControlStrength) # ----------------------------------------------------------------- def getBoostStrength(self): return self._boost_strength def setBoostStrength(self, value): self._boost_strength = value boost_strength = property(fget=getBoostStrength, fset=setBoostStrength) # ----------------------------------------------------------------- def getGripStrength(self): return self._grip_strength def setGripStrength(self, value): self._grip_strength = value grip_strength = property(fget=getGripStrength, fset=setGripStrength) # ----------------------------------------------------------------- def getTrackGrip(self): return self._track_grip def setTrackGrip(self, value): self._track_grip = value track_grip = property(fget=getTrackGrip, fset=setTrackGrip) # ----------------------------------------------------------------- def getMaxEnergy(self): return self._max_energy def setMaxEnergy(self, value): self._max_energy = value max_energy = property(fget=getMaxEnergy, fset=setMaxEnergy) # ----------------------------------------------------------------- def getMaxArmor(self): return self._max_armor def setMaxArmor(self, value): self._max_armor = value max_armor = property(fget=getMaxArmor, fset=setMaxArmor) # ----------------------------------------------------------------- def getWeight(self): return self._weight def setWeight(self, value): self._weight = value weight = property(fget=getWeight, fset=setWeight) # ----------------------------------------------------------------- def getDescription(self): return self._description def setDescription(self, value): self._description = value description = property(fget=getDescription, fset=setDescription) # ----------------------------------------------------------------- def getBrakeStrength(self): return self._brake_strength def setBrakeStrength(self, value): self._brake_strength = value brake_strength = property(fget=getBrakeStrength, fset=setBrakeStrength) # ----------------------------------------------------------------- def getName(self): return self._name def setName(self, value): self._name = value name = property(fget=getName, fset=setName) # ----------------------------------------------------------------- def getStreetNormal(self): return self._streetnormal def setStreetNormal(self, value): self._streetnormal = value streetnormal = property(fget=getStreetNormal, fset=setStreetNormal) # ----------------------------------------------------------------- def cleanResources(self): ''' Removes old nodes, gets called when a new vehcile loads ''' for node in self._blowout: node.removeNode() self._blowout = [] if self._model is not None: for node in self._model.getChildren(): node.removeNode() self._model.removeNode() self._model = None # self._physics_model.destroy() # self._collision_model.destroy() # temporary fix because destroy() doesnt work self._physics_model.disable() self._collision_model.disable() self._notify.info("Vehicle-Object cleaned: %s" % (self)) def __del__(self): ''' Destroy unused nodes ''' for node in self._blowout: node.removeNode() if self._model is not None: for node in self._model.getChildren(): node.removeNode() self._model.removeNode() self._model = None self._physics_model.destroy() self._collision_model.destroy() # temporary fix because destroy() doesnt work self._physics_model.disable() self._collision_model.disable() self._notify.info("Vehicle-Object deleted: %s" % (self))
class SplitScreen(object): ''' This class manages multiple display regions and handles adding and removing them from screen. ''' def __init__(self, cam_count=0): ''' @param cam_count: (int) number of cameras which should be added ''' self._notify = DirectNotify().newCategory("SplitScreen") self._notify.info("New SplitScreen-Object created: %s" % (self)) self.regions = [] # the regions the screen is separated into self.cameras = [] # the cameras (empty ones are None) self.filters = [] # the shader filters applied to each camera self.cameraPosPre = [] # the position of the cameras before change self.steps = 1 self.shaders_on = False if cam_count > 0: # add cameras, if needed self.addCameras(cam_count) # ----------------------------------------------------------------- def addCamera(self): ''' adds a camera for a new player (or an additional view) @return: returns the added camera object ''' self._notify.debug("Creating new camera") unused = self.getUnusedRegion() # if there is an unused camera slot, use it if unused != -1: self.setShaderOff() self.cameras[unused] = self.createCamera(self.regions[unused]) self.setShaderOn() # if there is no free slot, we have to recalculate the regions else: self.regions = self.calculateRegions(len(self.regions) + 1) # recalc self.cameras.append(self.createCamera( self.regions[unused])) # add a cam # if there are empty slots, they're filled with None for i in xrange(len(self.regions) - len(self.cameras)): self.cameras.append(None) unused -= 1 self.refreshCameras() # rearrange the regions # if there was an unused slot, the camera is now in it # if not, unused is -1 which points to the last element of the list # so unused points always to the newest cam self._notify.debug("New regions: %s , New cameras: %s" % (self.regions, self.cameras)) self._notify.debug("New camera created") return self.cameras[unused] # ----------------------------------------------------------------- def removeCamera(self, camera): ''' removes a camera out of the list @param camera: (Camera NodePath) camera to remove ''' self._notify.debug("Removing camera: %s" % (camera)) # get the index of the camera i = self.cameras.index(camera) self.filters[i].delBloom() # deactivate the shader self.filters.pop(i) # delete the filter self.cameras.pop(i) # delete the camera self.regions.pop(i) # delete the region # delete all empty cameras try: while True: self.cameras.remove(None) except: pass # delete all empty filters try: while True: self.filters.remove(None) except: pass # the regions have to be recalculated and the cameras have to be rearranged self.regions = self.calculateRegions(len(self.cameras)) self.refreshCameras() self._notify.debug("New regions: %s , New cameras: %s" % (self.regions, self.cameras)) # ----------------------------------------------------------------- def addCameras(self, cam_count): ''' adds multiple cameras @param cam_count: (int) number of cams to add @return: (list) returns all recently added cameras ''' cams = [] # this will be returned unused = self.getUnusedRegions() # this stores all unused slots # if there are enough unused camera slots, use it if len(unused) >= cam_count: for i in unused: self.cameras[i] = self.createCamera( self.regions[i]) # add the cam self.cams.append(self.cameras[i]) # if there are not enough free slots, we have to recalculate the regions else: self.regions = self.calculateRegions( len(self.cameras) - len(unused) + cam_count) # first fill the unused slots for i in unused: self.cameras[i] = self.createCamera( self.regions[i]) # add the cam self.cams.append(self.cameras[i]) # then add all other new cams at the end for i in xrange(cam_count - len(unused)): cam = self.createCamera(self.regions[i]) self.cameras.append(cam) # add the cam cams.append(cam) # if there are empty slots, they're filled with None for i in xrange(len(self.regions) - len(self.cameras)): self.cameras.append(None) # refresh all cameras self.refreshCameras() return cams # return all added cams # ----------------------------------------------------------------- def refreshCameras(self): ''' updates the size of all cameras, when the count of the regions has changed ''' taskMgr.remove("AnimateRegion") self.cameraPosPre = [] # those are the old positions # first deactivate all shaders self.setShaderOff() # then save all old regions for i in xrange(len(self.cameras)): if self.cameras[i] != None: # add the old regions to the list region = self.cameras[i].node().getDisplayRegion(0) self.cameraPosPre.append((region.getLeft(), region.getRight(), region.getBottom(), region.getTop())) #update the aspect of the camera self.cameras[i].node().getLens().setAspectRatio( ((self.regions[i][1] - self.regions[i][0]) / (self.regions[i][3] - self.regions[i][2]))) height = self.cameras[i].node().getDisplayRegion( 0).getPixelHeight() width = self.cameras[i].node().getDisplayRegion( 0).getPixelWidth() ratio = float(width) / float(height) self.cameras[i].node().getLens().setFov(45 * ratio) # start the animation in a new task taskMgr.add(self.animateRegion, "AnimateRegion") ## #Old Code without animation ## for i in xrange(len(self.cameras)): ## if self.cameras[i] != None: ## print self.cameras[i].node().getDisplayRegion(0), self.cameras[i].node().getDisplayRegions ## self.cameras[i].node().getDisplayRegion(0).setDimensions(self.regions[i][0], self.regions[i][1], self.regions[i][2], self.regions[i][3]) ## self._notify.debug("Aspect Ratio: %s:%s" %(self.regions[i][1]-self.regions[i][0],self.regions[i][3]-self.regions[i][2])) ## ## #self.cameras[i].node().getLens().setFov(45*((self.regions[i][1]-self.regions[i][0])/(self.regions[i][3]-self.regions[i][2]))) ## self.cameras[i].node().getLens().setAspectRatio(((self.regions[i][1]-self.regions[i][0])/(self.regions[i][3]-self.regions[i][2]))) ## ## # reactivate the shaders ## self.setShaderOn() #----------------------------------------------------------------- ##TODO Use task.time instead of self.steps (Frames) def animateRegion(self, task): ''' animates the subwindows to their new positions and reactivates the shaders after that ''' # if the animation is finished, we set the positions to final values if task.time >= self.steps: for i in xrange(len(self.cameraPosPre)): self.cameras[i].node().getDisplayRegion(0).setDimensions( self.calTheDiff(self.cameraPosPre[i][0], self.regions[i][0], self.steps), self.calTheDiff(self.cameraPosPre[i][1], self.regions[i][1], self.steps), self.calTheDiff(self.cameraPosPre[i][2], self.regions[i][2], self.steps), self.calTheDiff(self.cameraPosPre[i][3], self.regions[i][3], self.steps)) self.cameras[i].node().getLens().setAspectRatio( ((self.regions[i][1] - self.regions[i][0]) / (self.regions[i][3] - self.regions[i][2]))) height = self.cameras[i].node().getDisplayRegion( 0).getPixelHeight() width = self.cameras[i].node().getDisplayRegion( 0).getPixelWidth() ratio = float(width) / float(height) self.cameras[i].node().getLens().setFov(45 * ratio) # reactivate the shaders self.setShaderOn() # end the task return task.done # animate the screens for i in xrange(len(self.cameraPosPre)): self.cameras[i].node().getDisplayRegion(0).setDimensions( self.calTheDiff(self.cameraPosPre[i][0], self.regions[i][0], task.time), self.calTheDiff(self.cameraPosPre[i][1], self.regions[i][1], task.time), self.calTheDiff(self.cameraPosPre[i][2], self.regions[i][2], task.time), self.calTheDiff(self.cameraPosPre[i][3], self.regions[i][3], task.time)) self.cameras[i].node().getLens().setAspectRatio( ((self.regions[i][1] - self.regions[i][0]) / (self.regions[i][3] - self.regions[i][2]))) height = self.cameras[i].node().getDisplayRegion( 0).getPixelHeight() width = self.cameras[i].node().getDisplayRegion(0).getPixelWidth() ratio = float(width) / float(height) self.cameras[i].node().getLens().setFov(45 * ratio) # continue the task return task.cont def calTheDiff(self, alt, neu, tasktime): return alt + ((neu - alt) / self.steps) * tasktime #----------------------------------------------------------------- def getUnusedRegion(self): ''' looks for an unused region to add a new player into it @return: (int) the index of an empty camera region ''' for i in xrange(len(self.cameras)): if self.cameras[i] == None: return i else: return -1 # ----------------------------------------------------------------- def getUnusedRegions(self): ''' looks for all unused regions to add a new player into it @return: (list) the indices of all empty camera regions ''' unused = [] for i in xrange(len(self.cameras)): if self.cameras[i] == None: unused.append(i) return unused # ----------------------------------------------------------------- def createCamera(self, region): ''' Create a camera for a new player ''' camera = base.makeCamera(base.win, displayRegion=region) camera.node().getLens().setAspectRatio( ((region[1] - region[0]) / (region[3] - region[2]))) height = camera.node().getDisplayRegion(0).getPixelHeight() width = camera.node().getDisplayRegion(0).getPixelWidth() ratio = float(width) / float(height) camera.node().getLens().setFov(45 * ratio) camera.setPos(0, -8, 3) #set its position. return camera # ----------------------------------------------------------------- def calculateRegions(self, count): ''' Calculates the window size and position for a count of n screens @return: (tuple) the display region in panda format (x1,x2,y1,y2) x is left-right, y is bottom-up ''' regions = [ ] #this list stores the display regions for the several screens separations = ceil( sqrt(count)) # how often has the screen to be separated? # this is executed if a squarical order isn't senseful if ((separations**2) - separations >= count): for y in range(int(separations - 1), 0, -1): for x in range(1, int(separations + 1), 1): regions.append( ((x - 1) / separations, x / separations, (y - 1) / (separations - 1), y / (separations - 1))) # this is executed if the player count is near a square number e.g. 9 or 16 else: for y in range(int(separations), 0, -1): for x in range(1, int(separations + 1), 1): regions.append(((x - 1) / separations, x / separations, (y - 1) / separations, y / separations)) return regions # ----------------------------------------------------------------- def setShaderOn(self): ''' activates all shaders ''' # activate the shaders self.filters = [] for i in xrange(len(self.cameras)): if self.cameras[i] != None: self.filters.append(CommonFilters(base.win, self.cameras[i])) self.filters[i].setBloom(blend=(0, 0, 0, 1), desat=-0.8, intensity=4.0, size="big") else: self.filters.append(None) self.shaders_on = True # ----------------------------------------------------------------- def setShaderOff(self): ''' deactivates all shaders ''' # deactivate the shaders for filters in self.filters: if filters != None: filters.delBloom() del filters self.filters = [] self.shaders_on = False
class RoadShape(object): ''' describes the shape of the road e.g. |__/\__| ''' def __init__(self, *args, **kwds): ''' ''' self.points = [] self.name = "street part" self.author = "Rage Tracks Team" self.mirrored = True self.texcoords = [] for arg in args: if type(arg) == Vec2: self.points.append(arg) if "name" in list(kwds.keys()): self.name = str(kwds["name"]) if "author" in list(kwds.keys()): self.author = str(kwds["author"]) if "mirrored" in list(kwds.keys()): self.mirrored = bool(kwds["mirrored"]) # if the points should be mirrored, we'll do it if self.mirrored: self.mirrorPoints() self._notify = DirectNotify().newCategory("TrackGen3D") self._notify.info("New StreetData-Object created: %s" % (self)) # ------------------------------------------------------------------------------------- def addPoint(self, x, y): ''' adds a point to the road notice: the points are connected in the same order, they're added @param x: (float) x-coordinate @param y: (float) y-coordinate ''' self.points.append(Vec2(x, y)) # ------------------------------------------------------------------------------------- def readFile(self, filename): ''' reads the shape out of a file @param filename: (str) the filename ''' self.points = [] # open file xmlfile = dom.parse(filename) # create the root element xml = xmlfile.getElementsByTagName("xml").item(0) self.name = xml.getAttribute("name") # read name and author out of root self.author = xml.getAttribute("author") # check if the points should be mirrored mirrored = xml.getAttribute("mirrored") if mirrored == "False": self.mirrored = False else: self.mirrored = True # read out the points points = xml.getElementsByTagName("points") points = points[0].childNodes pointcount = points.length for i in range(pointcount): point = points.item(i) if point.nodeType == point.ELEMENT_NODE: x = float(point.getAttribute("x")) y = float(point.getAttribute("y")) self.points.append(Vec2(x, y)) # if the points should be mirrored, we'll do it if self.mirrored: self.mirrorPoints() self.calculateTexcoordinates() # ------------------------------------------------------------------------------------- def calculateTexcoordinates(self): ''' ''' tmp = [] length = 0 n = 0 # calculate the texcoords for i in range(len(self.points) - 1): n = (self.points[i + 1] - self.points[i]).length() length += n tmp.append(n) n = (self.points[0] - self.points[i + 1]).length() tmp.append(n) length += n n = 0 self.texcoords.append(n) for i in tmp: n += i / length self.texcoords.append(n) # ------------------------------------------------------------------------------------- def getTexCoordinates(self): ''' ''' return self.texcoords # ------------------------------------------------------------------------------------- def mirrorPoints(self): ''' mirrors the point at y axis ''' pointlist = [] for point in self.points: if point.getX() <= 0: pointlist.append(point) if point.getX() != 0: pointlist.insert(0, Vec2(point.getX() * -1, point.getY())) self.points = pointlist # ------------------------------------------------------------------------------------- def demirrorPoints(self): ''' mirrors the point at y axis ''' pointlist = [] for point in self.points: if point.getX() <= 0: pointlist.append(point) self.points = pointlist # ------------------------------------------------------------------------------------- def writeFile(self, filename): ''' writes the shape into a file @param filename: (str) the filename ''' # create the document doc = Document() # chreate the root element xml = doc.createElement("xml") # the name, author and information if the points are mirrored xml.setAttribute("mirrored", str(self.mirrored)) xml.setAttribute("name", self.name) xml.setAttribute("author", self.author) doc.appendChild(xml) # insert the points points = doc.createElement("points") if self.mirrored: self.demirrorPoints() for point in self.points: p = doc.createElement("point") p.setAttribute("x", str(point.getX())) p.setAttribute("y", str(point.getY())) points.appendChild(p) xml.appendChild(points) # write it into a file f = open(filename, "w") doc.writexml(f, addindent=" ", newl="\n") f.close() if self.mirrored: self.mirrorPoints() # ------------------------------------------------------------------------------------- def __str__(self): ''' returns a string representation e.g. for printing ''' return str(self.points) # ------------------------------------------------------------------------------------- def __getitem__(self, index): ''' this method is used for indexing like street_data[1] ''' return self.points[index] # ------------------------------------------------------------------------------------- def __len__(self): ''' returns the count of the points ''' return len(self.points) # ------------------------------------------------------------------------------------- def getLength(self): ''' returns the count of the points ''' return len(self.points)
class InputDevice(object): ''' ''' def __init__(self, device, settings): ''' ''' self._notify = DirectNotify().newCategory("Input") self._notify.info("New Input-Object created: %s" % (self)) self.device = device self.directions = [0, 0] # x and y movement self.boost = False # Button for boosting self.use_item = False # Button for using items self.escape = False # if this is a Joystick, look if there are Settings for Joysticks with this name if type(self.device) == joystickdevice.JoystickDevice: if self.device.getName() in settings["joysticks"]: self.settings = settings["joysticks"][self.device.getName()] else: self.settings = {} self._setStandardSettings() # Keyboard settings are always available elif type(self.device) == keyboarddevice.KeyboardDevice: #self.settings = settings["keyboard"] self.settings = {} self.settings["boost"] = "space" self.settings["use_item"] = "lalt" self.settings["up"] = "arrow_up" self.settings["down"] = "arrow_down" self.settings["left"] = "arrow_left" self.settings["right"] = "arrow_right" self.settings["escape"] = "escape" self.device.keys[self.settings["up"]] = False self.device.keys[self.settings["down"]] = False self.device.keys[self.settings["left"]] = False self.device.keys[self.settings["right"]] = False self.device.keys[self.settings["boost"]] = False self.device.keys[self.settings["use_item"]] = False self.device.keys[self.settings["escape"]] = False elif type(self.device) == wiidevice.WiiDevice: pass #Think isn't necessary by Wiimotes # maybe load settings here # --------------------------------------------------------- def _setStandardSettings(self): ''' if the input device is a joystick and no settings are available, this method analyzes the kind of the Joystick and tries to find a senseful configuration ''' # if we have at least two axes, the player is controlled by them if self.device.getAxisCount() >= 2: self.settings["directions"] = ("AXIS", 0) # if there is only one or less axes we have to use the cooliehat elif self.device.getHatCount() >= 1: self.settings["directions"] = ("HAT", 0) # if there isn't a hat either, the device can't be used else: raise StandardError( "the Joystick device has no useable axes or hats") # if four or more buttons are available, use the buttons for breakting and accelerating, too if self.device.getButtonCount() >= 4: self.settings["boost"] = ("BUTTON", 0) self.settings["use_item"] = ("BUTTON", 2) self.settings["accelerator"] = ("BUTTON", 1) self.settings["brake"] = ("BUTTON", 3) # if only two or three buttons and two axes are available, use the y-axis for breakting and accelerating elif self.device.getButtonCount() >= 2 and self.device.getAxisCount( ) >= 2: self.settings["boost"] = ("BUTTON", 0) self.settings["use_item"] = ("BUTTON", 1) self.settings["accelerator"] = ("AXIS", 0) self.settings["brake"] = ("AXIS", 0) # if only two or three buttons and a hat is available, use the y-axis of it for breakting and accelerating elif self.device.getButtonCount() >= 2 and self.device.getHatCount( ) >= 1: self.settings["boost"] = ("BUTTON", 0) self.settings["use_item"] = ("BUTTON", 1) self.settings["accelerator"] = ("HAT", 0) self.settings["brake"] = ("HAT", 0) # if the Joystick has less than 2 Buttons or less than 4 and no at or axes, it can't be used else: raise StandardError("the Joystick device has not enough buttons") # --------------------------------------------------------- def getSettings(self): ''' @return: (dict) returns the settings of the device ''' return self.settings # --------------------------------------------------------- def noticeAction(self): ''' ''' if type(self.device) == joystickdevice.JoystickDevice: ## first get the direction: # from axis if self.settings["directions"][0] == "AXIS": self.directions[0] = self.device.axes[ self.settings["directions"][1]] # or from cooliehat elif self.settings["directions"][0] == "HAT": self.directions[0] = self.device.hats[ self.settings["directions"][1]] # then get the acceleration # from buttons if self.settings["accelerator"][0] == self.settings["brake"][ 0] == "BUTTON": value = 0 if self.device.buttons[self.settings["accelerator"][1]]: value += 1 if self.device.buttons[self.settings["brake"][1]]: value -= 1 self.directions[1] = value # from axis elif self.settings["accelerator"][0] == self.settings["brake"][ 0] == "AXIS": self.directions[1] = -self.device.axes[ self.settings["accelerator"][1]] # or from cooliehat elif self.settings["accelerator"][0] == self.settings["brake"][ 0] == "HAT": self.directions[1] = self.device.hats[ self.settings["accelerator"][1]] # then get boost and item button values self.boost = self.device.buttons[self.settings["boost"][1]] self.use_item = self.device.buttons[self.settings["use_item"][1]] elif type(self.device) == keyboarddevice.KeyboardDevice: acceleration = 0 direction = 0 if self.device.keys[self.settings["up"]]: acceleration += 1 if self.device.keys[self.settings["down"]]: acceleration -= 1 if self.device.keys[self.settings["left"]]: direction -= 1 if self.device.keys[self.settings["right"]]: direction += 1 self.directions[0] = direction self.directions[1] = acceleration self.boost = self.device.keys[self.settings["boost"]] self.use_item = self.device.keys[self.settings["use_item"]] if self.device.keys[self.settings["escape"]]: sys.exit() elif type(self.device) == wiidevice.WiiDevice: pass
class PlaneView(FSM, DirectObject): """Give this class a plane as argument and it will create some nodes around it which you can parent the camera to (if there are no such nodes yet). Usage: plane_camera = PlaneCamera(aeroplane, camera) plane_camera.setView("ThirdPerson") plane_camera.setView("Next") """ def __init__(self, camera, parent): """Arguments: camera -- Camera to be used parent -- Aeroplane which the camera should follow """ self.notifier = DirectNotify().newCategory("azure-camera") self.camera = camera self.parent = parent # This gets replaced by a NodePath with all available cameras as # children and plane node as parent in createCamNodes() self.cameras = None #if parent.__class__.__name__ is not "Aeroplane": if not isinstance(self.parent, Aeroplane): raise ParamError, "Parent must be an Aeroplane instance, " + \ "but is %s" % type(self.parent) FSM.__init__(self, "PlaneCamera: %s" % self.parent.name) DirectObject.__init__(self) self.cameras = self.parent.node.find("cameras") if self.cameras.isEmpty(): self.createCamNodes() self.updateCamArray() self.sideview_direction = 0 # Set up the default camera self.setView("ThirdPerson") def createCamNodes(self): """Creates a few empty nodes around a plane which the camera might be parented to. It looks if there are cameras inside the model file and uses those if possible. Where everything named "camera CamType" is considered a camera. At least ThirdPerson, FirstPerson and Cockpit should be defined inside the egg file, otherwise some guessed defaults are taken. """ # Look for cameras inside the model (loaded egg file) self.cameras = NodePath("cameras") found_cams = self.parent.node.findAllMatches("**/camera ?*") found_cams.removeDuplicatePaths() found_cams.reparentTo(self.cameras) if not found_cams.isEmpty(): self.notifier.info("Cameras found under model:\n%s" % found_cams) else: self.notifier.info("No cameras found under model.") # FirstPerson camera is a must-have. Set up a guessed one if none # defined yet. if self.cameras.find("camera FirstPerson").isEmpty(): assert self.notifier.debug("No first person camera found in %s. " "Guessing best position." % self.parent.name) first_person = NodePath("camera FirstPerson") # TODO: Guess best position based on bounding box. first_person.setY(5) first_person.reparentTo(cameras) # ThirdPerson camera is a must-have. Set up a guessed one if none # defined yet. if self.cameras.find("camera ThirdPerson").isEmpty(): assert self.notifier.debug("No third person camera found in %s. " "Guessing best position." % self.parent.name) third_person = NodePath("camera ThirdPerson") # TODO: Guess best position based on bounding box. third_person.setPos(0, -30, 5) #third_person.setP(-80) third_person.reparentTo(cameras) # Cockpit needs to be accurate. Don't try to guess it. if self.cameras.find("camera Cockpit").isEmpty(): assert self.notifier.debug("No cockpit camera found in " "%s. Cockpit camera disabled." % self.parent.name) self.sideview_cam = NodePath("camera Sideview") self.sideview_cam.reparentTo(render) # Store the cams at parent node.. # You can edit the camera nodes from outside as well. # If you attach new camera nodes, though, you'll have to call this # function again. self.cameras.reparentTo(self.parent.node) def updateCamArray(self, cameramodes=None): """Set the cameras which next and previous will switch to. Expects a list or tuple. Defaults to all available cameras.""" a = [] if not cameramodes: for c in self.cameras.getChildren(): if c.getName().startswith("camera "): a.append(c.getName().strip("camera ")) self.setStateArray(a) else: self.setStateArray(cameramodes) def getView(self): """Returns the current view mode.""" return self.getCurrentOrNextState() def setView(self, mode, *args): """Convenience function.""" return self.request(mode, args) def defaultEnter(self, *args): """Executed by the FSM every time an undefined state is entered. Note: this function is called AFTER the responsible filter.""" assert self.notifier.debug("Changing state from %s to %s with args: %s." % (self.oldState, self.newState, args)) request = self.newState target_cam = self.cameras.find("camera " + request) if not target_cam.isEmpty(): try: self.camera.reparentTo(target_cam) self.camera.setPosHpr(0, 0, 0, 0, 0, 0) except: self.notifier.warning( "Ok, now this really shouldn't happen! Filter said the " "camera is there and enter can't find it...") def defaultFilter(self, request, args): """Executed by the FSM every time an undefined state is requested.""" assert self.notifier.debug("Requested %s with args: %s" % (request, args)) self.camera.setPosHpr(0, 0, 0, 0, 0, 0) # Always available. if request == "Off": # implemented in FSM.py return (request,) + args if request == "Next": # implemented in FSM.py return self.requestNext(args) if request == "Prev": # implemented in FSM.py return self.requestPrev(args) if request == "Detached": return (request,) + args if request == "Sideview": return (request,) + args # Depending on airplane. if not self.cameras.find("camera " + request).isEmpty(): return (request,) + args assert self.notifier.info("Sorry, no %s camera found." % request) return None def enterOff(self, *args): """Clean up everything by reparenting the camera to the airplane.""" self.camera.reparentTo(self.parent.node) self.camera.setPosHpr(0, 0, 0, 0, 0, 0) def enterSideview(self, *args): self.sideview_direction += 90 self.camera.reparentTo(self.sideview_cam) self.camera.setY(-30) self.sideview_cam.setH(self.sideview_direction) #self.addTask(self.updateSideview, "sideview camera", taskChain="world") self.task = self.updateSideview def exitSideview(self, *args): #self.removeTask("sideview camera") self.task = lambda x: Task.cont def updateSideview(self, task): self.sideview_cam.setPos(self.parent.node.getPos()) return Task.cont def enterDetached(self, *args): """Lets the camera view the plane from far away.""" self.camera.reparentTo(render) self.camera.setPosHpr(0, 0, 10, 0, 0, 0) #self.addTask(self.updateDetachedCam, "detached camera", # taskChain="world") self.task = self.updateDetachedCam def exitDetached(self, *args): #self.removeTask("detached camera") self.task = lambda x: Task.cont def updateDetachedCam(self, task): """Updates camera position and rotation for Detached camera.""" try: self.camera.lookAt(self.parent.node) except: self.notifier.warning("Error on detached cam task. Exit.") return Task.done return Task.cont def enterThirdPerson(self, *args): """Lets the camera view the plane from far away.""" self._hist = [] self.camera.reparentTo(self.cameras.find("camera ThirdPerson")) self.cameras.find("camera ThirdPerson").setPos(0, -30, 0) #self.addTask(self.updateThirdPersonCam, "third person camera", # taskChain="world") self.task = self.updateThirdPersonCam #print "entering third person" def exitThirdPerson(self, *args): #self.removeTask("third person camera") self.task = lambda x: Task.cont del self._hist def updateThirdPersonCam(self, task): """Updates camera position and rotation for ThirdPerson camera.""" speed = self.parent.physics.speed() velocity = self.parent.physics.velocity() #v = Point3(self.parent.physics.angVelVector()) v = Point3(self.parent.physics.angVelBodyHpr()) print round(v.getX(), 2), round(v.getY(), 2), round(v.getZ(), 2) #self.segs = LineSegs("lines"); #self.segs.setColor(1,1,1,1) #self.segs.drawTo(-1, 0) #self.segsnode = self.segs.create() #render2d.attachNewNode(self.segsnode) vec = Point3(self.parent.physics.angVelBodyHpr()) # Y hiervon ist pitch, Z ist roll #print round(vec.getY(), 2), round(vec.getZ(), 2) self.camera.lookAt(self.parent.node) self.camera.setR(self.camera, vec.getZ()*3) #self.camera.setPos(abs(v.getX()), 0, vec.getY()) #plane = self.parent.node #self._hist.insert(0, [task.time, camera.getPos(plane)]) #while len(self._hist) > 50: # self._hist.pop() # #for snapshot in self._hist: # if snapshot[0] > task.time: # break #time_delta = snapshot[0] - task.time #self.camera.setPos(plane, snapshot[1]) #print snapshot #self.camera.setPos(render, snapshot[1]) #self.camera.lookAt(plane, (0, 20+1*speed, 0)) #self.camera.setY(5+0.1*speed) #self.camera.setZ(5-0.1*speed) return Task.cont def update(self, task): return self.task(task) def destroy(self): self.removeAllTasks() self.demand("Off")
class Game(ShowBase): ''' ''' def __init__(self, *args): ''' ''' #loadPrcFileData("", "fullscreen 0\n win-size 1280 720") #loadPrcFileData("", "want-pstats 1\n pstats-host 127.0.0.1\n pstats-tasks 1\n task-timer-verbose 1") ## loadPrcFileData("", "sync-video #f") loadPrcFileData( "", "default-directnotify-level debug\n notify-level-x11display fatal\n notify-level-Game debug\n notify-level-Menu debug\n notify-level-Vehicle debug" ) ShowBase.__init__(self) ##base.toggleWireframe() self._notify = DirectNotify().newCategory("Game") self._notify.info("New Game-Object created: %s" % (self)) base.setBackgroundColor(0, 0, 0) base.setFrameRateMeter(True) #Show the Framerate base.camNode.setActive(False) #disable default cam self.disableMouse() #disable manual camera-control ## render.setShaderAuto() self.music = base.loader.loadSfx("data/music/track1.ogg") self.menuselect = base.loader.loadSfx("data/sounds/menuselect.wav") #Laps self.laps = 3 #the Laps self.starttime = 0 #Time the Game starts self.winingPlayer = 0 # load the settings self.settings = settings.Settings() self.settings.loadSettings("user/config.ini") gettext.install( "ragetracks", "data/language") #, unicode=True) #installs the system language #trans = gettext.translation("ragetracks", "data/language", ["de"]) #installs choosen language #trans.install() #usage: print _("Hallo Welt") #Fullscreen if self.settings.fullscreen: wp = WindowProperties() wp.setFullscreen(self.settings.fullscreen) wp.setOrigin(0, 0) wp.setTitle("RageTracks") wp.setSize(int(base.pipe.getDisplayWidth()), int(base.pipe.getDisplayHeight())) base.win.requestProperties(wp) #enable anti-aliasing if self.settings.antialias: loadPrcFileData("", "framebuffer-multisample 1\n multisamples 2") render.setAntialias(AntialiasAttrib.MMultisample) #Initialize needed variables and objects self.players = [] #holds the player objects self.TRACK_GRIP = 0.5 self.LINEAR_FRICTION = 0.02 self.ANGULAR_FRICTION = 0.02 self.splitscreen = splitscreen.SplitScreen(0) #Initialize Physics (ODE) self.world = OdeWorld() self.deltaTimeAccumulator = 0.0 #this variable is necessary to track the time for the physics self.stepSize = 1.0 / 100.0 # This stepSize makes the simulation run at 60 frames per second #Initialize Collisions (ODE) self.space = OdeSimpleSpace() #Initialize the surface-table, it defines how objects interact with each other self.world.initSurfaceTable(1) self.world.setSurfaceEntry(0, 0, 150, 100.0, 100.1, 0.9, 0.00001, 0.0, 0.002) self.space.setAutoCollideWorld(self.world) self.contactgroup = OdeJointGroup() self.space.setAutoCollideJointGroup(self.contactgroup) # initialize the input devices self.devices = inputdevice.InputDevices( self.settings.getInputSettings()) #render.setShaderAuto() startgame = True #Start the Game for arg in sys.argv: if arg == "--ep": startgame = False if sys.argv[sys.argv.index(arg) + 1] == "startGame": player = self.addPlayer(self.devices.devices[0]) import glob self.vehicle_list = glob.glob("data/models/vehicles/*.egg") #start loading the model base.enableParticles() n = 0 if len(sys.argv) >= sys.argv.index(arg) + 3: try: n = int(sys.argv[sys.argv.index(arg) + 2]) except: n = 0 if n >= len(self.vehicle_list): n = 0 self.players[0].setVehicle( loader.loadModel(self.vehicle_list[n])) taskMgr.add(self.devices.fetchEvents, "fetchEvents") track = trackgen3d.Track3d(1000, 1800, 1600, 1200, 5) #len(self._players)) streetPath = render.attachNewNode(track.createRoadMesh()) borderleftPath = render.attachNewNode( track.createBorderLeftMesh()) borderrightPath = render.attachNewNode( track.createBorderRightMesh()) borderleftcollisionPath = NodePath( track.createBorderLeftCollisionMesh()) borderrightcollisionPath = NodePath( track.createBorderRightCollisionMesh()) textures = ["tube", "tube2", "street"] tex = textures[random.randint(0, len(textures) - 1)] roadtex = loader.loadTexture('data/textures/' + tex + '.png') bordertex = loader.loadTexture('data/textures/border.png') streetPath.setTexture(roadtex) borderleftPath.setTexture(bordertex) borderrightPath.setTexture(bordertex) self.startGame(streetPath, borderleftPath, borderrightPath, track.trackpoints, borderleftcollisionPath, borderrightcollisionPath) if arg == "--PSt": PStatClient.connect( ) #activate to start performance measuring with pstats if arg == "--wire": base.toggleWireframe() if startgame: self.music.play() myMenu = Menu(self) taskMgr.add(self.devices.fetchEvents, "fetchEvents") myMenu.showStartScreen() base.accept("tab-up", self.takeScreenshot) # ----------------------------------------------------------------- def takeScreenshot(self): ''' ''' self.screenshot(source=base.win) # ----------------------------------------------------------------- def addPlayer(self, device): ''' creates a new player object, initializes it and sorts the cameras on the screen ''' self._notify.info("Adding Player, Device: %s" % (device)) screen = self.splitscreen.addCamera() camera = PlayerCam(screen) #Create a new player object self.players.append( player.Player(len(self.players), self.world, self.space, device, camera)) self._notify.info("Player added: %s" % (self.players[-1])) # ----------------------------------------------------------------- def removePlayer(self, player): ''' deletes a player object and sorts the cameras on the screem ''' #delete the cam self.splitscreen.removeCamera(player.camera.camera) #delete the player self.players.remove(player) ##all objects must be deleted! self._notify.info("Player removed: %s" % (player)) # ----------------------------------------------------------------- def createTrackpointTree(self, trackpoints): ''' Create a tree out of the trackpoints ''' self.track_tupel_list = [] #Change from Vec3 to tupel for point in self.trackpoints: self.track_tupel_list.append( (point.getX(), point.getY(), point.getZ())) self.list4tree = self.track_tupel_list[:] return KDTree.construct_from_data(self.list4tree) # ----------------------------------------------------------------- def startGame(self, track, borderl, borderr, trackpoints, borderlcoll, borderrcoll): ''' Start the game ''' #Create the KDTree for the position determination self.trackpoints = trackpoints #The mid points of the street for position calculation self.TrackpointTree = self.createTrackpointTree(self.trackpoints) self._notify = DirectNotify().newCategory("Game") self._notify.info("Initializing start game") #Initialize needed variables self.sparks = [] counter = 0 for player in self.players: player.activateGameCam() self.players[counter].vehicle.physics_model.setPosition( 0, -20 * counter, 10) self.players[counter].vehicle.model.setScale(2) self.players[counter].vehicle.model.setH(0) self.players[counter].vehicle.model.setP(0) self.players[counter].vehicle.model.setR(0) self.players[counter].vehicle.physics_model.setQuaternion( self.players[counter].vehicle.model.getQuat(render)) ## print "#####!!!!!####", self.players[counter].vehicle.getBoostStrength() self.players[counter].vehicle.setBoostStrength(1000) counter += 1 #Add the Skybox self.skybox = self.loader.loadModel("data/models/skybox.egg") t = Texture() boxes = ["space", "city", "ocean"] box = boxes[random.randint(0, len(boxes) - 1)] t.load(PNMImage("data/textures/skybox_" + box + ".png")) self.skybox.setTexture(t) self.skybox.setBin("background", 1) self.skybox.setDepthWrite(0) self.skybox.setDepthTest(0) self.skybox.setLightOff() self.skybox.setScale(10000) self.skybox.reparentTo(render) #Create the Track self.track = track self.track.reparentTo(render) self.borderl = borderl self.borderl.reparentTo(render) self.borderr = borderr self.borderr.reparentTo(render) self.borderlcoll = borderlcoll self.borderrcoll = borderrcoll ## self.borderlcoll.reparentTo(render) ## self.borderrcoll.reparentTo(render) ## roadtex = loader.loadTexture('data/textures/street.png') #### roadtex = loader.loadTexture('data/textures/tube.png') ## bordertex = loader.loadTexture('data/textures/border.png') ## self.track.setTexture(roadtex) ## self.borderl.setTexture(bordertex) ## self.borderr.setTexture(bordertex) self.rings = [] y = 100 for i in xrange(4): ring = loader.loadModel("data/models/ring.egg") ring.setScale(34) #ring.setZ(-15) ring.setY(y) y += 30 ring.setTransparency(TransparencyAttrib.MAlpha) ring.setLightOff() ring.reparentTo(render) self.rings.append(ring) taskMgr.add(self.turnRings, "turnRings") #add collision with the map self.groundGeom = OdeTriMeshGeom(self.space, OdeTriMeshData(self.track, True)) self.groundGeom.setCollideBits(0) self.groundGeom.setCategoryBits(1) self.borderl = OdeTriMeshGeom(self.space, OdeTriMeshData(self.borderlcoll, True)) self.borderl.setCollideBits(0) self.borderl.setCategoryBits(0) self.borderr = OdeTriMeshGeom(self.space, OdeTriMeshData(self.borderrcoll, True)) self.borderr.setCollideBits(0) self.borderr.setCategoryBits(0) #Create the Plane that you get hit by if you fall down self.plane = OdePlaneGeom(self.space, 0, 0, 1, -250) self.plane.setCollideBits(0) self.plane.setCategoryBits(4) #Load the Lights ambilight = AmbientLight('ambilight') ambilight.setColor(VBase4(0.2, 0.2, 0.2, 1)) render.setLight(render.attachNewNode(ambilight)) dlight = DirectionalLight('dlight') dlight.setColor(VBase4(10.0, 10.0, 10.0, 1)) if (base.win.getGsg().getSupportsBasicShaders() != 0): pass ##dlight.setShadowCaster(True, 2048, 2048) #enable shadows for this light ##TODO wegen Linux dlnp = render.attachNewNode(dlight) dlnp.setHpr(0, -60, 0) render.setLight(dlnp) self.space.setCollisionEvent("ode-collision") base.accept("ode-collision", self.onCollision) #start the gametask self._notify.debug("Starting gameTask") taskMgr.add(self.gameTask, "gameTask") self._notify.debug("Start Pos Calc") self.pos_vehicle = 0 taskMgr.add(self.calculatePos, "calculatePos") taskMgr.add(self.updatePos, "updatePos") self.world.setGravity(0, 0, -90.81) self._notify.info("Start game initialized") #set up the collision event self.starttime = time.time() # ----------------------------------------------------------------- def onCollision(self, entry): ''' Handles Collision-Events ''' geom1 = entry.getGeom1() geom2 = entry.getGeom2() body1 = entry.getBody1() body2 = entry.getBody2() for player in self.players: ## if geom1.compareTo(player.vehicle.getFrontRay().getRay()) or geom2.compareTo(player.vehicle.getFrontRay().getRay()): ## ###slipstream doesnt work but why? ## #if player.device.boost: ## player.vehicle.setBoost(player.vehicle.getBoostStrength()*0.2) #workaround until panda 1.7.1 #if the player collides with the ground plane he will get reset to the starting position if geom1.compareTo( self.plane ) == 0 and player.vehicle.physics_model.compareTo( body2) == 0 or geom2.compareTo( self.plane ) == 0 and player.vehicle.physics_model.compareTo( body1) == 0: player.vehicle.physics_model.setPosition(0, 0, 20) player.vehicle.physics_model.setLinearVel(0, 0, 0) player.vehicle.physics_model.setTorque(0, 0, 0) player.vehicle.physics_model.setRotation( Mat3.rotateMat(0, (Vec3(0, 0, 1)))) return #Decrease energy on collision elif player.vehicle.physics_model.compareTo( body1) == 0 or player.vehicle.physics_model.compareTo( body2) == 0: player.vehicle.energy -= player.vehicle.physics_model.getLinearVel( ).length() * 0.1 player.updateOSD() # ----------------------------------------------------------------- def onRayCollision(self, entry, player): ''' Handles Collision-Events with the street ''' geom1 = entry.getGeom1() geom2 = entry.getGeom2() body1 = entry.getBody1() body2 = entry.getBody2() ray = player.vehicle.ray.getRay() normal = Vec3(entry.getContactGeom(0).getNormal()) normal.normalize() player.vehicle.streetnormal = normal player.vehicle.physics_model.setGravityMode( 0) #disable gravity if on the track mass = player.vehicle.physics_model.getMass().getMagnitude() force_pos = ray.getPosition() contact = entry.getContactPoint(0) force_dir = force_pos - contact linear_velocity = player.vehicle.physics_model.getLinearVel() z_direction = player.vehicle.collision_model.getQuaternion().xform( Vec3(0, 0, 1)) actual_speed = Vec3(linear_velocity[0] * z_direction[0], linear_velocity[1] * z_direction[1], linear_velocity[2] * z_direction[2]) acceleration = ( (ray.getLength() / 2) - force_dir.length() ) * actual_speed.length() * 2.5 #calculate the direction player.vehicle.hit_ground = True player.vehicle.collision_model.setCollideBits(6) #force_dir.normalize() #Change the angle of the vehicle so it matches the street upvec = Vec3(player.vehicle.collision_model.getQuaternion().xform( Vec3(0, 0, 1))) player.vehicle.physics_model.addTorque( upvec.cross(normal) * mass * upvec.angleDeg(normal) - player.vehicle.physics_model.getAngularVel() * mass) if upvec.cross(normal).length() != 0: ## rotation = Mat3.rotateMat(upvec.angleDeg(normal),upvec.cross(normal)) ## protation=player.vehicle.physics_model.getRotation() ## protation*=rotation ## player.vehicle.collision_model.setRotation(protation) ## upvec = Vec3(player.vehicle.collision_model.getQuaternion().xform( Vec3(0, 0, 1))) player.vehicle.collision_model.setPosition(contact + (upvec * force_dir.length())) #checks if the vehicle is moving to or away from the road if (z_direction + actual_speed).length() < actual_speed.length(): goes_up = True else: goes_up = False needs_boost = 0 #calculates the needed boost based on the actual moving direction if goes_up: if actual_speed.length() < acceleration: needs_boost = acceleration - actual_speed.length() else: needs_boost = acceleration + actual_speed.length() else: if -actual_speed.length() < acceleration: needs_boost = acceleration + actual_speed.length() else: needs_boost = acceleration - actual_speed.length() #push the vehicle if needs_boost > 0: force_dir = Vec3(normal[0] * acceleration, normal[1] * acceleration, normal[2] * acceleration) player.vehicle.physics_model.addForce(force_dir * mass) #pull the vehicle elif needs_boost: force_dir = Vec3(normal[0] * acceleration, normal[1] * acceleration, normal[2] * acceleration) player.vehicle.physics_model.addForce(force_dir * mass) return # ----------------------------------------------------------------- def onFrontRayCollision(self, entry, player): ''' handles extreme changes in height collision with the street the vehicle needs to get lifted ''' normal = entry.getContactGeom(0).getNormal() mass = player.vehicle.physics_model.getMass().getMagnitude() speed = player.vehicle.speed #if speed > 5: speed = 5 upvec = Vec3(player.vehicle.collision_model.getQuaternion().xform( Vec3(0, 0, 1))) player.vehicle.physics_model.addTorque( upvec.cross(normal) * mass * 3 * upvec.angleDeg(Vec3(normal)) - player.vehicle.physics_model.getAngularVel() * mass) # ----------------------------------------------------------------- def onBorderCollision(self, entry, player): ''' handles collisions with the border ''' normal = entry.getContactGeom(0).getNormal() #player.vehicle.physics_model.addForce(player.vehicle.speed*player.vehicle.weight) #return needed_rotation = 90 - Vec3(normal).angleDeg(player.vehicle.direction) rotation = Mat3.rotateMat(needed_rotation, player.vehicle.direction) force = rotation.xform(normal) player.vehicle.physics_model.addTorque( player.vehicle.direction.cross(force) * 100 - player.vehicle.physics_model.getAngularVel()) player.vehicle.physics_model.addForce( force * player.vehicle.physics_model.getLinearVel().length() * player.vehicle.weight * 50) player.vehicle.physics_model.addForce( -(player.vehicle.physics_model.getLinearVel() * player.vehicle.weight * 50)) # ----------------------------------------------------------------- def calculatePos(self, task): ''' Appropriate the players position ''' task.delayTime = 0.1 ##TODO set value ca. 0.5 self.players[self.pos_vehicle].pre_position = self.players[ self.pos_vehicle].position self.pos_vehicle = (self.pos_vehicle + 1) % len(self.players) pos = self.TrackpointTree.query( query_point=(self.players[self.pos_vehicle].getVehicle().getPos()), t=1) self.players[self.pos_vehicle].position = self.track_tupel_list.index( pos[0]) #print (self.players[self.pos_vehicle].position - self.players[self.pos_vehicle].pre_position) #updateLaps if ((self.players[self.pos_vehicle].position - self.players[self.pos_vehicle].pre_position) <= -800): self.players[self.pos_vehicle].lap += 1 #Check if one Wins if (self.players[self.pos_vehicle].lap == self.laps + 1): #+1 because it starts at 1 print "Player", self.players[ self. pos_vehicle].number, "Time:", time.time() - self.starttime self.players[ self.pos_vehicle].time = time.time() - self.starttime self.winingPlayer += 1 if self.winingPlayer >= 3 or self.winingPlayer >= len( self.players): print "Game Finish" self._notify.debug(self.players[self.pos_vehicle].lap) if ((self.players[self.pos_vehicle].position - self.players[self.pos_vehicle].pre_position) >= 800): self.players[self.pos_vehicle].lap -= 1 #self._notify.debug( self.players[self.pos_vehicle].lap ) #self._notify.debug( ("Player", self.pos_vehicle,":", self.track_tupel_list.index(pos[0]))) #self._notify.debug( self.players[self.pos_vehicle].getVehicle().getPos()) return task.again # ----------------------------------------------------------------- def updatePos(self, task): ''' Set the rank for each player ''' task.delayTime = 0.1 ##TODO set value ca. 0.5 positionen = [] for player in self.players: positionen.append(player.position) positionen.sort() for player in self.players: player.rank = positionen.index(player.position) #self._notify.debug( ("PlayerRank", player.rank )) return task.again # ----------------------------------------------------------------- def gameTask(self, task): ''' this task runs once per frame if the game is running And calculate the physics ''' #self.space.autoCollide() # Setup the contact joints self.deltaTimeAccumulator += globalClock.getDt() while self.deltaTimeAccumulator > self.stepSize: # Step the simulation for player in self.players: player.doStep() #refresh player specific things (rays) #get the player input and set the forces if player.device.boost: player.vehicle.setBoost() else: player.vehicle.stopBlowout() if player.device.directions[ 0] != 0 or player.device.directions[1] != 0: player.vehicle.direction = player.device.directions linear_velocity = player.vehicle.physics_model.getLinearVel() angular_velocity = player.vehicle.physics_model.getAngularVel() mass = player.vehicle.physics_model.getMass().getMagnitude() #calculate airresistance to get energy out of the ode-system player.vehicle.physics_model.addForce( linear_velocity * -self.LINEAR_FRICTION * mass) player.vehicle.physics_model.addTorque( angular_velocity * -self.ANGULAR_FRICTION * mass) #calculate the ray col = OdeUtil.collide(player.vehicle.ray.getRay(), self.groundGeom) if not col.isEmpty(): self.onRayCollision( col, player ) #handles collisions from the ray with the street col = OdeUtil.collide(player.vehicle.frontray.getRay(), self.groundGeom) if not col.isEmpty(): self.onFrontRayCollision(col, player) #Collision with the border col = OdeUtil.collide(player.vehicle.collision_model, self.borderr) if not col.isEmpty(): self.onBorderCollision(col, player) else: col = OdeUtil.collide(player.vehicle.collision_model, self.borderl) if not col.isEmpty(): self.onBorderCollision(col, player) self.deltaTimeAccumulator -= self.stepSize # Remove a stepSize from the accumulator until the accumulated time is less than the stepsize self.space.autoCollide() # Setup the contact joints self.world.quickStep(self.stepSize) self.contactgroup.empty() # Clear the contact joints for player in self.players: # set new rank player.updatePlayer() return task.cont # ----------------------------------------------------------------- def turnRings(self, task): ''' ''' speeds = [.2, -.5, .7, -.3] for i in xrange(len(self.rings)): self.rings[i].setR(self.rings[i].getR() + speeds[i]) return task.cont