def set(self, pipe, width, height, fullscreen, embedded): self.notify.debugStateCall(self) state = False self.notify.info('SET') if self.restrict_to_embedded: fullscreen = 0 embedded = 1 if embedded: if base.appRunner.windowProperties: width = base.appRunner.windowProperties.getXSize() height = base.appRunner.windowProperties.getYSize() self.current_pipe = base.pipe self.current_properties = WindowProperties(base.win.getProperties()) properties = self.current_properties self.notify.debug('DISPLAY PREVIOUS:') self.notify.debug(' EMBEDDED: %s' % bool(properties.getParentWindow())) self.notify.debug(' FULLSCREEN: %s' % bool(properties.getFullscreen())) self.notify.debug(' X SIZE: %s' % properties.getXSize()) self.notify.debug(' Y SIZE: %s' % properties.getYSize()) self.notify.debug('DISPLAY REQUESTED:') self.notify.debug(' EMBEDDED: %s' % bool(embedded)) self.notify.debug(' FULLSCREEN: %s' % bool(fullscreen)) self.notify.debug(' X SIZE: %s' % width) self.notify.debug(' Y SIZE: %s' % height) if self.current_pipe == pipe and bool(self.current_properties.getParentWindow()) == bool(embedded) and self.current_properties.getFullscreen() == fullscreen and self.current_properties.getXSize() == width and self.current_properties.getYSize() == height: self.notify.info('DISPLAY NO CHANGE REQUIRED') state = True else: properties = WindowProperties() properties.setSize(width, height) properties.setFullscreen(fullscreen) properties.setParentWindow(0) if embedded: if base.appRunner.windowProperties: properties = base.appRunner.windowProperties original_sort = base.win.getSort() if self.resetWindowProperties(pipe, properties): self.notify.debug('DISPLAY CHANGE SET') properties = base.win.getProperties() self.notify.debug('DISPLAY ACHIEVED:') self.notify.debug(' EMBEDDED: %s' % bool(properties.getParentWindow())) self.notify.debug(' FULLSCREEN: %s' % bool(properties.getFullscreen())) self.notify.debug(' X SIZE: %s' % properties.getXSize()) self.notify.debug(' Y SIZE: %s' % properties.getYSize()) if bool(properties.getParentWindow()) == bool(embedded) and properties.getFullscreen() == fullscreen and properties.getXSize() == width and properties.getYSize() == height: self.notify.info('DISPLAY CHANGE VERIFIED') state = True else: self.notify.warning('DISPLAY CHANGE FAILED, RESTORING PREVIOUS DISPLAY') self.restoreWindowProperties() else: self.notify.warning('DISPLAY CHANGE FAILED') self.notify.warning('DISPLAY SET - BEFORE RESTORE') self.restoreWindowProperties() self.notify.warning('DISPLAY SET - AFTER RESTORE') base.win.setSort(original_sort) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() return state
class DisplayOptions: notify = DirectNotifyGlobal.directNotify.newCategory('DisplayOptions') def __init__(self): self.restore_failed = False self.loadFromSettings() def loadFromSettings(self): return Settings.readSettings() mode = not Settings.getWindowedMode() music = Settings.getMusic() sfx = Settings.getSfx() toonChatSounds = Settings.getToonChatSounds() musicVol = Settings.getMusicVolume() sfxVol = Settings.getSfxVolume() resList = [ (640, 480), (800, 600), (1024, 768), (1280, 1024), (1600, 1200)] res = resList[Settings.getResolution()] embed = Settings.getEmbeddedMode() self.notify.debug('before prc settings embedded mode=%s' % str(embed)) self.notify.debug('before prc settings full screen mode=%s' % str(mode)) if mode == None: mode = 1 if res == None: res = (800, 600) if not Settings.doSavedSettingsExist(): self.notify.info('loadFromSettings: No settings; isDefaultEmbedded=%s' % self.isDefaultEmbedded()) embed = self.isDefaultEmbedded() if embed and not self.isEmbeddedPossible(): self.notify.warning('Embedded mode is not possible.') embed = False if not mode and not self.isWindowedPossible(): self.notify.warning('Windowed mode is not possible.') mode = True loadPrcFileData('toonBase Settings Window Res', 'win-size %s %s' % (res[0], res[1])) self.notify.debug('settings resolution = %s' % str(res)) loadPrcFileData('toonBase Settings Window FullScreen', 'fullscreen %s' % mode) self.notify.debug('settings full screen mode=%s' % str(mode)) loadPrcFileData('toonBase Settings Music Active', 'audio-music-active %s' % music) loadPrcFileData('toonBase Settings Sound Active', 'audio-sfx-active %s' % sfx) loadPrcFileData('toonBase Settings Music Volume', 'audio-master-music-volume %s' % musicVol) loadPrcFileData('toonBase Settings Sfx Volume', 'audio-master-sfx-volume %s' % sfxVol) loadPrcFileData('toonBase Settings Toon Chat Sounds', 'toon-chat-sounds %s' % toonChatSounds) self.settingsFullScreen = mode self.settingsWidth = res[0] self.settingsHeight = res[1] self.settingsEmbedded = embed self.notify.debug('settings embedded mode=%s' % str(self.settingsEmbedded)) self.notify.info('settingsFullScreen = %s, embedded = %s width=%d height=%d' % (self.settingsFullScreen, self.settingsEmbedded, self.settingsWidth, self.settingsHeight)) def restrictToEmbedded(self, restrict, change_display = True): if base.appRunner is None or base.appRunner.windowProperties is None: restrict = 0 self.restrict_to_embedded = choice(restrict, 1, 0) self.notify.debug('restrict_to_embedded: %s' % self.restrict_to_embedded) if change_display: self.set(base.pipe, self.settingsWidth, self.settingsHeight, self.settingsFullScreen, self.settingsEmbedded) def set(self, pipe, width, height, fullscreen, embedded): self.notify.debugStateCall(self) state = False self.notify.info('SET') if self.restrict_to_embedded: fullscreen = 0 embedded = 1 if embedded: if base.appRunner.windowProperties: width = base.appRunner.windowProperties.getXSize() height = base.appRunner.windowProperties.getYSize() self.current_pipe = base.pipe self.current_properties = WindowProperties(base.win.getProperties()) properties = self.current_properties self.notify.debug('DISPLAY PREVIOUS:') self.notify.debug(' EMBEDDED: %s' % bool(properties.getParentWindow())) self.notify.debug(' FULLSCREEN: %s' % bool(properties.getFullscreen())) self.notify.debug(' X SIZE: %s' % properties.getXSize()) self.notify.debug(' Y SIZE: %s' % properties.getYSize()) self.notify.debug('DISPLAY REQUESTED:') self.notify.debug(' EMBEDDED: %s' % bool(embedded)) self.notify.debug(' FULLSCREEN: %s' % bool(fullscreen)) self.notify.debug(' X SIZE: %s' % width) self.notify.debug(' Y SIZE: %s' % height) if self.current_pipe == pipe and bool(self.current_properties.getParentWindow()) == bool(embedded) and self.current_properties.getFullscreen() == fullscreen and self.current_properties.getXSize() == width and self.current_properties.getYSize() == height: self.notify.info('DISPLAY NO CHANGE REQUIRED') state = True else: properties = WindowProperties() properties.setSize(width, height) properties.setFullscreen(fullscreen) properties.setParentWindow(0) if embedded: if base.appRunner.windowProperties: properties = base.appRunner.windowProperties original_sort = base.win.getSort() if self.resetWindowProperties(pipe, properties): self.notify.debug('DISPLAY CHANGE SET') properties = base.win.getProperties() self.notify.debug('DISPLAY ACHIEVED:') self.notify.debug(' EMBEDDED: %s' % bool(properties.getParentWindow())) self.notify.debug(' FULLSCREEN: %s' % bool(properties.getFullscreen())) self.notify.debug(' X SIZE: %s' % properties.getXSize()) self.notify.debug(' Y SIZE: %s' % properties.getYSize()) if bool(properties.getParentWindow()) == bool(embedded) and properties.getFullscreen() == fullscreen and properties.getXSize() == width and properties.getYSize() == height: self.notify.info('DISPLAY CHANGE VERIFIED') state = True else: self.notify.warning('DISPLAY CHANGE FAILED, RESTORING PREVIOUS DISPLAY') self.restoreWindowProperties() else: self.notify.warning('DISPLAY CHANGE FAILED') self.notify.warning('DISPLAY SET - BEFORE RESTORE') self.restoreWindowProperties() self.notify.warning('DISPLAY SET - AFTER RESTORE') base.win.setSort(original_sort) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() return state def resetWindowProperties(self, pipe, properties): if base.win: currentProperties = WindowProperties(base.win.getProperties()) gsg = base.win.getGsg() else: currentProperties = WindowProperties.getDefault() gsg = None newProperties = WindowProperties(currentProperties) newProperties.addProperties(properties) if base.pipe != pipe: gsg = None if gsg == None and currentProperties.getFullscreen() != newProperties.getFullscreen() or currentProperties.getParentWindow() != newProperties.getParentWindow(): self.notify.debug('window properties: %s' % properties) self.notify.debug('gsg: %s' % gsg) base.pipe = pipe if not base.openMainWindow(props = properties, gsg = gsg, keepCamera = True): self.notify.warning('OPEN MAIN WINDOW FAILED') return 0 self.notify.info('OPEN MAIN WINDOW PASSED') base.graphicsEngine.openWindows() if base.win.isClosed(): self.notify.warning('Window did not open, removing.') base.closeWindow(base.win) return 0 base.disableShowbaseMouse() if 'libotp' in sys.modules: NametagGlobals = NametagGlobals import libotp NametagGlobals.setCamera(base.cam) NametagGlobals.setMouseWatcher(base.mouseWatcherNode) else: self.notify.debug('Adjusting properties') base.win.requestProperties(properties) base.graphicsEngine.renderFrame() return 1 def restoreWindowProperties(self): if self.resetWindowProperties(self.current_pipe, self.current_properties): self.restore_failed = False else: self.notify.warning("Couldn't restore original display settings!") if base.appRunner and base.appRunner.windowProperties: fullscreen = 0 embedded = 1 tryProps = base.appRunner.windowProperties if self.resetWindowProperties(self.current_pipe, tryProps): self.current_properties = copy.copy(tryProps) self.restore_failed = False return None if self.current_properties.getFullscreen(): fullscreen = 0 embedded = 0 tryProps = self.current_properties tryProps.setFullscreen(0) if self.resetWindowProperties(self.current_pipe, tryProps): self.current_properties = copy.copy(tryProps) self.restore_failed = False return None self.notify.error('Failed opening regular window!') base.panda3dRenderError() self.restore_failed = True def isDefaultEmbedded(): result = False try: embedOption = int(base.launcher.getValue('GAME_DEFAULT_TO_EMBEDDED', None)) if embedOption != None: result = bool(int(embedOption)) except: pass return result isDefaultEmbedded = staticmethod(isDefaultEmbedded) def isEmbeddedPossible(): result = False try: showOption = base.launcher.getValue('GAME_SHOW_EMBEDDED_OPTION', None) if showOption != None: result = bool(int(showOption)) except: pass return result isEmbeddedPossible = staticmethod(isEmbeddedPossible) def isWindowedPossible(): result = True try: showOption = base.launcher.getValue('GAME_SHOW_WINDOWED_OPTION', None) if showOption != None: result = bool(int(showOption)) except: pass return result isWindowedPossible = staticmethod(isWindowedPossible)
def getScreenRatio(): props = WindowProperties(base.win.getProperties()) return float(props.getXSize()) / float(props.getYSize())
def set(self, pipe, width, height, fullscreen, embedded): self.notify.debugStateCall(self) state = False self.notify.info("SET") #fullscreen = options.fullscreen_runtime #embedded = options.embedded_runtime if self.restrict_to_embedded: fullscreen = 0 embedded = 1 if embedded: if base.appRunner.windowProperties: width = base.appRunner.windowProperties.getXSize() height = base.appRunner.windowProperties.getYSize() self.current_pipe = base.pipe self.current_properties = WindowProperties(base.win.getProperties()) properties = self.current_properties self.notify.debug("DISPLAY PREVIOUS:") self.notify.debug(" EMBEDDED: %s" % bool(properties.getParentWindow())) self.notify.debug(" FULLSCREEN: %s" % bool(properties.getFullscreen())) self.notify.debug(" X SIZE: %s" % properties.getXSize()) self.notify.debug(" Y SIZE: %s" % properties.getYSize()) self.notify.debug("DISPLAY REQUESTED:") self.notify.debug(" EMBEDDED: %s" % bool(embedded)) self.notify.debug(" FULLSCREEN: %s" % bool(fullscreen)) self.notify.debug(" X SIZE: %s" % width) self.notify.debug(" Y SIZE: %s" % height) if ((self.current_pipe == pipe) and \ (bool(self.current_properties.getParentWindow( )) == bool(embedded)) and \ (self.current_properties.getFullscreen ( ) == fullscreen) and \ (self.current_properties.getXSize ( ) == width) and \ (self.current_properties.getYSize ( ) == height)): # no display change required self.notify.info("DISPLAY NO CHANGE REQUIRED") state = True else: properties = WindowProperties() properties.setSize(width, height) properties.setFullscreen(fullscreen) properties.setParentWindow(0) if embedded: if base.appRunner.windowProperties: properties = base.appRunner.windowProperties # get current sort order original_sort = base.win.getSort() if self.resetWindowProperties(pipe, properties): self.notify.debug("DISPLAY CHANGE SET") # verify display change properties = base.win.getProperties() self.notify.debug("DISPLAY ACHIEVED:") self.notify.debug(" EMBEDDED: %s" % bool(properties.getParentWindow())) self.notify.debug(" FULLSCREEN: %s" % bool(properties.getFullscreen())) self.notify.debug(" X SIZE: %s" % properties.getXSize()) self.notify.debug(" Y SIZE: %s" % properties.getYSize()) if ((bool(properties.getParentWindow( )) == bool(embedded)) and \ (properties.getFullscreen ( ) == fullscreen) and \ (properties.getXSize ( ) == width) and \ (properties.getYSize ( ) == height)): self.notify.info("DISPLAY CHANGE VERIFIED") state = True else: self.notify.warning( "DISPLAY CHANGE FAILED, RESTORING PREVIOUS DISPLAY") self.restoreWindowProperties() else: self.notify.warning("DISPLAY CHANGE FAILED") self.notify.warning("DISPLAY SET - BEFORE RESTORE") self.restoreWindowProperties() self.notify.warning("DISPLAY SET - AFTER RESTORE") # set current sort order base.win.setSort(original_sort) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() return state
class DisplayOptions: """A class stolen from Pirates so we can respect saved window settings when we get to Pick A Toon.""" notify = DirectNotifyGlobal.directNotify.newCategory("DisplayOptions") def __init__(self): self.restore_failed = False #self.restrictToEmbedded(1, False) self.loadFromSettings() def loadFromSettings(self): """Read the saved settings.""" Settings.readSettings() mode = not Settings.getWindowedMode() music = Settings.getMusic() sfx = Settings.getSfx() toonChatSounds = Settings.getToonChatSounds() musicVol = Settings.getMusicVolume() sfxVol = Settings.getSfxVolume() resList = [(640, 480), (800, 600), (1024, 768), (1280, 1024), (1600, 1200)] #copied from Resolution in settingsFile.h res = resList[Settings.getResolution()] embed = Settings.getEmbeddedMode() self.notify.debug("before prc settings embedded mode=%s" % str(embed)) self.notify.debug("before prc settings full screen mode=%s" % str(mode)) if mode == None: mode = 1 if res == None: res = (800, 600) loadPrcFileData("toonBase Settings Window Res", ("win-size %s %s" % (res[0], res[1]))) self.notify.debug("settings resolution = %s" % str(res)) loadPrcFileData("toonBase Settings Window FullScreen", ("fullscreen %s" % (mode))) self.notify.debug("settings full screen mode=%s" % str(mode)) loadPrcFileData("toonBase Settings Music Active", ("audio-music-active %s" % (music))) loadPrcFileData("toonBase Settings Sound Active", ("audio-sfx-active %s" % (sfx))) loadPrcFileData("toonBase Settings Music Volume", ("audio-master-music-volume %s" % (musicVol))) loadPrcFileData("toonBase Settings Sfx Volume", ("audio-master-sfx-volume %s" % (sfxVol))) loadPrcFileData("toonBase Settings Toon Chat Sounds", ("toon-chat-sounds %s" % (toonChatSounds))) self.settingsFullScreen = mode self.settingsWidth = res[0] self.settingsHeight = res[1] self.settingsEmbedded = embed self.notify.debug("settings embedded mode=%s" % str(self.settingsEmbedded)) self.notify.info( "settingsFullScreen = %s, embedded = %s width=%d height=%d" % (self.settingsFullScreen, self.settingsEmbedded, self.settingsWidth, self.settingsHeight)) # these settings test error recovery, as no one has a 16000 x 12000 monitor (yet) #self.settingsFullScreen = True #self.settingsWidth = 16000 #self.settingsHeight = 12000 def restrictToEmbedded(self, restrict, change_display=True): # to completely disable restrict to embedded, uncomment: #restrict = 0 # if we are not running embedded, restricting to # embedded is not an option if base.appRunner is None or base.appRunner.windowProperties is None: restrict = 0 self.restrict_to_embedded = choice(restrict, 1, 0) self.notify.debug("restrict_to_embedded: %s" % self.restrict_to_embedded) # window mode may have changed if change_display: self.set(base.pipe, self.settingsWidth, self.settingsHeight, self.settingsFullScreen, self.settingsEmbedded) def set(self, pipe, width, height, fullscreen, embedded): self.notify.debugStateCall(self) state = False self.notify.info("SET") #fullscreen = options.fullscreen_runtime #embedded = options.embedded_runtime if self.restrict_to_embedded: fullscreen = 0 embedded = 1 if embedded: if base.appRunner.windowProperties: width = base.appRunner.windowProperties.getXSize() height = base.appRunner.windowProperties.getYSize() self.current_pipe = base.pipe self.current_properties = WindowProperties(base.win.getProperties()) properties = self.current_properties self.notify.debug("DISPLAY PREVIOUS:") self.notify.debug(" EMBEDDED: %s" % bool(properties.getParentWindow())) self.notify.debug(" FULLSCREEN: %s" % bool(properties.getFullscreen())) self.notify.debug(" X SIZE: %s" % properties.getXSize()) self.notify.debug(" Y SIZE: %s" % properties.getYSize()) self.notify.debug("DISPLAY REQUESTED:") self.notify.debug(" EMBEDDED: %s" % bool(embedded)) self.notify.debug(" FULLSCREEN: %s" % bool(fullscreen)) self.notify.debug(" X SIZE: %s" % width) self.notify.debug(" Y SIZE: %s" % height) if ((self.current_pipe == pipe) and \ (bool(self.current_properties.getParentWindow( )) == bool(embedded)) and \ (self.current_properties.getFullscreen ( ) == fullscreen) and \ (self.current_properties.getXSize ( ) == width) and \ (self.current_properties.getYSize ( ) == height)): # no display change required self.notify.info("DISPLAY NO CHANGE REQUIRED") state = True else: properties = WindowProperties() properties.setSize(width, height) properties.setFullscreen(fullscreen) properties.setParentWindow(0) if embedded: if base.appRunner.windowProperties: properties = base.appRunner.windowProperties # get current sort order original_sort = base.win.getSort() if self.resetWindowProperties(pipe, properties): self.notify.debug("DISPLAY CHANGE SET") # verify display change properties = base.win.getProperties() self.notify.debug("DISPLAY ACHIEVED:") self.notify.debug(" EMBEDDED: %s" % bool(properties.getParentWindow())) self.notify.debug(" FULLSCREEN: %s" % bool(properties.getFullscreen())) self.notify.debug(" X SIZE: %s" % properties.getXSize()) self.notify.debug(" Y SIZE: %s" % properties.getYSize()) if ((bool(properties.getParentWindow( )) == bool(embedded)) and \ (properties.getFullscreen ( ) == fullscreen) and \ (properties.getXSize ( ) == width) and \ (properties.getYSize ( ) == height)): self.notify.info("DISPLAY CHANGE VERIFIED") state = True else: self.notify.warning( "DISPLAY CHANGE FAILED, RESTORING PREVIOUS DISPLAY") self.restoreWindowProperties() else: self.notify.warning("DISPLAY CHANGE FAILED") self.notify.warning("DISPLAY SET - BEFORE RESTORE") self.restoreWindowProperties() self.notify.warning("DISPLAY SET - AFTER RESTORE") # set current sort order base.win.setSort(original_sort) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() return state def resetWindowProperties(self, pipe, properties): if base.win: currentProperties = WindowProperties(base.win.getProperties()) gsg = base.win.getGsg() else: currentProperties = WindowProperties.getDefault() gsg = None # Check to see if the window properties will change in any # important way. newProperties = WindowProperties(currentProperties) newProperties.addProperties(properties) if base.pipe != pipe: gsg = None if (gsg == None) or \ (currentProperties.getFullscreen() != newProperties.getFullscreen()) or \ (currentProperties.getParentWindow() != newProperties.getParentWindow()): # For now, assume that if we change fullscreen state, we # need to destroy the window and create a new one. self.notify.debug("window properties: %s" % properties) self.notify.debug("gsg: %s" % gsg) base.pipe = pipe if not base.openMainWindow( props=properties, gsg=gsg, keepCamera=True): self.notify.warning("OPEN MAIN WINDOW FAILED") return 0 self.notify.info("OPEN MAIN WINDOW PASSED") base.graphicsEngine.openWindows() if base.win.isClosed(): self.notify.warning("Window did not open, removing.") base.closeWindow(base.win) return 0 base.disableShowbaseMouse() # If we've already imported (and therefore downloaded) # libotp.dll, then we already have a NametagGlobals, and # we should keep it up-to-date with the new MouseWatcher # etc. if 'libotp' in sys.modules: from libotp import NametagGlobals NametagGlobals.setCamera(base.cam) NametagGlobals.setMouseWatcher(base.mouseWatcherNode) else: # If the properties are changing only slightly # (e.g. window size), we can keep the current window and # just adjust its properties directly. self.notify.debug("Adjusting properties") base.win.requestProperties(properties) base.graphicsEngine.renderFrame() return 1 def restoreWindowProperties(self): if (self.resetWindowProperties(self.current_pipe, self.current_properties)): self.restore_failed = False else: # Oops, we couldn't get the original settings back! self.notify.warning("Couldn't restore original display settings!") if base.appRunner and base.appRunner.windowProperties: # Try to go back into embedded. That might help. fullscreen = 0 embedded = 1 tryProps = base.appRunner.windowProperties if (self.resetWindowProperties(self.current_pipe, tryProps)): self.current_properties = copy.copy(tryProps) self.restore_failed = False return if self.current_properties.getFullscreen(): # Try again without the fullscreen option. That might # help. fullscreen = 0 embedded = 0 tryProps = self.current_properties tryProps.setFullscreen(0) if (self.resetWindowProperties(self.current_pipe, tryProps)): self.current_properties = copy.copy(tryProps) self.restore_failed = False return # Couldn't even open a regular window. This is kind of # like a low-level panic situation. self.notify.error("Failed opening regular window!") base.panda3dRenderError() self.restore_failed = True return
def __init__(self): ShowBase.__init__(self) ########## Window configuration ######### wp = WindowProperties() wp.setSize(1024, 860) wp.setTitle("") wp.setOrigin(-2, -2) self.win.requestProperties(wp) self.win.movePointer(0, wp.getXSize() / 2, wp.getYSize() / 2) print wp.getXSize() / 2, wp.getYSize() / 2 ########## Gameplay settings ######### self.gameMode = {"display": PLAY, "play": TERRAIN} self.level = 1.5 self.mode_initialized = False ######### Camera ######### self.disableMouse() self.mainCamera = Camera(self.camera) self.mainCamera.camObject.setHpr(0, 0, 0) self.loadLevel() ######### Events ######### self.taskMgr.add(self.gameLoop, "gameLoop", priority=35) self.keys = {"w": 0, "s": 0, "a": 0, "d": 0, "space": 0, "escape": 0} self.accept("w", self.setKey, ["w", 1]) self.accept("w-up", self.setKey, ["w", 0]) self.accept("s", self.setKey, ["s", 1]) self.accept("s-up", self.setKey, ["s", 0]) self.accept("a", self.setKey, ["a", 1]) self.accept("a-up", self.setKey, ["a", 0]) self.accept("d", self.setKey, ["d", 1]) self.accept("d-up", self.setKey, ["d", 0]) self.accept("space", self.setKey, ["space", 1]) self.accept("space-up", self.setKey, ["space", 0]) self.accept("escape", self.setKey, ["escape", 1]) self.accept("escape-up", self.setKey, ["escape", 0]) self.accept("wheel_up", self.zoomCamera, [-1]) self.accept("wheel_down", self.zoomCamera, [1]) self.accept("window-event", self.handleWindowEvent) ######### GUI ######### #self.fonts = {"failure" : loader.loadFont('myfont.ttf')} self.guiElements = [] self._GCLK = None self._FT = None
class Game(ShowBase): def __init__(self): ShowBase.__init__(self) #start the time self.globalTime = 0 self.nextEnemy = 1 #setup your collision event handlers, apparently needs a direct object self.do = DirectObject() self.do.accept('unit-into-unit', self.handleUnitIntoCollision) self.do.accept('unit-out-unit', self.handleUnitOutCollision) self.do.accept('unit-into-cube', self.handleCubeIntoCollision) self.do.accept('unit-into-wing', self.handleWingIntoCollision) self.do.accept('unit-into-bar', self.handleBarIntoCollision) #get window properties self.winProps = WindowProperties() #self.winProps.setFullscreen(True) self.winProps.setCursorHidden(True) base.win.requestProperties(self.winProps) self.winProps = base.win.getProperties() self.screenHeight = self.winProps.getYSize() #set up the control scheme self.controlScheme = ControlScheme(base.mouseWatcherNode, base.win, \ [LEFT, RIGHT, UP, DOWN, PAUSE, PULL, PUSH, SWITCH, QUIT]) #disable the automatic task to move the camera #(this does not actually disable the mouse) base.disableMouse() #declare null values for variables, fill them in later self.environment = None self.player = None #a node for holding all in-game units self.unitNodePath = NodePath('unit holder') self.unitNodePath.reparentTo(self.render) #object lists self.enemies = [] self.obstacles = [] self.projectiles = [] #list of enemies to be spawned self.eSpawnList = [] #not paused by default self.paused = False self.pauseWasPressed = False #variables for tracking time self.previousFrameTime = 0 #start the collision traverser traverser = CollisionTraverser() base.cTrav = traverser#run every frame self.cTrav = base.cTrav #set the check for units accidentally passing through level geometry self.cTrav.setRespectPrevTransform(True) #self.cTrav.showCollisions(self.render) #self.cTrav.showCollisions(self.unitNodePath)#show the collisions #load terrain and enemies #load the environment, it seems that an x value of zero, a y value of -50 puts the origin point relatively in the middle of the crater filename = PARAMS_PATH + "environment.txt" self.loadLevelGeom(filename) #load the enemies filename = PARAMS_PATH + "enemies.txt" self.loadLevelEnemies(filename) #lookup table for actors self.actors = {} #place the player in the environment self.player = Player(self.controlScheme, self.camera, self, 0, 0, 0) self.player.setName("player") self.player.setH(180) self.player.reparentTo(self.unitNodePath) self.player.nodePath = self.render.find("player") self.actors["player"] = self.player #add some lights topLight = DirectionalLight("top light") topLight.setColor(Vec4(0.5, 0.5, 0.5, 1)) topLight.setDirection(Vec3(0, -90, 0)) self.render.setLight(self.render.attachNewNode(topLight)) ambientLight = AmbientLight("ambient light") ambientLight.setColor(Vec4(0.5, 0.5, 0.5, 1)) self.render.setLight(self.render.attachNewNode(ambientLight)) #the distance the camera is from the player self.cameraHOffset = 45 self.cameraVOffset = 10 #add the collision sound self.collisionSound = self.loader.loadSfx(SFX_PATH + "collide.wav") #register the update task self.taskMgr.add(self.updateGame, "updateGame") #add targeting to the world self.setupTargeting() #seed the random number generator random.seed() # configure the entire GUI self.setupGUI() # configure the title screen self.setupTitleScreen() def setupGUI(self): GUIFont = loader.loadFont(FONTS_PATH + 'orbitron-medium.ttf') """ self.debugText = TextNode('debug') self.debugText.setText("") self.debugText.setAlign(TextNode.ALeft) self.debugText.setFont(GUIFont) dTextNodePath = aspect2d.attachNewNode(self.debugText) dTextNodePath.setScale(0.075) dTextNodePath.setPos(-1.2, 0, -0.9) """ #INTRO self.introText = TextNode('intro') self.introText.setText("") self.introText.setAlign(TextNode.ALeft) self.introText.setFont(GUIFont) self.introText.setCardColor(0.1, 0.1, 0.1, 0.6) self.introText.setCardAsMargin(0.5, 0.5, 0.5, 0.5) self.introText.setCardDecal(True) self.introText.setWordwrap(30.0) self.iTextNodePath = aspect2d.attachNewNode(self.introText) self.iTextNodePath.setScale(0.06) self.iTextNodePath.setPos(-1.2, 0, -0.7) #image is 171 x 323 self.leftMouseImage = OnscreenImage() self.leftMouseImage.setImage(GUI_PATH + "mouse-icon-left.png") self.leftMouseImage.setTransparency(1) self.leftMousePath = aspect2d.attachNewNode(self.leftMouseImage.node()) self.rightMouseImage = OnscreenImage() self.rightMouseImage.setImage(GUI_PATH + "mouse-icon-right.png") self.rightMouseImage.setTransparency(1) self.rightMousePath = aspect2d.attachNewNode(self.rightMouseImage.node()) self.middleMouseImage = OnscreenImage() self.middleMouseImage.setImage(GUI_PATH + "mouse-icon-middle.png") self.middleMouseImage.setTransparency(1) self.middleMousePath = aspect2d.attachNewNode(self.middleMouseImage.node()) self.leftMousePath.setScale(.105882, 0, .2) self.leftMousePath.setPos(1.1, 0, -0.75) self.rightMousePath.setScale(.105882, 0, .2) self.rightMousePath.setPos(1.1, 0, -0.75) self.middleMousePath.setScale(.105882, 0, .2) self.middleMousePath.setPos(1.1, 0, -0.75) self.leftMousePath.hide() self.rightMousePath.hide() self.middleMousePath.hide() #HUD #image is 365 x 187 self.attackModeImage = OnscreenImage() self.attackModeImage.setImage(GUI_PATH + "mode-area.png") self.attackModeImage.setTransparency(1) modeNodePath = aspect2d.attachNewNode(self.attackModeImage.node()) modeNodePath.setScale(.136631, 0, .07) modeNodePath.setPos(-1.13, 0, 0.88) self.energyBarImage = OnscreenImage() self.energyBarImage.setImage(GUI_PATH + "energy-bar-full.png") self.energyBarImage.setTransparency(1) eBarNodePath = aspect2d.attachNewNode(self.energyBarImage.node()) eBarNodePath.setScale(.400, 0, .0475) eBarNodePath.setPos(-0.66, 0, 0.88) self.healthBarImage = OnscreenImage() self.healthBarImage.setImage(GUI_PATH + "health-bar-full.png") self.healthBarImage.setTransparency(1) hBarNodePath = aspect2d.attachNewNode(self.healthBarImage.node()) hBarNodePath.setScale(.400, 0, .0475) hBarNodePath.setPos(0.85, 0, 0.88) def setupTitleScreen(self): self.titleScreenIsActive = True #image is 800 x 600 self.titleImage = OnscreenImage() self.titleImage.setImage(GUI_PATH + "title.png") titleNodePath = aspect2d.attachNewNode(self.titleImage.node()) titleNodePath.setScale(1.33333, 0, 1) titleNodePath.setPos(0, 0, 0) def updateTitleScreen(self): if (self.controlScheme.keyDown(PUSH) or self.controlScheme.keyDown(PULL) or self.controlScheme.keyDown(SWITCH)) and self.titleScreenIsActive: self.titleImage.hide() self.titleScreenIsActive = False elif self.titleScreenIsActive: self.titleImage.setImage(GUI_PATH + "title.png") self.globalTime=0 else: pass def calculateBarImage(self, level): if level == 0: level = "empty" elif level == 10: level = "full" elif level == 1: level = "1" elif level == 2: level = "2" elif level == 3: level = "3" elif level == 4: level = "4" elif level == 5: level = "5" elif level == 6: level = "6" elif level == 7: level = "7" elif level == 8: level = "8" elif level == 9: level = "9" return level def updateGUI(self): """ self.debugText.setText("Energy: "+str((100*self.player.energy/self.player.maxEnergy))+"%, Health: "+str((100*self.player.health/self.player.maxHealth))) """ self.updateIntro() if self.player.currentWeapon == AREA: modeImg = "mode-area" elif self.player.currentWeapon == NARROW: modeImg = "mode-narrow" energyLevel = self.calculateBarImage((100 * (self.player.energy / self.player.maxEnergy)) // 10) self.energyBarImage.setImage(GUI_PATH + "energy-bar-" + energyLevel + ".png") self.energyBarImage.setTransparency(1) self.attackModeImage.setImage(GUI_PATH + modeImg + ".png") self.attackModeImage.setTransparency(1) healthLevel = self.calculateBarImage((100 * (self.player.health / self.player.maxHealth)) // 10) self.healthBarImage.setImage(GUI_PATH + "health-bar-" + healthLevel + ".png") self.healthBarImage.setTransparency(1) def updateIntro(self): modifiedTime = self.globalTime/5 if self.introText is None: pass elif modifiedTime>=14300 and self.introText is not None: self.iTextNodePath.removeNode() self.introText = None elif modifiedTime<300: #0-300 self.introText.setText("Hey are you receiving?") elif modifiedTime<800: #300-800 self.introText.setText("We recently uncovered the location of an old cruiser wreck from the war.") elif modifiedTime<1500: #800-1500 self.introText.setText("You're gonna go in there and get the little bits of it that are still worth salvaging.") elif modifiedTime<2900: #1500-2900 self.introText.setText("Be aware though, this job may not be quite as simple as a grab-and-run. The coordinates have been leaked to some of our old enemies.") elif modifiedTime<4200: #2900-4200 self.introText.setText("To give you an edge, we've made a few upgrades to your electromagnetic grapple.") elif modifiedTime<5300: #4200-5300 self.introText.setText("Pull enemies inwards with the right mouse button.") self.leftMousePath.hide() self.rightMousePath.show() self.middleMousePath.hide() elif modifiedTime<6400: #5300-6400 self.introText.setText("Push enemies away with the left mouse button.") self.leftMousePath.show() self.rightMousePath.hide() self.middleMousePath.hide() elif modifiedTime<8500: #6400-8500 self.introText.setText("Toggle between your range and narrow electromagnet with the middle mouse button (or spacebar).") self.leftMousePath.hide() self.rightMousePath.hide() self.middleMousePath.show() elif modifiedTime<13300: #8500-13300 self.introText.setText("You can give a solid kick to anything straight in front of you or just push everything around you away. Try and throw 'em into each other or other wreckage to finish 'em off for good.") self.leftMousePath.hide() self.rightMousePath.hide() self.middleMousePath.hide() elif modifiedTime<14300: #13300-14300 self.introText.setText("After all, the more salvage left over, the better. Out.") def loadLevelGeom(self, filename): filename = os.path.abspath(filename) if not os.path.isfile(filename): print "FILE DOES NOT EXIST:" exit(1) #get the lines from the file textFileList = open(filename, 'r').readlines() if len(textFileList) < 1: print "FATAL ERROR READING FILE" exit(1) #now split each line into lists for num, val in enumerate(textFileList): val = val.rstrip('\n')#strip the newlines val = val.strip() textFileList[num] = val.split(TEXT_DELIMITER) obstacle = None for list in textFileList: #go through the list if list[0] == TERRAIN_OUTER:#do all the things for the terrain #choose the model modelVal = list[1] modelVal = (MODELS_PATH + modelVal) self.environment = self.loader.loadModel(modelVal) self.environment.reparentTo(self.render) #get the collision geometry for the environment #and move it up a bit to allow the character to float above the crater self.craterCollision = self.environment.find("**/craterCollisionPlane") self.craterCollision.setZ(self.environment.getZ() + 0.15) self.environment.setCollideMask(BitMask32.allOff()) self.craterCollision.setCollideMask(BitMask32(TERRAIN_RAY_MASK)) #self.environment.find( #.find("craterCollisionPlane").setZ(self.environment.getZ() + 10) #set scale scaleVal = list[2].split(',')#split by commas self.environment.setScale(float(scaleVal[0]), float(scaleVal[1]), float(scaleVal[2])) #set location locVal = list[3].split(',') self.environment.setPos(float(locVal[0]), float(locVal[1]), float(locVal[2]))#then we have our terrain #set rotation hprVal = list[4].split(',') self.environment.setHpr(float(hprVal[0]), float(hprVal[1]), float(hprVal[2])) elif list[0] == TERRAIN_CUBE: #choose the model modelVal = list[1] modelVal = (MODELS_PATH + modelVal) #load the model obstacle = self.loader.loadModel(modelVal) obstacle.reparentTo(render) #set scale scaleVal = list[2].split(',') obstacle.setScale(float(scaleVal[0]), float(scaleVal[1]), float(scaleVal[2])) #set location locVal = list[3].split(',') obstacle.setPos(float(locVal[0]), float(locVal[1]), float(locVal[2]))#the we have our object hprVal = list[4].split(',') obstacle.setHpr(float(hprVal[0]), float(hprVal[1]), float(hprVal[2])) #set up collisions unitCollision = obstacle.find("**/CubeBlock") unitCollision.node().setName("cube") obstacle.setCollideMask(BitMask32.allOff()) unitCollision.setCollideMask(BitMask32(PLAYER_ENEMY_OBJECTS)) self.obstacles.append(obstacle) elif list[0] == TERRAIN_WING: modelVal = list[1] modelVal = (MODELS_PATH + modelVal) #load the model obstacle = self.loader.loadModel(modelVal) obstacle.reparentTo(render) #set scale scaleVal = list[2].split(',') obstacle.setScale(float(scaleVal[0]), float(scaleVal[1]), float(scaleVal[2])) #set location locVal = list[3].split(',') obstacle.setPos(float(locVal[0]), float(locVal[1]), float(locVal[2]))#the we have our object hprVal = list[4].split(',') obstacle.setHpr(float(hprVal[0]), float(hprVal[1]), float(hprVal[2])) #set up collisions unitCollision = obstacle.find("**/wingCollider") unitCollision.node().setName("wing") obstacle.setCollideMask(BitMask32.allOff()) unitCollision.setCollideMask(BitMask32(PLAYER_ENEMY_OBJECTS)) self.obstacles.append(obstacle) elif list[0] == TERRAIN_BAR: modelVal = list[1] modelVal = (MODELS_PATH + modelVal) #load the model obstacle = self.loader.loadModel(modelVal) obstacle.reparentTo(render) #set scale scaleVal = list[2].split(',') obstacle.setScale(float(scaleVal[0]), float(scaleVal[1]), float(scaleVal[2])) #set location locVal = list[3].split(',') obstacle.setPos(float(locVal[0]), float(locVal[1]), float(locVal[2]))#the we have our object hprVal = list[4].split(',') obstacle.setHpr(float(hprVal[0]), float(hprVal[1]), float(hprVal[2])) #set up collisions unitCollision = obstacle.find("**/metalBarCollisionCube") unitCollision.node().setName("bar") obstacle.setCollideMask(BitMask32.allOff()) unitCollision.setCollideMask(BitMask32(PLAYER_ENEMY_OBJECTS)) elif list[0] == TERRAIN_SHARDS: modelVal = list[1] modelVal = (MODELS_PATH + modelVal) #load the model obstacle = self.loader.loadModel(modelVal) obstacle.reparentTo(render) #set scale scaleVal = list[2].split(',') obstacle.setScale(float(scaleVal[0]), float(scaleVal[1]), float(scaleVal[2])) #set location locVal = list[3].split(',') obstacle.setPos(float(locVal[0]), float(locVal[1]), float(locVal[2]))#the we have our object hprVal = list[4].split(',') obstacle.setHpr(float(hprVal[0]), float(hprVal[1]), float(hprVal[2])) #set up collisions unitCollision = obstacle.find("**/metalShardCollisionCube") unitCollision.node().setName("shard") obstacle.setCollideMask(BitMask32.allOff()) unitCollision.setCollideMask(BitMask32(PLAYER_ENEMY_OBJECTS)) else: print "FATAL ERROR READING FILE" exit(1) pass def loadLevelEnemies(self, filename): filename = os.path.abspath(filename) if not os.path.isfile(filename): print "FILE DOES NOT EXIST:" exit(1) #get the lines from the file and split them textFileList = open(filename, 'r').readlines() if len(textFileList) < 1: print "FATAL ERROR READING FILE" exit(1) for num, val in enumerate(textFileList): val = val.rstrip('\n')#strip the newlines val = val.strip() textFileList[num] = val.split(TEXT_DELIMITER) currwave = dict() currwave["time"] = None currwave["enemies"] = [] currEnem = dict() for val in textFileList: if val[0] == BEGIN_WAVE: currwave = dict() currwave["time"] = float(val[1])#set your time currwave["enemies"] = [] elif val[0] == RUSH_ENEMY: currEnem = dict() pos = [] pos = val[1].split(',')#get the three values for spawning, not floats currEnem["type"] = RUSH_ENEMY currEnem["xVal"] = float(pos[0]) currEnem["yVal"] = float(pos[1]) currEnem["zVal"] = float(pos[2]) currwave["enemies"].append(dict(currEnem))#copy elif val[0] == DRONE_ENEMY: currEnem = dict() pos = [] pos = val[1].split(',')#get the three values for spawning, not floats currEnem["type"] = DRONE_ENEMY currEnem["xVal"] = float(pos[0]) currEnem["yVal"] = float(pos[1]) currEnem["zVal"] = float(pos[2]) currwave["enemies"].append(dict(currEnem))#copy elif val[0] == SHOOTING_ENEMY: currEnem = dict() pos = [] pos = val[1].split(',')#get the three values for spawning, not floats currEnem["type"] = SHOOTING_ENEMY currEnem["xVal"] = float(pos[0]) currEnem["yVal"] = float(pos[1]) currEnem["zVal"] = float(pos[2]) currwave["enemies"].append(dict(currEnem))#copy elif val[0] == END_WAVE:#then we are done with that wave self.eSpawnList.append(dict(currwave))#copy else: pass#then something was stupid #now sort your waves with lowest time first self.eSpawnList.sort(key = lambda object: object["time"]) #and you're done def updateGame(self, task): if not self.titleScreenIsActive: self.globalTime = self.globalTime + task.time elapsedTime = task.time - self.previousFrameTime #base.resetPrevTransform(render)#for our high intensity collision detection if self.controlScheme.keyDown(QUIT): exit(0) if not self.paused and not self.titleScreenIsActive: time = elapsedTime while time > 0.02: self.updateGameComponents(0.02) time -= 0.02 self.updateGameComponents(time) self.cTrav.traverse(render) self.spawnEnemies()#globalTime is available if self.controlScheme.keyDown(PAUSE): if not self.pauseWasPressed: self.paused = not self.paused self.controlScheme.resetMouse() self.pauseWasPressed = True else: self.pauseWasPressed = False self.updateGUI() self.updateTitleScreen() self.previousFrameTime = task.time return task.cont def updateGameComponents(self, time): ''' Updates the state of the world. @precondition: The game isn't paused. ''' self.updateCamera(time) for enemy in self.enemies: enemy.update(time) for projectile in self.projectiles: projectile.update(time) #check for basic terrain collisions self.player.terrainCollisionCheck() self.player.update(time) for enemy in self.enemies: enemy.terrainCollisionCheck() for projectile in self.projectiles: projectile.terrainCollisionCheck() def spawnEnemies(self):#now we spawn our enemies while((len(self.eSpawnList) > 0) and self.eSpawnList[0]["time"] < self.globalTime): for val in self.eSpawnList[0]["enemies"]: if val["type"] == RUSH_ENEMY: #add an enemy tempEnemy = RushEnemy(self, val["xVal"], val["yVal"], val["zVal"]) self.configureEnemy(tempEnemy) elif val["type"] == DRONE_ENEMY: #add an enemy tempEnemy = DroneEnemy(self, self.player, val["xVal"], val["yVal"], val["zVal"]) self.configureEnemy(tempEnemy) elif val["type"] == SHOOTING_ENEMY: #add an enemy tempEnemy = ShootingEnemy(self, val["xVal"], val["yVal"], val["zVal"]) self.configureEnemy(tempEnemy) else: pass del self.eSpawnList[0]#del def configureEnemy(self, tempEnemy):#after making an enemy configure it for the game numString = str(self.nextEnemy) tempEnemy.setName("enemy" + numString) tempEnemy.reparentTo(self.unitNodePath) tempEnemy.nodePath = self.render.find("enemy1") self.actors["enemy" + numString] = tempEnemy self.nextEnemy = self.nextEnemy + 1 self.enemies.append(tempEnemy) def rotateCamera(self): if self.controlScheme.mouseX > self.winProps.getXSize(): self.camera.setH(-(self.winProps.getXSize() - 20) * 0.5) else: self.camera.setH(-self.controlScheme.mouseX * 0.5) def updateCamera(self, elapsedTime): #update the camera's heading based on the mouse's x position if self.controlScheme.recheckMouse(): self.camera.setH(-self.controlScheme.mouseX * 0.5) else: self.rotateCamera() #update the camera's pitch and vertical position based on the mouse's y position self.cameraVOffset = min(self.screenHeight, max(0, self.controlScheme.mouseY)) / self.screenHeight * 25 + 4 self.cameraHOffset = self.cameraVOffset * 0.8 + 30 self.camera.setP(atan2(-self.cameraVOffset * 0.7, self.cameraHOffset) \ * 180 / pi) #update the camera to point at the player self.camera.setPos(self.player.getX() + self.cameraHOffset * sin(self.camera.getH() * pi / 180), self.player.getY() - self.cameraHOffset * cos(self.camera.getH() * pi / 180), self.player.getZ() + 0.3 + self.cameraVOffset) def selectTarget(self): """Finds the closest shootable object and returns it""" #traverse all objects in render self.mPickerTraverser.traverse(self.unitNodePath) if (self.mCollisionQue.getNumEntries() > 0): self.mCollisionQue.sortEntries() for i in range(0, self.mCollisionQue.getNumEntries()): entry = self.mCollisionQue.getEntry(i) pickedObj = entry.getIntoNodePath() if not pickedObj.isEmpty(): name = pickedObj.getParent().getName() if name == "render": return None #if the object is shootable, set it as the target try: if self.actors[name].shootable: return self.actors[name] except: continue return None def setupTargeting(self): """Set up the collisions necessary to target enemies and other objects""" #Since we are using collision detection to do picking, we set it up #any other collision detection system with a traverser and a handler self.mPickerTraverser = CollisionTraverser() #Make a traverser #self.mPickerTraverser.showCollisions(self.unitNodePath) self.mCollisionQue = CollisionHandlerQueue() #create a collision solid ray to detect against self.mPickRay = CollisionRay() self.mPickRay.setOrigin(self.player.getPos(self.render)) self.mPickRay.setDirection(self.render.getRelativeVector(self.player, Vec3(0, 1, 0))) self.mPickRay2 = CollisionRay() self.mPickRay2.setOrigin(self.player.getPos(self.render)) self.mPickRay2.setDirection(self.render.getRelativeVector(self.player, Vec3(0.06, 1, 0))) self.mPickRay3 = CollisionRay() self.mPickRay3.setOrigin(self.player.getPos(self.render)) self.mPickRay3.setDirection(self.render.getRelativeVector(self.player, Vec3(-0.06, 1, 0))) self.mPickRay4 = CollisionRay() self.mPickRay4.setOrigin(self.player.getPos(self.render)) self.mPickRay4.setDirection(self.render.getRelativeVector(self.player, Vec3(0, 1, 0.06))) self.mPickRay5 = CollisionRay() self.mPickRay5.setOrigin(self.player.getPos(self.render)) self.mPickRay5.setDirection(self.render.getRelativeVector(self.player, Vec3(0, 1, -0.06))) #create our collison Node to hold the ray self.mPickNode = CollisionNode('pickRay') self.mPickNode.setIntoCollideMask(BitMask32.allOff()) self.mPickNode.addSolid(self.mPickRay) self.mPickNode2 = CollisionNode('pickRay2') self.mPickNode2.setIntoCollideMask(BitMask32.allOff()) self.mPickNode2.addSolid(self.mPickRay2) self.mPickNode3 = CollisionNode('pickRay3') self.mPickNode3.setIntoCollideMask(BitMask32.allOff()) self.mPickNode3.addSolid(self.mPickRay3) self.mPickNode4 = CollisionNode('pickRay4') self.mPickNode4.setIntoCollideMask(BitMask32.allOff()) self.mPickNode4.addSolid(self.mPickRay4) self.mPickNode5 = CollisionNode('pickRay5') self.mPickNode5.setIntoCollideMask(BitMask32.allOff()) self.mPickNode5.addSolid(self.mPickRay5) #Attach that node to the player since the ray will need to be positioned #relative to it, returns a new nodepath #well use the default geometry mask #this is inefficent but its for mouse picking only self.mPickNP = self.player.attachNewNode(self.mPickNode) self.mPickNP2 = self.player.attachNewNode(self.mPickNode2) self.mPickNP3 = self.player.attachNewNode(self.mPickNode3) self.mPickNP4 = self.player.attachNewNode(self.mPickNode4) self.mPickNP5 = self.player.attachNewNode(self.mPickNode5) #well use what panda calls the "from" node. This is really a silly convention #but from nodes are nodes that are active, while into nodes are usually passive environments #this isnt a hard rule, but following it usually reduces processing #Everything to be picked will use bit 1. This way if we were doing other #collision we could seperate it, we use bitmasks to determine what we check other objects against #if they dont have a bitmask for bit 1 well skip them! #self.mPickNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.mPickNode.setFromCollideMask(PLAYER_ENEMY_OBJECTS) self.mPickNode2.setFromCollideMask(PLAYER_ENEMY_OBJECTS) self.mPickNode3.setFromCollideMask(PLAYER_ENEMY_OBJECTS) self.mPickNode4.setFromCollideMask(PLAYER_ENEMY_OBJECTS) self.mPickNode5.setFromCollideMask(PLAYER_ENEMY_OBJECTS) #Register the ray as something that can cause collisions self.mPickerTraverser.addCollider(self.mPickNP, self.mCollisionQue) self.mPickerTraverser.addCollider(self.mPickNP2, self.mCollisionQue) self.mPickerTraverser.addCollider(self.mPickNP3, self.mCollisionQue) self.mPickerTraverser.addCollider(self.mPickNP4, self.mCollisionQue) self.mPickerTraverser.addCollider(self.mPickNP5, self.mCollisionQue) def handleUnitIntoCollision(self, entry): try: fromName = entry.getFromNodePath().getParent().getName() intoName = entry.getIntoNodePath().getParent().getName() Unit.collideWithUnit(self.actors[intoName], self.actors[fromName]) if (fromName == "player" or intoName == "player") and self.collisionSound.status() is not self.collisionSound.PLAYING: self.collisionSound.play() except: pass def handleUnitOutCollision(self, entry): pass def handleWingIntoCollision(self, entry): fromName = entry.getFromNodePath().getParent().getName() Unit.collideWithObstacle(self.actors[fromName]) if fromName == "player" and self.collisionSound.status() is not self.collisionSound.PLAYING: self.collisionSound.play() def handleCubeIntoCollision(self, entry): try: fromName = entry.getFromNodePath().getParent().getName() Unit.collideWithObstacle(self.actors[fromName]) if fromName == "player" and self.collisionSound.status() is not self.collisionSound.PLAYING: self.collisionSound.play() except: pass def handleBarIntoCollision(self, entry): fromName = entry.getFromNodePath().getParent().getName() Unit.collideWithObstacle(self.actors[fromName]) if fromName == "player" and self.collisionSound.status() is not self.collisionSound.PLAYING: self.collisionSound.play() def gameOver(self): pass