def clear(self,fadeout = 0,bgfile = None): self.clearQuickItems() if not fadeout: self.itemEntries.clear() self.reload() else: dr = self.camera.node().getDisplayRegion(0) texture = dr.getScreenshot() w = dr.getPixelWidth() h = dr.getPixelHeight() self.itemEntries.clear() self.reload() if bgfile: bgentry = StoryViewItemEntry(fileName = bgfile,key = '__bg__',category = SVIC.BG) self.newItem(bgentry) tempbg = OnscreenImage(texture) if w > h: tempbg.setScale(1*w/float(h),1,1) else: tempbg.setScale(1,1,1*h/float(w)) tempbg.setColor(1,1,1,1) tempbg.reparentTo(self.bgNodePath) tempbg.setName('__tempbg__') li = LerpColorInterval(tempbg, fadeout, (1,1,1,0), (1,1,1,1),blendType = 'easeInOut' ) self._intervals.append(li) li.start()
class HUD(HasFrame): def __init__(self): HasFrame.__init__(self, 2) self.crosshair = OnscreenImage('gui/crosshair.png', pos=(0, 0, 0), scale=0.03, parent=self.frame) self.crosshair.setTransparency(1) self.crosshair.setColor(1, 1, 1, 0.7)
class MainMenu(DirectObject): def __init__(self, skipIntro=False): render.show() engine.Mouse.showCursor() # In case we just got back from the tutorial, which hides everything # sometimes. engine.renderLit.show() self.backgroundSound = audio.FlatSound("menu/background.ogg", volume=0.3) self.backgroundSound.setVolume(0) self.backgroundSound.setLoop(True) self.clickSound = audio.FlatSound("menu/click.ogg", volume=0.3) self.active = True self.accept("escape", self.escape) self.accept("mouse1", self.click) self.cameraDistance = 20 self.globe = engine.loadModel("menu/Globe") self.globe.reparentTo(render) self.globe.setTransparency(TransparencyAttrib.MAlpha) self.globe.setColor(Vec4(1, 1, 1, 0.6)) self.globe.setTwoSided(True) self.globe.setRenderModeWireframe() self.overlay = camera.attachNewNode("overlay") self.overlay.setTransparency(TransparencyAttrib.MAlpha) self.overlay.setColor(Vec4(1, 1, 1, 0)) self.overlay.setPos(0, 0, 0) self.overlay.setPos(0, self.cameraDistance, 0) self.overlay1 = engine.loadModel("menu/overlay1") self.overlay1.setScale(4) self.overlay1.setTwoSided(True) self.overlay1.setRenderModeWireframe() self.overlay1.reparentTo(self.overlay) self.overlay2 = engine.loadModel("menu/overlay2") self.overlay2.setScale(4) self.overlay2.setTwoSided(True) self.overlay2.setRenderModeWireframe() self.overlay2.reparentTo(self.overlay) self.overlay3 = engine.loadModel("menu/overlay3") self.overlay3.setScale(4) self.overlay3.setTwoSided(True) self.overlay3.setRenderModeWireframe() self.overlay3.setR(uniform(0, 360)) self.overlay3.setP(uniform(0, 360)) self.overlay3.setH(uniform(0, 360)) self.overlay3.reparentTo(self.overlay) self.overlay4 = engine.loadModel("menu/overlay3") self.overlay4.setScale(4) self.overlay4.setTwoSided(True) self.overlay4.setRenderModeWireframe() self.overlay4.setH(uniform(0, 360)) self.overlay4.setR(uniform(0, 360)) self.overlay4.setP(uniform(0, 360)) self.overlay4.reparentTo(self.overlay) self.text = engine.loadModel("menu/text") self.text.setScale(4) self.text.setTwoSided(True) self.text.reparentTo(self.overlay) self.selector = engine.loadModel("menu/selector") self.selector.setScale(4) self.selector.setTwoSided(True) self.selector.reparentTo(self.overlay) self.selectedItem = 0 self.skyBox = engine.loadModel("menu/skybox") self.skyBox.setScale(self.cameraDistance * 5) self.skyBox.setRenderModeWireframe() self.skyBox.setTwoSided(True) self.skyBox.reparentTo(render) self.skyBox.setTransparency(TransparencyAttrib.MAlpha) self.skyBox.setColor(Vec4(1, 1, 1, 0)) cmbg = CardMaker("background") size = 10 cmbg.setFrame(-size * engine.aspectRatio, size * engine.aspectRatio, -size, size) self.background = camera.attachNewNode(cmbg.generate()) self.background.setTexture(loader.loadTexture("menu/background.jpg"), 1) self.background.setPos(0, size * 1.25, 0) self.background.setDepthWrite(False) self.belt = JunkBelt(5) self.angle = uniform(0, 360) self.period = 60 self.uiAngle = 0 self.logo = OnscreenImage(image="menu/logo.png", pos=(0, 0, 0), scale=((512.0 / 175.0) * 0.075, 0, 0.075)) self.logo.setTransparency(TransparencyAttrib.MAlpha) self.logo.setColor(1, 1, 1, 0) self.logo.setBin("transparent", 0) self.loadingScreen = OnscreenImage(image="menu/loading.jpg", pos=(0, 0, 0)) self.loadingScreen.setScale(render2d, VBase3(1)) self.loadingScreen.setSx(2) self.loadingScreen.hide() self.skipToEndOfTutorial = skipIntro global firstBoot firstBoot = False self.introTime = 2 if firstBoot and not skipIntro: self.introTime = 4 self.showLogin = firstBoot self.hostList = ui.HostList(self.startClient) self.mapList = ui.MapList(self.startServer) self.loginDialog = ui.LoginDialog(self.setUsername) self.loginDialogShown = False self.introSound = audio.FlatSound("menu/intro.ogg", volume=0.15) self.introSound.play() self.clientConnectAddress = None self.serverMapName = None self.serverMode = 0 # 0 for normal, 1 for tutorial self.serverGameType = 0 # 0 for deathmatch, 1 for survival self.username = "******" self.startTime = -1 self.goTime = -1 if base.appRunner is not None: token = base.appRunner.getToken("username") if token != "" and token != "Unnamed": self.setUsername(token) self.loginDialogShown = True def escape(self): if self.hostList.visible: self.hostList.hide() elif self.mapList.visible: self.mapList.hide() def startClient(self, host): self.clickSound.play() self.hostList.hide() self.loadingScreen.show() self.clientConnectAddress = host self.goTime = engine.clock.time def startServer(self, map, gametype): # Tutorial works on Point Control maps. if not (self.serverMode == 1 and gametype == 1): self.clickSound.play() self.mapList.hide() self.loadingScreen.show() self.serverMapName = map self.serverGameType = gametype self.goTime = engine.clock.time def setUsername(self, username): self.clickSound.play() self.username = username engine.savedUsername = self.username engine.saveConfigFile() self.loginDialog.hide() def update(self): if not self.active: return net.context.readTick() if self.startTime == -1: self.startTime = engine.clock.time elapsedTime = engine.clock.time - self.startTime if elapsedTime < self.introTime: blend = elapsedTime / self.introTime self.angle += engine.clock.timeStep * (1 - blend) self.cameraDistance = 20 + (1 - blend)**2 * 200 elif elapsedTime < self.introTime + 2: self.cameraDistance = 20 blend = (elapsedTime - self.introTime) / 2 self.overlay.setColor(Vec4(1, 1, 1, blend)) self.logo.setColor(1, 1, 1, blend) self.skyBox.setColor(Vec4(1, 1, 1, blend)) if not self.backgroundSound.isPlaying(): self.backgroundSound.play() self.backgroundSound.setVolume(blend * 0.5) else: self.cameraDistance = 20 self.overlay.setColor(Vec4(1, 1, 1, 1)) self.logo.setColor(1, 1, 1, 1) self.skyBox.setColor(Vec4(1, 1, 1, 1)) self.backgroundSound.setVolume(0.5) if elapsedTime > self.introTime: if not self.loginDialogShown and self.showLogin: self.loginDialog.show() self.loginDialogShown = True self.uiAngle -= engine.clock.timeStep * 2 self.text.setR(self.uiAngle) self.hostList.update() self.mapList.update() self.loginDialog.update() mouse = base.win.getPointer(0) props = base.win.getProperties() vector = Vec3((mouse.getX() / float(props.getXSize())) - 0.5, (mouse.getY() / float(props.getYSize())) - 0.5, 0) vector.normalize() angle = math.degrees(math.atan2(-vector.getX(), vector.getY())) + 180 angle -= self.uiAngle if not self.hostList.visible and not self.mapList.visible and not self.loginDialog.visible: self.selectedItem = int(round(angle / 90.0)) while self.selectedItem > 3: self.selectedItem -= 4 while self.selectedItem < 0: self.selectedItem += 4 self.selector.setR(self.uiAngle + self.selectedItem * 90) self.overlay1.setR(self.overlay1.getR() - engine.clock.timeStep * 2) self.overlay2.setR(self.overlay2.getR() + engine.clock.timeStep * 2) self.overlay3.setH(self.overlay3.getH() + engine.clock.timeStep * 10) self.overlay4.setP(self.overlay4.getP() - engine.clock.timeStep * 10) self.belt.update() self.angle += engine.clock.timeStep * 0.025 camera.setPos( math.cos(self.angle) * self.cameraDistance, math.sin(self.angle) * self.cameraDistance, math.cos(elapsedTime / 45 + 2) * 2) camera.lookAt(Point3(0, 0, 0)) backend = None game = None if self.goTime != -1 and engine.clock.time - self.goTime > 0.25: if self.clientConnectAddress is not None: self.delete() online.connectTo(self.clientConnectAddress) backend = ClientBackend(self.clientConnectAddress, self.username) game = Game(backend) elif self.serverMapName is not None: if self.serverMode == 0: # Normal server mode self.delete() if self.serverGameType == 0: backend = PointControlBackend( True, self.username) # Deathmatch else: backend = SurvivalBackend(True, self.username) # Survival game = Game(backend) game.localStart(self.serverMapName) elif self.serverMode == 1: # Tutorial mode self.delete() backend = PointControlBackend(False, self.username) game = Tutorial(backend, 2 if self.skipToEndOfTutorial else 0) game.localStart(self.serverMapName) net.context.writeTick() return backend, game def click(self): if self.mapList.visible or self.hostList.visible or self.loginDialog.visible or engine.clock.time - \ self.startTime < self.introTime + 0.5: return self.clickSound.play() if self.selectedItem == 0: # Join self.hostList.show() elif self.selectedItem == 1: # Tutorial self.mapList.show() self.serverMode = 1 elif self.selectedItem == 2: # Exit engine.exit() elif self.selectedItem == 3: # Host self.mapList.show() self.serverMode = 0 def delete(self): self.loadingScreen.destroy() self.hostList.delete() self.mapList.delete() self.loginDialog.delete() self.active = False self.overlay.removeNode() self.belt.delete() self.background.removeNode() self.globe.removeNode() self.skyBox.removeNode() self.ignoreAll() self.logo.destroy() self.introSound.stop() self.backgroundSound.stop()
class EngineCore(ShowBase.ShowBase): DEBUG = False loadPrcFileData("", "window-title {}".format(EDITION)) loadPrcFileData("", "framebuffer-multisample 1") loadPrcFileData("", "multisamples 8") loadPrcFileData("", 'bullet-filter-algorithm groups-mask') loadPrcFileData("", "audio-library-name null") loadPrcFileData("", "model-cache-compressed-textures 1") # loadPrcFileData("", "transform-cache 0") # loadPrcFileData("", "state-cache 0") loadPrcFileData("", "garbage-collect-states 0") # loadPrcFileData("", " framebuffer-srgb truein") # loadPrcFileData("", "geom-cache-size 50000") # v-sync, it seems useless # loadPrcFileData("", "sync-video 1") # for debug use # loadPrcFileData("", "gl-version 3 2") def __init__(self, global_config): self.global_config = global_config if self.global_config["pstats"]: # pstats debug provided by panda3d loadPrcFileData("", "want-pstats 1") loadPrcFileData( "", "win-size {} {}".format(*self.global_config["window_size"])) # Setup onscreen render if self.global_config["use_render"]: self.mode = RENDER_MODE_ONSCREEN # Warning it may cause memory leak, Pand3d Official has fixed this in their master branch. # You can enable it if your panda version is latest. loadPrcFileData( "", "threading-model Cull/Draw" ) # multi-thread render, accelerate simulation when evaluate else: if self.global_config["offscreen_render"]: self.mode = RENDER_MODE_OFFSCREEN loadPrcFileData("", "threading-model Cull/Draw") else: self.mode = RENDER_MODE_NONE if is_mac() and (self.mode == RENDER_MODE_OFFSCREEN ): # Mac don't support offscreen rendering self.mode = RENDER_MODE_ONSCREEN # Setup some debug options if self.global_config["headless_machine_render"]: # headless machine support loadPrcFileData("", "load-display pandagles2") if self.global_config["debug"]: # debug setting EngineCore.DEBUG = True _free_warning() setup_logger(debug=True) self.accept('1', self.toggleDebug) self.accept('2', self.toggleWireframe) self.accept('3', self.toggleTexture) self.accept('4', self.toggleAnalyze) else: # only report fatal error when debug is False _suppress_warning() # a special debug mode if self.global_config["debug_physics_world"]: self.accept('1', self.toggleDebug) self.accept('4', self.toggleAnalyze) super(EngineCore, self).__init__(windowType=self.mode) # Change window size at runtime if screen too small # assert int(self.global_config["use_topdown"]) + int(self.global_config["offscreen_render"]) <= 1, ( # "Only one of use_topdown and offscreen_render options can be selected." # ) # main_window_position = (0, 0) if self.mode == RENDER_MODE_ONSCREEN: if self.global_config["fast"]: pass else: loadPrcFileData("", "compressed-textures 1") # Default to compress h = self.pipe.getDisplayHeight() w = self.pipe.getDisplayWidth() if self.global_config["window_size"][ 0] > 0.9 * w or self.global_config["window_size"][ 1] > 0.9 * h: old_scale = self.global_config["window_size"][ 0] / self.global_config["window_size"][1] new_w = int(min(0.9 * w, 0.9 * h * old_scale)) new_h = int(min(0.9 * h, 0.9 * w / old_scale)) self.global_config["window_size"] = tuple([new_w, new_h]) from panda3d.core import WindowProperties props = WindowProperties() props.setSize(self.global_config["window_size"][0], self.global_config["window_size"][1]) self.win.requestProperties(props) logging.warning( "Since your screen is too small ({}, {}), we resize the window to {}." .format(w, h, self.global_config["window_size"])) # main_window_position = ( # (w - self.global_config["window_size"][0]) / 2, (h - self.global_config["window_size"][1]) / 2 # ) # self.highway_render = None # if self.global_config["use_topdown"]: # self.highway_render = HighwayRender(self.global_config["use_render"], main_window_position) # screen scale factor self.w_scale = max( self.global_config["window_size"][0] / self.global_config["window_size"][1], 1) self.h_scale = max( self.global_config["window_size"][1] / self.global_config["window_size"][0], 1) if self.mode == RENDER_MODE_ONSCREEN: self.disableMouse() if not self.global_config["debug_physics_world"] and (self.mode in [ RENDER_MODE_ONSCREEN, RENDER_MODE_OFFSCREEN ]): initialize_asset_loader(self) gltf.patch_loader(self.loader) # Display logo if self.mode == RENDER_MODE_ONSCREEN and (not self.global_config["debug"]) \ and (not self.global_config["fast"]): self._loading_logo = OnscreenImage( image=AssetLoader.file_path("PGDrive-large.png"), pos=(0, 0, 0), scale=(self.w_scale, 1, self.h_scale)) self._loading_logo.setTransparency(True) for i in range(20): self.graphicsEngine.renderFrame() self.taskMgr.add(self.remove_logo, "remove _loading_logo in first frame") self.closed = False # add element to render and pbr render, if is exists all the time. # these element will not be removed when clear_world() is called self.pbr_render = self.render.attachNewNode("pbrNP") # attach node to this root root whose children nodes will be clear after calling clear_world() self.worldNP = self.render.attachNewNode("world_np") # same as worldNP, but this node is only used for render gltf model with pbr material self.pbr_worldNP = self.pbr_render.attachNewNode("pbrNP") self.debug_node = None # some render attribute self.pbrpipe = None self.world_light = None # physics world self.physics_world = PhysicsWorld( self.global_config["debug_static_world"]) # collision callback self.physics_world.dynamic_world.setContactAddedCallback( PythonCallbackObject(collision_callback)) # for real time simulation self.force_fps = ForceFPS(self, start=True) # init terrain self.terrain = Terrain() self.terrain.attach_to_world(self.render, self.physics_world) # init other world elements if self.mode != RENDER_MODE_NONE: from pgdrive.engine.core.our_pbr import OurPipeline self.pbrpipe = OurPipeline(render_node=None, window=None, camera_node=None, msaa_samples=4, max_lights=8, use_normal_maps=False, use_emission_maps=True, exposure=1.0, enable_shadows=False, enable_fog=False, use_occlusion_maps=False) self.pbrpipe.render_node = self.pbr_render self.pbrpipe.render_node.set_antialias(AntialiasAttrib.M_auto) self.pbrpipe._recompile_pbr() self.pbrpipe.manager.cleanup() # set main cam self.cam.node().setCameraMask(CamMask.MainCam) self.cam.node().getDisplayRegion(0).setClearColorActive(True) self.cam.node().getDisplayRegion(0).setClearColor(BKG_COLOR) lens = self.cam.node().getLens() lens.setFov(70) lens.setAspectRatio(1.2) self.sky_box = SkyBox() self.sky_box.attach_to_world(self.render, self.physics_world) self.world_light = Light(self.global_config) self.world_light.attach_to_world(self.render, self.physics_world) self.render.setLight(self.world_light.direction_np) self.render.setLight(self.world_light.ambient_np) self.render.setShaderAuto() self.render.setAntialias(AntialiasAttrib.MAuto) # ui and render property if self.global_config["show_fps"]: self.setFrameRateMeter(True) # onscreen message self.on_screen_message = ScreenMessage( debug=self.DEBUG ) if self.mode == RENDER_MODE_ONSCREEN and self.global_config[ "onscreen_message"] else None self._show_help_message = False self._episode_start_time = time.time() self.accept("h", self.toggle_help_message) self.accept("f", self.force_fps.toggle) else: self.on_screen_message = None # task manager self.taskMgr.remove('audioLoop') def render_frame(self, text: Optional[Union[dict, str]] = None): """ The real rendering is conducted by the igLoop task maintained by panda3d. Frame will be drawn and refresh, when taskMgr.step() is called. This function is only used to pass the message that needed to be printed in the screen to underlying renderer. :param text: A dict containing key and values or a string. :return: None """ if self.on_screen_message is not None: self.on_screen_message.update_data(text) self.on_screen_message.render() if self.mode == RENDER_MODE_ONSCREEN: self.sky_box.step() # if self.highway_render is not None: # self.highway_render.render() def step_physics_world(self): dt = self.global_config["physics_world_step_size"] self.physics_world.dynamic_world.doPhysics(dt, 1, dt) def _debug_mode(self): debugNode = BulletDebugNode('Debug') debugNode.showWireframe(True) debugNode.showConstraints(True) debugNode.showBoundingBoxes(False) debugNode.showNormals(True) debugNP = self.render.attachNewNode(debugNode) self.physics_world.dynamic_world.setDebugNode(debugNP.node()) self.debug_node = debugNP def toggleAnalyze(self): self.worldNP.analyze() print(self.physics_world.report_bodies()) # self.worldNP.ls() def toggleDebug(self): if self.debug_node is None: self._debug_mode() if self.debug_node.isHidden(): self.debug_node.show() else: self.debug_node.hide() def report_body_nums(self, task): logging.debug(self.physics_world.report_bodies()) return task.done def close_world(self): self.taskMgr.stop() # It will report a warning said AsynTaskChain is created when taskMgr.destroy() is called but a new showbase is # created. logging.debug( "Before del taskMgr: task_chain_num={}, all_tasks={}".format( self.taskMgr.mgr.getNumTaskChains(), self.taskMgr.getAllTasks())) self.taskMgr.destroy() logging.debug( "After del taskMgr: task_chain_num={}, all_tasks={}".format( self.taskMgr.mgr.getNumTaskChains(), self.taskMgr.getAllTasks())) self.physics_world.dynamic_world.clearContactAddedCallback() self.physics_world.destroy() self.destroy() close_asset_loader() import sys if sys.version_info >= (3, 0): import builtins else: import __builtin__ as builtins if hasattr(builtins, 'base'): del builtins.base def clear_world(self): self.worldNP.removeNode() self.pbr_worldNP.removeNode() def toggle_help_message(self): if self.on_screen_message: self.on_screen_message.toggle_help_message() def draw_line(self, start_p, end_p, color, thickness: float): """ Draw line use LineSegs coordinates system. Since a resolution problem is solved, the point on screen should be described by [horizontal ratio, vertical ratio], each of them are ranged in [-1, 1] :param start_p: 2d vec :param end_p: 2d vec :param color: 4d vec, line color :param thickness: line thickness """ line_seg = LineSegs("interface") line_seg.setColor(*color) line_seg.moveTo(start_p[0] * self.w_scale, 0, start_p[1] * self.h_scale) line_seg.drawTo(end_p[0] * self.w_scale, 0, end_p[1] * self.h_scale) line_seg.setThickness(thickness) line_np = self.aspect2d.attachNewNode(line_seg.create(False)) return line_np def remove_logo(self, task): alpha = self._loading_logo.getColor()[-1] if alpha < 0.1: self._loading_logo.destroy() return task.done else: new_alpha = alpha - 0.08 self._loading_logo.setColor((1, 1, 1, new_alpha)) return task.cont
class Engine(ShowBase): def __init__(self, mouse): ShowBase.__init__(self) self.mouse = mouse self.joy_x = None self.joy_y = None props = WindowProperties() props.setMouseMode(WindowProperties.MRelative) # keep mouse in screen self.disableMouse() self.win.requestProperties(props) self.setBackgroundColor(0, 0, 0) # Make missiles glow self.filters = CommonFilters(self.win, self.cam) self.filters.setBloom(blend=(0, 0, 0, 1), desat=-0.5, intensity=3.0, size="large") self.screen_width = self.win.getXSize() self.screen_height = self.win.getYSize() self.center_x = self.screen_width/2 self.center_y = self.screen_height/2 # self.win.movePointer(0, self.center_x, self.center_y) self.enableParticles() self.cTrav = CollisionTraverser() # self.cTrav.setRespectPrevTransform(True) self.pusher = PhysicsCollisionHandler() self.pusher.addInPattern('%fn-into-%in') self.target = None self.maxvel = 50 self.roll_time = 0 self.fuel = 1000 self.ship() self.sounds() self.hud() self.part = Spacedust(self) self.events() self.camLens.setFov(70) self.camLens.setNear(1) self.camLens.setFar(500) self.get_key = { "ACCEL": False, "DECEL": False, "FORWARD_THRUST": False, "REVERSE_THRUST": False, "ROLL_LEFT": False, "ROLL_RIGHT": False, "ROLL_LEFT_BEG": False, "ROLL_RIGHT_BEG": False, "FIRE": False, "FIRING": False, "LOCK": False, "LOCKING": False, } self.AIworld = AIWorld(self.render) self.taskMgr.add(self.update, "task-update") self.taskMgr.doMethodLater(1, self.fuel_usage, "task-fuel-usage") self.taskMgr.add(self.AI_update, "AI-update") self.gen_enemy() def gen_enemy(self): x = randint(-1000, 1000) y = randint(-1000, 1000) z = randint(-1000, 1000) Enemy(self, 0, x, y, z) def AI_update(self, task): self.AIworld.update() return task.cont def hud(self): self.font = self.loader.loadFont("./fnt/subatomic.tsoonami.ttf") self.aim = OnscreenImage(image="./png/ring.png", pos=Vec3(0), scale=0.02) self.aim.setTransparency(TransparencyAttrib.MAlpha) self.locker = OnscreenImage(image="./png/ring.png", pos=Vec3(0), scale=0.12) self.locker.setTransparency(TransparencyAttrib.MAlpha) self.locker.hide() self.txtFuel = OnscreenText(parent=self.render2d, align=TextNode.ALeft, pos=(-0.95, 0.8), text='FUEL', fg=(1, 1, 1, 0.5), scale=0.05, font=self.font, mayChange=True) self.txtSpeed = OnscreenText(parent=self.render2d, align=TextNode.ALeft, pos=(-0.95, 0.7), text='SPEED', fg=(1, 1, 1, 0.5), scale=0.05, font=self.font, mayChange=True) self.txtDist = OnscreenText(parent=self.render2d, align=TextNode.ALeft, pos=(-0.95, 0.6), text='DIST', fg=(1, 1, 1, 0.5), scale=0.05, font=self.font, mayChange=True) self.txtCoord = OnscreenText(parent=self.render2d, align=TextNode.ALeft, pos=(-0.95, 0.5), text='COORD', fg=(1, 1, 1, 0.5), scale=0.05, font=self.font, mayChange=True) self.taskMgr.doMethodLater(1, self.instruments, "task-instruments") def instruments(self, task): self.txtSpeed.setText("SPEED: %s" % str(int(self.mvel))) self.txtFuel.setText("FUEL: %s" % str(self.fuel)) if self.target is not None: self.txtDist.setText("DISTANCE: %s" % str(round(self.dist, 1))) else: self.txtDist.setText("DISTANCE: ---") self.txtCoord.setText("COORD: %s %s %s" % (str(round(self.fighter.getX(), 1)), str(round(self.fighter.getY(), 1)), str(round(self.fighter.getZ(), 1)))) return task.again def set_key(self, key, value): self.get_key[key] = value def toggle_key(self, key): self.set_key(key, not self.get_key[key]) def init_roll(self, a, task): if task.time <= 2: if self.roll_time <= task.time: self.roll_time = task.time else: self.roll_time += task.time if self.roll_time > 2: self.roll_time = 2 self.fighter.setR(self.fighter.getR() + a * self.roll_time) else: self.fighter.setR(self.fighter.getR() + a * 2) return task.cont def end_roll(self, a, b, task): if task.time < b: self.roll_time -= task.time if self.roll_time < 0: self.roll_time = 0 self.fighter.setR(self.fighter.getR() + a * (b - task.time)) return task.cont else: return task.done def roll(self, a): if a > 0: self.set_key("ROLL_RIGHT_BEG", True) else: self.set_key("ROLL_LEFT_BEG", True) self.taskMgr.add(self.init_roll, "task-init-roll", extraArgs=[a], appendTask=True) def unroll(self, a): if a > 0: self.set_key("ROLL_RIGHT_BEG", False) else: self.set_key("ROLL_LEFT_BEG", False) self.taskMgr.remove("task-init-roll") self.taskMgr.add(self.end_roll, "task-end-roll", extraArgs=[a, self.roll_time], appendTask=True) def to_roll(self): if self.get_key["ROLL_LEFT"]: if not self.get_key["ROLL_LEFT_BEG"]: if self.fuel > 5: self.roll(-1) self.snd_roller.play() else: if self.get_key["ROLL_LEFT_BEG"]: self.unroll(-1) self.snd_roller.stop() if self.get_key["ROLL_RIGHT"]: if not self.get_key["ROLL_RIGHT_BEG"]: if self.fuel > 5: self.roll(+1) self.snd_roller.play() else: if self.get_key["ROLL_RIGHT_BEG"]: self.unroll(+1) self.snd_roller.stop() def fuel_usage(self, task): if self.get_key["FORWARD_THRUST"] or self.get_key["REVERSE_THRUST"]: self.fuel -= 9 if self.get_key["ROLL_LEFT_BEG"] or self.get_key["ROLL_RIGHT_BEG"]: self.fuel -= 4 self.fuel -= 1 if self.fuel < 0: self.fuel = 0 return task.again def chk_speed(self, mvel): if mvel < 0.01: # stop fighter dead if self.prt.getActive(): self.set_key("DECEL", False) mvel = 0 if mvel > self.maxvel: # stop fighter accelerating if self.pft.getActive(): self.set_key("ACCEL", False) mvel = self.maxvel self.part.p.renderer.setLineScaleFactor(mvel*2) self.part.pn.setPos(self.fighter, 0, 10, 0) return mvel def thrust_shake(self, task): x = uniform(-1000, 1000) y = uniform(-1000, 1000) self.repos(x, y, 0.001) return task.cont def thrust_end(self, task): if task.time < 5: f = (5. - task.time) / 5. s = 1000.*f x = uniform(-s, s) y = uniform(-s, s) self.repos(x, y, 0.001) self.snd_thrust.setVolume(f) return task.cont self.snd_thrust.stop() return task.done def thrust(self, a): if a > 0: self.set_key("FORWARD_THRUST", True) else: self.set_key("REVERSE_THRUST", True) self.taskMgr.remove("task-thrust-end") self.snd_thrust.setVolume(1) self.snd_thrust.play() self.taskMgr.add(self.thrust_shake, "task-thrust-shake") def unthrust(self, a): if a > 0: self.set_key("FORWARD_THRUST", False) else: self.set_key("REVERSE_THRUST", False) self.taskMgr.remove("task-thrust-shake") self.taskMgr.add(self.thrust_end, "task-thrust-end") def to_thrust(self): if self.get_key["ACCEL"]: if self.mvel < self.maxvel - 1: if not self.get_key["FORWARD_THRUST"]: if self.fuel > 10: self.pft.setActive(True) self.thrust(+1) else: if self.get_key["FORWARD_THRUST"]: self.pft.setActive(False) self.unthrust(+1) if self.get_key["DECEL"]: if self.mvel > 0: if not self.get_key["REVERSE_THRUST"]: if self.fuel > 10: self.prt.setActive(True) self.thrust(-1) else: if self.get_key["REVERSE_THRUST"]: self.prt.setActive(False) self.unthrust(-1) def events(self): self.accept("escape", self.quit) self.accept('mouse1', self.set_key, ["FIRE", True]) self.accept('mouse1-up', self.set_key, ["FIRE", False]) self.accept('mouse3', self.set_key, ["LOCK", True]) self.accept('mouse3-up', self.set_key, ["LOCK", False]) self.accept("w", self.set_key, ["ACCEL", True]) self.accept("w-up", self.set_key, ["ACCEL", False]) self.accept("s", self.set_key, ["DECEL", True]) self.accept("s-up", self.set_key, ["DECEL", False]) self.accept("a", self.set_key, ["ROLL_LEFT", True]) self.accept("a-up", self.set_key, ["ROLL_LEFT", False]) self.accept("d", self.set_key, ["ROLL_RIGHT", True]) self.accept("d-up", self.set_key, ["ROLL_RIGHT", False]) def update(self, task): self.pos() self.speed() if self.fuel > 0: self.to_roll() self.to_thrust() self.to_fire() self.to_lock() self.rehud() return task.cont def rehud(self): if self.target is not None: c = self.target.np.getPos(self.fighter) self.dist = c.length() c.normalize() self.d2 = c - Vec3(0, 1, 0)*c.dot(Vec3(0, 1, 0)) self.target.radar.setPos(self.d2.getX(), 1, self.d2.getZ()) def sounds(self): self.audio3d = Audio3DManager.Audio3DManager(self.sfxManagerList[0], self.camera) self.audio3d.setListenerVelocityAuto() self.snd_space = self.loader.loadSfx("./snd/space.flac") self.snd_space.setLoop(True) self.snd_thrust = self.loader.loadSfx("./snd/thrust.flac") self.snd_thrust.setLoop(True) self.snd_roller = self.loader.loadSfx("./snd/roller.flac") self.snd_roller.setLoop(True) self.snd_launch = self.loader.loadSfx("./snd/launch.flac") self.snd_lock = self.loader.loadSfx("./snd/lock.flac") self.snd_space.play() def quit(self): self.taskMgr.running = False def repos(self, x, y, d): player_q = self.fighter.getQuat() up = player_q.getUp() right = player_q.getRight() up.normalize() right.normalize() up_q = copy(player_q) right_q = copy(player_q) up_q.setFromAxisAngle(-(x * d), up) right_q.setFromAxisAngle(y * d, right) self.fighter.setQuat(player_q.multiply(up_q.multiply(right_q))) def move_end(self, x, y, task): if task.time <= 1: d = 0.002*(1 - task.time) self.repos(x, y, d) return task.cont return task.done def pos(self): if self.mouse: md = self.win.getPointer(0) x = md.getX() y = md.getY() else: x = self.joy_x y = self.joy_y if self.win.movePointer(0, self.center_x, self.center_y): x -= self.center_x y -= self.center_y if x != 0 or y != 0: self.taskMgr.add(self.move_end, 'task-move-end', extraArgs=[x, y], appendTask=True) def speed(self): fwd = self.fighter.getQuat().getForward() fwd.normalize() self.mvel = self.anpo.getVelocity().length() # speed control self.mvel = self.chk_speed(self.mvel) self.anpo.setVelocity(fwd * self.mvel) def ship(self): an = ActorNode() an.getPhysicsObject().setMass(100) self.fighter = self.render.attachNewNode(an) self.physicsMgr.attachPhysicalNode(an) self.anpo = an.getPhysicsObject() fn = ForceNode("force-node-fighter") self.fighter.attachNewNode(fn) self.pft = LinearVectorForce(Vec3(0, +1, 0) * 500) # forward thrust self.prt = LinearVectorForce(Vec3(0, -1, 0) * 500) # reverse thrust self.pft.setMassDependent(1) self.prt.setMassDependent(1) self.pft.setActive(False) self.prt.setActive(False) fn.addForce(self.pft) fn.addForce(self.prt) an.getPhysical(0).addLinearForce(self.pft) an.getPhysical(0).addLinearForce(self.prt) self.camera.reparentTo(self.fighter) from_obj = self.fighter.attachNewNode(CollisionNode('fighter')) from_obj.node().setFromCollideMask(BitMask32(0x1)) from_obj.setCollideMask(BitMask32(0x1)) from_obj.node().addSolid(CollisionSphere(0, 0, 0, 1)) # from_obj.show() self.pusher.addCollider(from_obj, self.fighter) self.cTrav.addCollider(from_obj, self.pusher) def launch_bullet(self): speed = 500. scale = Vec3(0.05) color = Vec4(0, 1, 0, 1) mask = BitMask32(0x2) lookat = Vec3(0, 100, 0) Missile(self, "bullet", speed, scale, color, mask, self.fighter, Vec3(-0.5, 0, 0), self.fighter, lookat, 0.5) Missile(self, "bullet", speed, scale, color, mask, self.fighter, Vec3(+0.5, 0, 0), self.fighter, lookat, 0.5) self.snd_launch.play() def to_fire(self): if self.get_key["FIRE"]: if not self.get_key["FIRING"]: self.set_key("FIRING", True) self.taskMgr.doMethodLater(0.16, self.fire_bullet, "task-fire-bullet") else: if self.get_key["FIRING"]: self.set_key("FIRING", False) self.taskMgr.remove("task-fire-bullet") def fire_bullet(self, task): if self.fuel >= 5: self.fuel -= 5 self.launch_bullet() return task.again def launch_missile(self): speed = 100 scale = Vec3(0.2) color = Vec4(1, 0, 0, 1) mask = BitMask32(0x2) lookat = Vec3(0, 0, 0) self.missile = Missile(self, "missile", speed, scale, color, mask, self.fighter, Vec3(0, 0, -2), self.target.np, lookat, 3) self.snd_launch.play() self.taskMgr.add(self.guide_missile, "task-guide-missile") def guide_missile(self, task): try: quat = Quat() lookAt(quat, self.target.np.getPos() - self.missile.anp.getPos(), Vec3.up()) self.missile.anp.setQuat(quat) fwd = quat.getForward() fwd.normalize() mvel = self.missile.anpo.getVelocity().length() self.missile.anpo.setVelocity(fwd*mvel) except: return task.done return task.cont def can_lock(self): if self.dist >= 30 and self.dist <= 300 and abs(self.d2.getX()) <= 0.1 and abs(self.d2.getZ()) <= 0.1: return True else: return False def remove_lock(self): if self.get_key["LOCKING"]: self.set_key("LOCKING", False) self.locker.hide() self.snd_lock.stop() self.taskMgr.remove("task-fire-missile") def to_lock(self): if self.get_key["LOCK"]: if self.can_lock(): if self.fuel >= 100: if not self.get_key["LOCKING"]: self.set_key("LOCKING", True) self.locker.setScale(0.12) self.locker.setColor(1, 0, 0, 0.5) self.locker.show() self.snd_lock.play() self.taskMgr.add(self.fire_missile, "task-fire-missile") else: self.remove_lock() else: self.remove_lock() else: self.remove_lock() def fire_missile(self, task): if self.fuel >= 100: if task.time < 3.6: e = (3.6 - task.time)/3.6 f = 0.02 + e*0.1 self.locker.setScale(f) self.locker.setColor(e, 1-e, 0, 0.5) return task.cont else: self.fuel -= 100 self.launch_missile() return task.done
def _createItem(self, entry, ignore_fadein = False): '''Create an item(not including adding this to itemEntries)''' imagepathes = runtime_data.game_settings['imagepathes'] imagetypes = runtime_data.game_settings['imagetypes'] modelpathes = runtime_data.game_settings['modelpathes'] modeltypes = runtime_data.game_settings['modeltypes'] if self._sceneItems.has_key(entry.key): self._sceneItems[entry.key].removeNode() self._sceneItems.pop(entry.key) item = None if entry.category == SVIC.FG or entry.category == SVIC.BG or entry.category == SVIC.O2D: texture = None for ft in ((folder,type) for folder in imagepathes for type in imagetypes): if exists(ft[0] + entry.fileName + ft[1]): texture = loader.loadTexture(ft[0] + entry.fileName + ft[1]) break '''Alternative item = loader.loadModel(r"models/plain.egg") item.setTexture(texture, 1) ''' item = OnscreenImage(texture) item.setPos(entry.pos[0],entry.pos[1],entry.pos[2]) item.setScale(entry.scale[0]*texture.getOrigFileXSize()/float(texture.getOrigFileYSize()),entry.scale[1],entry.scale[2]) #Always make its height fill the screen normally color = (entry.color[0],entry.color[1],entry.color[2],entry.color[3]) if entry.fadein: lv = LerpColorInterval(item, entry.fadein, color, (color[0],color[1],color[2],0) ) self._intervals.append(lv) lv.start() else: item.setColor(color) item.setName(entry.key) if entry.category == SVIC.FG: item.reparentTo(self.fgNodePath) elif entry.category == SVIC.BG: item.reparentTo(self.bgNodePath) elif entry.category == SVIC.O2D: item.reparentTo(self.vNodePath) elif entry.category == SVIC.AFG: item = None for ft in ((folder,type) for folder in imagepathes for type in modeltypes): if exists(ft[0] + entry.fileName + ft[1]): item = loader.loadModel(ft[0] + entry.fileName + ft[1]) break if not item: item = loader.loadModel(entry.fileName) item.setPos(entry.pos[0],entry.pos[1],entry.pos[2]) item.setScale(entry.scale) #For generated egg animation with "egg-texture-cards" is a 1x1 rectangle by default color = (entry.color[0],entry.color[1],entry.color[2],entry.color[3]) if entry.fadein: lv = LerpColorInterval(item, entry.fadein, color, (color[0],color[1],color[2],0) ) self._intervals.append(lv) lv.start() else: item.setColor(color) item.setTransparency(1) item.setName(entry.key) item.reparentTo(self.fgNodePath) #item.setBin("unsorted", 0) elif entry.category == SVIC.O3D: item = None for ft in ((folder,type) for folder in modelpathes for type in modeltypes): if exists(ft[0] + entry.fileName + ft[1]): item = loader.loadModel(ft[0] + entry.fileName + ft[1]) break if not item: item = loader.loadModel(entry.fileName) item.setPos(entry.pos[0],entry.pos[1],entry.pos[2]) item.setScale(entry.scale) #For generated egg animation with "egg-texture-cards" is a 1x1 rectangle by default color = (entry.color[0],entry.color[1],entry.color[2],entry.color[3]) if entry.fadein: lv = LerpColorInterval(item, entry.fadein, color, (color[0],color[1],color[2],0) ) self._intervals.append(lv) lv.start() else: item.setColor(color) item.setTransparency(1) item.setName(entry.key) item.reparentTo(self.vNodePath) if item: self._sceneItems[entry.key] = item if entry.quickitem: self._quickitems.append(entry.key)
class ImagePresenter(MessagePresenter): """ A display that can present images with a fixed (or optionally randomly chosen) position, size and other display properties (e.g. coloring). See also MessagePresenter for usage information. """ def __init__( self, pos=(-0.25, 0.5), # position of the image center in the aspect2d viewport # may also be a callable object (e.g.a draw from a random number generator) scale=0.2, # scaling of the image; may also be callable rotation=( 0, 0, 0 ), # yaw, pitch, roll -- the most relevant is the roll coordinate; may also be callable color=(1, 1, 1, 1), # (r,g,b,a) image color renderviewport=None, # the parent viewport if desired image='blank.tga', # the initial image to present *args, **kwargs): """Construct a new ImagePresenter.""" MessagePresenter.__init__(self, *args, **kwargs) self.pos = pos self.scale = scale self.rotation = rotation self.color = color self.renderviewport = renderviewport # set up the text panel... #if not (type(self.pos) is List or type(self.pos) is tuple): #pos = self.pos() #if callable(self.scale): #scale = self.scale() #if callable(self.rotation): #rotation = self.rotation() #if callable(self.color): #color = self.color() self.icon = OnscreenImage( image=image, pos=(pos[0], 0, pos[1]), scale=scale, hpr=rotation, color=((0, 0, 0, 0) if image == "blank.tga" else self.color), parent=self.renderviewport) self.icon.setTransparency(TransparencyAttrib.MAlpha) def _present(self, message): self.icon.setImage(message.strip()) self.icon.setTransparency(TransparencyAttrib.MAlpha) # select remaining properties randomly, if applicable # if callable(self.pos): # p = self.pos() # self.icon.setPos(p[0],p[1],p[2]) # if callable(self.scale): # self.icon.setScale(self.scale()) # if callable(self.rotation): # rot = self.rotation() # self.icon.setHpr(rot[0],rot[1],rot[2]) col = self.color #() if callable(self.color) else self.color self.icon.setColor(col[0], col[1], col[2], col[3]) self.marker(222) def _unpresent(self): try: self.marker(223) self.icon.setColor(0, 0, 0, 0) except: pass def destroy(self): self.icon.removeNode() def precache(self, message): loader.loadTexture(message)
class MyApp(ShowBase): def __init__(self, fStartDirect=True): #ConfigVariableBool("fullscreen",0).setValue(1) ShowBase.__init__(self) self.loadInitialCamPos()#initialize camera positioning self.assocs=dict() self.loadBooleans() self.loadLists() self.shuffleCards() self.loadValues() #creates a random sequence of cards we will memorize self.setInputs() #set up keyboard and mouse inputs self.setUpCollision() #sets up collision detection self.setUpScene() #sets up geometry in the 3D Enviroments self.loadSFX() self.light=self.setUpPointLight() taskMgr.add(self.setUpChest, 'setUpChest') #sets up rotating graphic of chest def loadValues(self): self.counter,self.lightCounter,self.fade,self.numFireflies=0,0,0,15 self.numCards=13 self.numCardsCopy=copy.copy(self.numCards) self.shuffledCardFacesCopy=copy.copy(self.shuffledCardFaces) def loadLists(self): self.cardsPos,self.imageList,self.visitedItems=[],[],[] self.buttonList,self.lastCoord,self.fireFlyList=[],[],[] self.previousCard,self.nextCard=[],[] def loadBooleans(self): self.toggleChest=False self.fadeToggle=False self.togglePreviousCard=False self.toggleNextCard=False self.toggleBar=True self.titleText=None self.userLocation=None def loadInitialCamPos(self): #we disable our mouse because we be using a different method #that will set up our mouse controls base.disableMouse() self.camPosx,self.camPosz=15,28 self.camera.setH(90) self.camera.setP(-25) self.heading=0 base.camera.setPos(self.camPosx,0,self.camPosz) def loadSFX(self): self.soundSteps = loader.loadMusic("footsteps.wav") #circus in the Sky is a piece written by Uzman Riaz (credit) #self.circusInTheSky=loader.loadMusic("circusInTheSky.wav") def setUpCollision(self): #pusher and queue are handlers from when a collision occurs self.cTrav = CollisionTraverser() self.queue = CollisionHandlerQueue() self.pusher = CollisionHandlerPusher() #set up scene geometrys self.setUpCollisionRay() self.setUpCollisionNode() def setUpPointLight(self): taskMgr.doMethodLater(.1, self.createTitleText, 'textFadeInOut') #we create multiple point lights to make it appear as if there are #'firefly' entities within the chest for n in xrange(self.numFireflies): self.generateLights("%fFirefly"%n) #sets up a soft ambient light so that our 3D enviroment appears #more realistic self.alight = AmbientLight('ambientLight') self.alight.setColor(VBase4(.6, .6, .6, 1)) alnp = render.attachNewNode(self.alight) render.setLight(alnp) self.treasureChest.setLight(alnp) def createTitleText(self,task): #task allows up to fade text in and out self.updateFade() if self.titleText!=None: self.titleText.remove() self.titleText=OnscreenText(text="[Click on the chest to begin]", style=Plain,pos=(0,0),fg=(1,1,1,self.fade)) if self.toggleChest==True: self.titleText.remove() return task.done return task.again def generateLights(self,name): #generate pointlights and reparenting them to the chest name=PointLight("Light") name=render.attachNewNode(name) name.setPos(0,0,22) name.hide() self.modelLight = loader.loadModel("misc/Pointlight.egg.pz") self.modelLight.reparentTo(name) self.treasureChest.setLight(name) self.fireFlyList.append(name) def setUpChest(self,task): if self.toggleChest==True: #chest rotates backwards if clicked on self.speed=-1.5 else: self.speed=.5 #chest rotates forward slowly self.lightCounter+=1 angle,radius= radians(self.heading),1.2 x,y,z =(cos(angle)*radius,sin(angle)*radius,sin(angle)*radius) self.heading+=self.speed self.heading%=360 self.treasureChest.setH(self.heading) if self.lightCounter%7==0: for n in xrange(self.numFireflies): self.generateFireFlies(x,y,n) if abs(self.treasureChest.getH()-360)<2 and self.toggleChest==True: #if chest is activated and the chest if facing the camera taskMgr.add(self.moveChest, 'moveChest') return task.done else: return Task.cont def moveChest(self,task): #units are calculated so that camera and chest move simultaneously #to create smooth transition between frames self.alight.setColor(VBase4(.8, .8, .8, 1)) self.shiftChestUnits,self.intervals=.1,52.0 x,y,z=self.treasureChest.getPos() newx=x+self.shiftChestUnits self.treasureChest.setPos(newx,y,z) self.moveCamera() if int(x)==self.camPosx-10: #if we get within a range of acceptable values # we set up our homepage self.homePage() return task.done else: return task.cont def moveCamera(self): self.originalZ,self.targetZ=28.0,22.0 self.shiftCameraZ=(self.originalZ-self.targetZ)/self.intervals self.pitchChange=25.0/self.intervals newPitch=self.camera.getP()+self.pitchChange newHeight=self.camera.getPos()[2]-self.shiftCameraZ camerax,cameray=self.camera.getPos()[0],self.camera.getPos()[1] self.camera.setPos(camerax,cameray,newHeight) self.camera.setP(newPitch) def generateFireFlies(self,x,y,n): zLowerLimit=21.0 zHigherLimit=22.0 light=self.fireFlyList[n] self.xFirefly=random.uniform(-x,x) self.yFirefly=random.uniform(-y,y) self.zFirefly=random.uniform(zLowerLimit,zHigherLimit) light.setPos(self.xFirefly,self.yFirefly,self.zFirefly) def setUpFog(self): self.fogDensity=.03 myFog = Fog("fog") myFog.setColor(1,1,1) myFog.setExpDensity(self.fogDensity) render.setFog(myFog) def displayHelpPanel(self): self.dummyNode1=self.createDummyNode("self.dummyNode1") self.dummyNode2=self.createDummyNode("self.dummyNode2") self.dummyNode3=self.createDummyNode("self.dummyNode3") self.floorPlan=OnscreenImage( image="floorplan.png", scale=(.4,.25,.55), pos=(.7,0,.3)) self.floorPlan.setTransparency(TransparencyAttrib.MAlpha) self.floorPlan.reparentTo(self.dummyNode1) self.displayToggleBar() self.displayAdjacencies() taskMgr.doMethodLater(.1, self.createSubTitle, 'textFadeInOut') def createSubTitle(self,task): self.previousTitlePos=(-1.205,.89) self.nextTitlePos=(-1.195,-.43) try: self.titlePrevious.destroy() self.titlePrevious=OnscreenText( text="[Previous]",pos=self.previousTitlePos, scale=.045,fg=(1,1,1,self.fade)) except: self.titlePrevious=OnscreenText( text="[Previous]",pos=self.previousTitlePos, scale=.045,fg=(1,1,1,self.fade)) try : self.titleNext.destroy() self.titleNext=OnscreenText( text="[Next]",pos=self.nextTitlePos,scale=.045,fg=(1,1,1,self.fade)) except: self.titleNext=OnscreenText( text="[Next]",pos=self.nextTitlePos, scale=.045,fg=(1,1,1,self.fade)) return task.again def createDummyNode(self,name): name=render.attachNewNode("2d") name.reparentTo(aspect2d) return name def displayToggleBar(self): self.toggleBarImage=DirectButton( image = "hidebar.png",scale=(.07,0.1,.55),pos=(1.17,0,.3), relief=None,command=lambda: self.switchDisplays( self.toggleBar,self.dummyNode1,self.toggleBarImage, "hidebar.png","showbar.png", (.07,0.1,.55),(1.17,0,.3))) self.togglePreviousBar() self.toggleNextBar() def togglePreviousBar(self): self.previousBarPos=(-1.2,0,.57) self.togglePreviousBarImage=(DirectButton( image = "hidebarshort.png", scale=(.07,0.1,.195),pos=self.previousBarPos,relief=None, command= lambda: self.switchDisplays( self.togglePreviousCard, self.dummyNode2,self.togglePreviousBarImage, "hidebarshort.png","showbarshort.png", (.07,0.1,.195),self.previousBarPos))) def toggleNextBar(self): self.nextBarPos=(-1.2,0,-.7) self.toggleNextBarImage=(DirectButton( image = "hidebarshort.png", scale=(.07,0.1,.195),pos=self.nextBarPos,relief=None, command= lambda: self.switchDisplays( self.toggleNextCard,self.dummyNode3,self.toggleNextBarImage, "hidebarshort.png","showbarshort.png", (.07,0.1,.195),self.nextBarPos))) def switchPreviousCardDisplay(self): self.toggleBarPrevious=not(self.toggleBarPrevious) def displayAdjacencies(self): if self.previousCard: self.displayPreviousCard() if self.nextCard: self.displayNextCard() def displayPreviousCard(self): self.previousCardPos=(-1,0,.58) self.previousCardTextPos=(-.9,.57) prevCard=self.previousCard.split(".")[0] self.previousCard=OnscreenImage( image=self.previousCard,pos=self.previousCardPos, scale=(0.07,0.82,0.12)) self.previousCard.reparentTo(self.dummyNode2) try: self.assocPrevText.destroy() self.assocPrevText=OnscreenText( text="(%s)"%self.inputs[prevCard], pos=self.previousCardTextPos, scale=.06,fg=(1,1,1,1),align=TextNode.ALeft) self.assocPrevText.reparentTo(self.dummyNode2) except: self.assocPrevText=OnscreenText( text="(%s)"%self.inputs[prevCard], pos=self.previousCardTextPos, scale=.06,fg=(1,1,1,1),align=TextNode.ALeft) self.assocPrevText.reparentTo(self.dummyNode2) def displayNextCard(self): self.nextCardPos=(-1,0,-.685) self.nextCardTextPos=(-.9,-.69) nextCard=self.nextCard.split(".")[0] self.nextCard=OnscreenImage( image=self.nextCard,pos=self.nextCardPos,scale=(0.07,0.82,0.12)) self.nextCard.reparentTo(self.dummyNode3) try: self.assocNextText.destroy() self.assocNextText=OnscreenText( text="(%s)"%self.inputs[nextCard], pos=self.nextCardTextPos, scale=.06,fg=(1,1,1,1),align=TextNode.ALeft) self.assocNextText.reparentTo(self.dummyNode3) except: self.assocNextText=OnscreenText( text="(%s)"%self.inputs[nextCard], pos=self.nextCardTextPos,scale=.06, fg=(1,1,1,1),align=TextNode.ALeft) self.assocNextText.reparentTo(self.dummyNode3) def switchDisplays(self,toggleBar,dummyNode,imageNode,hideImage, showImage,scale,pos): toggleBar=not(toggleBar) if toggleBar==True: dummyNode.show() imageNode.destroy() imageNode=(DirectButton(image = hideImage,scale=scale,pos=pos, relief=None, command=lambda: self.switchDisplays( toggleBar,dummyNode, imageNode,hideImage, showImage,scale,pos))) else: dummyNode.hide() imageNode.destroy() imageNode=(DirectButton(image = showImage,scale=scale,pos=pos, relief=None, command= lambda: self.switchDisplays( toggleBar,dummyNode, imageNode,hideImage, showImage,scale,pos))) def shuffleCards(self): self.shuffledCardNames=[] self.shuffledCardFaces=copy.copy(cardFaces) random.shuffle(self.shuffledCardFaces) for face in self.shuffledCardFaces: self.shuffledCardNames.append(face.split(".")[0]) def setUpCollisionRay(self): #Make a collision node for ours selection ray #Repurposed from Panda3D Documentation self.selectionNode = CollisionNode('mouseRay') self.selectionNP = camera.attachNewNode(self.selectionNode) self.selectionNode.setFromCollideMask( GeomNode.getDefaultCollideMask()) self.selectionNode.setFromCollideMask(1) self.selectionNode.setIntoCollideMask(0) self.selectionRay = CollisionRay() #Make our ray self.selectionNode.addSolid(self.selectionRay) #Add it to the collision node #Register the ray as something that can cause collisions self.cTrav.addCollider(self.selectionNP,self.queue) def setUpCollisionNode(self): #add a collision node to our camera self.fromObject = base.camera.attachNewNode( CollisionNode('colNode')) self.fromObject.setPos(0,0,3) self.fromObject.node().addSolid(CollisionSphere(0, 0, 0, .5)) self.fromObject.node().setIntoCollideMask(0) self.cTrav.addCollider(self.fromObject,self.pusher) self.pusher.addCollider( self.fromObject, base.camera, base.drive.node()) def setInputs(self): self.accept("mouse1",self.mouse1Tasks) self.accept('escape', sys.exit) def playFootSteps(self): self.soundSteps.play() def mouse1Tasks(self): self.mouseTask() def setUpScene(self): #self.setUpControls() self.setUpBackground() #set up the items where we can store information self.setUpItems() def mouseTask(self): self.scale=53 self.loadItemList() if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.selectionRay.setFromLens( base.camNode, mpos.getX(), mpos.getY()) #self.cTrav.showCollisions(render) if self.queue.getNumEntries() > 0: self.mouseEntry() def mouseEntry(self): #if we've clicked on something self.queue.sortEntries() #we get closest item pickedObj = self.queue.getEntry(0).getIntoNodePath().getTag("items") #check if what we clicked is what we want (has proper tag) if len(pickedObj)>0 and (pickedObj not in self.visitedItems): self.mouseTaskSupport(pickedObj) if self.queue.getEntry(0).getIntoNodePath().getTag("openChest"): self.toggleChest=True def mouseTaskSupport(self,pickedObj): self.assocs[ self.shuffledCardNames[self.counter]]=self.items[int(pickedObj)] self.counter+=1 self.visitedItems.append(pickedObj) #self.queue.getEntry(0).getIntoNodePath().clearTag("items") #if len(self.visitedItems)==len(self.items): if len(self.visitedItems)==5: self.testMemory() self.drawMiniCards(-self.camera.getPos()[1]/self.scale+.40, self.camera.getPos()[0]/self.scale-.2) self.updateDisplayCards() self.displayAdjacencies() def loadItemList(self): self.items=["painting","post","tv","bed","carpet","table","tree", "shelf","loveSeat1","loveSeat2","longSofa", "dinnerTable","dinnerChair1","dinnerChair2"] def testMemory(self): self.nextButton=DirectButton(image = 'arrow.png', scale=.15,pos=(0.8,0,-0.6), relief=None, command=self.recallMemory) self.nextButton.setTransparency(TransparencyAttrib.MAlpha) def displayPriorityArrow(self): self.arrow=OnscreenImage(image="arrow2.png", scale=(.05,.1,.05),pos=(-.51,0,-.6), color=(1,0,0,0)) self.arrow.setTransparency(TransparencyAttrib.MAlpha) taskMgr.doMethodLater(.1, self.fadeArrow, 'arrowFadeInOut') def displayUserLocation(self,task,scale=(.05,1,.05)): self.updateFade() if self.userLocation!=None: self.userLocation.destroy(),self.userAngle.destroy() x=-self.camera.getPos()[1]/self.scale+.40 y=self.camera.getPos()[0]/self.scale-.2 self.userLocation=OnscreenImage( image="dot.png",pos=(x,0,y),scale=scale, color=(1,1,1,self.fade)) self.userAngle=OnscreenImage( image="rotating.png",pos=(x,0,y),scale=scale, color=(1,1,1,self.fade)) self.userAngle.setR(-self.camera.getHpr()[0]) self.userLocation.setTransparency(TransparencyAttrib.MAlpha) self.userAngle.setTransparency(TransparencyAttrib.MAlpha) self.userLocation.reparentTo(self.dummyNode1) self.userAngle.reparentTo(self.dummyNode1) return Task.again def updateFade(self): if self.fadeToggle==True: self.fade+=.05 if self.fade>1: self.fadeToggle=False elif self.fadeToggle==False: self.fade-=.05 if self.fade<0: self.fadeToggle=True def drawMiniCards(self,x,y): self.lastCoord+=([[x,0,y]]) self._draw_line_segs(self.dummyNode1,self.lastCoord) for i in xrange(len(self.lastCoord)): self.miniCards=OnscreenImage( image=self.shuffledCardFaces[i], pos=(self.lastCoord[i][0],0,self.lastCoord[i][2]), scale=(0.03,0.82,0.050)) self.miniCards.reparentTo(self.dummyNode1) def _draw_line_segs(self, parent, points, thickness=1.5): segs = LineSegs() segs.setThickness(thickness) segs.setColor( Vec4(1,0,0,.35) ) if points: segs.moveTo(points[0][0], points[0][1], points[0][2]) for p in points[1:]: segs.drawTo(p[0], p[1], p[2]) lines = NodePath(segs.create()) lines.reparentTo(parent) def recallMemory(self): self.checkList=[] self.checkListFaces=[] self.startCard=0 self.endCard=13 self.cardSet=0 self.bk=OnscreenImage(image="bk.png",scale=(2,1,1)) self.recallCards(self.startCard,self.endCard, self.cardSet,0) self.scaleCards=(0.1,0.1,0.13) scaleCards2=(0.07,0.05,0.10) self.recallMemoryPrompt=OnscreenText( text="List the cards in the sequence as you recall", pos=(0,.45),scale=.045,fg=(0,0,0,.75)) def recallCards(self,startCard,endCard,cardSet,createEntries=1): for i in xrange(startCard,endCard): x=2*(i+1)/(self.numCards+1.0)-1-cardSet*1.75 self.cardsPos.append(x) self.createButtons(i,x) if createEntries==1: self.createEntries(x, cardSet) for image in self.buttonList: image.setTransparency(TransparencyAttrib.MAlpha) def createButtons(self,i,x): self.buttonList.append(DirectButton( image = cardFaces[i],scale=(0.06,0.1,0.095),pos=(x,0,.3), relief=None, command=lambda: self.createCheckButtons(i))) def createCheckButtons(self,i): self.correctCount=0 self.checkList.append(i) self.checkListFaces.append(cardFaces[i]) for i in xrange(len(self.checkList)): x=2*(i+1)/(self.numCards+1.0)-1 self.cards=OnscreenImage(image=self.checkListFaces[i], pos=(x,0,-.2),scale=(0.06,0.1,0.095)) if len(self.checkList)==13: correct=self.testResults() self.results=OnscreenText( text="You recalled %d out of %d correctly"%( correct,self.numCards),pos=(0,-0.85),scale=.1) def testResults(self): for i in xrange(len(self.shuffledCardFaces)): if self.shuffledCardFaces[i]==self.checkListFaces[i]: self.correctCount+=1 return self.correctCount def updateDisplayCards(self): self.numCardsCopy-=1 self.previousCard=self.shuffledCardFacesCopy.pop(0) if len(self.shuffledCardFacesCopy)!=0: self.nextCard=self.shuffledCardFacesCopy[0] else: self.nextCard=False for image in self.imageList: image.destroy() self.displayCards() def displayCards(self): for i in xrange(self.numCardsCopy): x=2*(i+1)/(self.numCards+1.0)-.65 self.cardsPos.append(x) self.imageList.append(OnscreenImage( image="%s"%(self.shuffledCardFacesCopy[i]), pos=(x,0,-.8),scale=(0.05,0.05,0.08))) #we use middle numbers as coordinates def fadeArrow(self,task): self.arrow.setColor(1,0,0,self.fade) return task.cont def setUpBackground(self): self.scale=10 #load grass and set position, scale, and texture self.walls=loader.loadModel("Walls") self.walls.setPos(0,0,0) self.walls.setScale(self.scale,self.scale,self.scale) walltex1 = loader.loadTexture('walltex1.png') self.walls.setTexture(walltex1) #render our object self.walls.reparentTo(render) self.loadColGeomsSet1() self.loadColGeomsSet2() self.setUpBackgroundSupport() def setUpBackgroundSupport(self): for geom in self.colGeoms: self.createCollisionGeom(*geom) cFloorNode=CollisionNode('floorCollision') floorQuad=CollisionPolygon(Point3(5, 0, 0), Point3(-1.5,0,0), Point3(-1.5, -4, 0),Point3(5, -4, 0)) cFloorNode.addSolid(floorQuad) def loadColGeomsSet1(self): self.colGeoms=[ (11,(2.4,-1.80,1),(2.4,-1.80,0),(.55,-1.80,0), (.55,-1.80,1)),#Interior 2b (firsthalf), (1,(5,-.05,0),(5,-.05,1),(-1.5,-.05,1), (-1.5,-.05,0)),#West Wall (2,(-1.5,0,0),(-1.5,0,1),(-1.5,-4,1), (-1.5,-4,0)),#South Edge (5,(0.52,0,0),(0.52,0,1),(0.52,-1.2,1), (0.52,-1.2,0)), #South Wall_1_Interior (3,(0.38,0,1),(0.38,0,0),(0.38,-1.2,0), (0.38,-1.2,1)), #South Wall_1_Exterior (4,(0.38,-1.7,1),(0.38,-1.7,0),(0.38,-4,0),(0.38,-4,1)), #South Wall_2_Exterior (6,(0.52,-1.7,0),(0.52,-1.7,1),(0.52,-4,1),(0.52,-4,0)), #South Wall_2 Interior (7,(1.8,0,1),(1.8,0,0),(1.8,-1.45,0),(1.8,-1.45,1)), #Interior 1 (TV) (8,(1.9,0,0),(1.9,0,1),(1.9,-1.45,1),(1.9,-1.45,0)), #Interior 1b (TV) (9,(2.4,-1.95,0),(2.4,-1.95,1),(.55,-1.95,1), (.55,-1.95,0)), #Interior 2 (firsthalf) (10,(3.95,-1.95,0),(3.95,-1.95,1), (2.7,-1.95,1),(2.7,-1.95,0))] #Interior 2 (secondhalf) def loadColGeomsSet2(self): self.colGeoms+=[ (12,(3.95,-1.80,1),(3.95,-1.80,0), (2.7,-1.80,0), (2.7,-1.80,1)), #Interior 2b (secondhalf) (13,(2.95,-1.9,0),(2.95,-1.9,1),(2.95,-2.1,1), (2.95,-2.1,0)),#North Wall 1 Exterior (firsthalf)E (14,(2.95,-2.48,0),(2.95,-2.48,1),(2.95,-4,1), (2.95,-4,0)),#North Wall 1 Exterior (secondhalf)E (15,(2.7,-1.9,1),(2.7,-1.9,0),(2.7,-2.1,0), (2.7,-2.1,1)), #North Wall 1b Interior (firsthalf) E (16,(2.7,-2.48,1),(2.7,-2.48,0),(2.7,-4,0), (2.7,-4,1)), #North Wall 1b Interior (secondhalf) E (17,(3.82,0,1),(3.82,0,0),(3.82,-.35,0), Point3(3.82,-.35,1)),#North Wall 2 Interior (firsthalf) W (18,(3.82,-1.1,1),(3.82,-1.1,0),(3.82,-1.9,0), Point3(3.82,-1.9,1)),#North Wall 2 Interior (secondhalf) W (19,(4,0,0),(4,0,1),(4,-.35,1), Point3(4,-.35,0)),#North Wall 2 Exterior (firsthalf) W (20,(4,-1.1,0),(4,-1.1,1),(4,-1.9,1), Point3(4,-1.9,0))#North Wall 2 Exterior (secondhalf) W ] def createCollisionGeom(self,n,firstPts,secondPts,thirdPts,fourthPts): collisionNode="wallCollision%d"%n collisionNodeName="cWallNode%d"%n collisionNodeName=CollisionNode(collisionNode) quadName="wallQuad%d"%n quadName=CollisionPolygon(Point3(firstPts),Point3(secondPts), Point3(thirdPts),Point3(fourthPts)) collisionNodeName.addSolid(quadName) self.wallC=self.walls.attachNewNode(collisionNodeName) self.roof=self.loadItems("Roof","rooftex.png",scaleX=6,scaleY=6) self.walls2=self.loadItems("Walls2","walltex2.png") self.grass=self.loadItems("grass",'8CYNDAC0.png') self.floor=self.loadItems("floor","floor.png") self.exterior=self.loadItems("exterior",'brick.png') def setUpItems(self): self.itemList=[] self.scale=10 self.tv=self.loadItems("tv",'tv.png') self.carpet=self.loadItems("carpet","carpet.png") self.white=self.loadItems("white","walltex2.png",8,4) self.painting=self.loadItems("painting","kosbie.png") self.wood=self.loadItems("wood","wood.png",8,4) self.tree=self.loadItems("GroomedTree",None,1,1,.9,(52,-5,0)) self.shelf=self.loadItems("shelf","darkwood.png") self.couches=self.loadItems("couch","leather.png",5,5) self.dining=self.loadItems("chairs","wood.png") self.treasureChest=self.loadItems( "treasurechest","woodpanel.png",1,1,None,(0,0,20)) self.sky=self.loadItems("sky","sky.png",1,1) self.selectionItems = render.attachNewNode("selectionRoot") self.setUpCollisionGeom() def setUpCollisionGeom(self): self.paintingNode=self.loadCollisionPolygon( "painting",self.painting,(3.35,-.07,.45),(3.35,-.07,.8), (2.9,-.07,.8),(2.9,-.07,.45)) self.postNode=self.loadCollisionTube( "post",self.wood,.25,-2,0,.25,-2,.55,.03) self.tvNode=self.loadCollisionPolygon( "tv",self.tv,(1.75,-.35,.78),(1.75,-.35,.5),(1.75,-1.1,.5), (1.75,-1.1,.78)) self.bedNode=self.loadCollisionPolygon( "bed",self.white,(1,-2.7,.17),(.5,-2.7,.17),(.5,-1.9,.17), (1,-1.9,.17)) self.carpetNode=self.loadCollisionPolygon( "carpet",self.carpet,(1.95,-3.15,.05),(2.4,-3.15,.05), (2.4,-2.55,.05),(1.95,-2.55,.05)) self.tableNode=self.loadCollisionPolygon( "table",self.wood,(1,-3.5,.26),(1.45,-3.5,.26), (1.45,-3.1,.26),(1,-3.1,.26)) self.supportSetUpCollisionGeom() def supportSetUpCollisionGeom(self): self.treeNode=self.loadCollisionTube( "tree",self.tree,0,0,0,0,0,7,2) self.shelfNode=self.loadCollisionPolygon( "shelf",self.shelf,(.6,-0.05,.78),(.6,-0.05,0), (.6,-.43,0),(.6,-.43,.78)) self.couchNode1=self.loadCollisionTube( "couch1",self.couches,1.05,-.96,0,1.05,-.96,.2,.2) self.couchNode2=self.loadCollisionTube( "couch2",self.couches,1.45,-.96,0,1.45,-.96,.2,.2) self.couchNode3=self.loadCollisionTube( "couch3",self.couches,1.00,-.16,.1,1.5,-.16,.1,.2) self.dinnerTable=self.loadCollisionPolygon( "dinnerTable",self.dining,(3.6,-.89,.26),(3.6,-.61,.26), (3.1,-.61,.26),(3.1,-.89,.26)) self.dinnerChairNode1=self.loadCollisionTube( "dinnerChair1",self.dining,2.9,-.75,0,2.9,-.75,.2,.1) self.dinnerChairNode2=self.loadCollisionTube( "dinnerChair1",self.dining,3.7,-.75,0,3.7,-.75,.2,.1) self.chestNode=self.loadCollisionTube( "chest",self.treasureChest,.02,.02,.25,.07,.07,.25,.25) self.chestNode.setTag( "openChest","1") self.itemList+=(self.paintingNode,self.postNode,self.tvNode, self.bedNode,self.carpetNode,self.tableNode, self.treeNode,self.shelfNode,self.couchNode1, self.couchNode2,self.couchNode3,self.dinnerTable, self.dinnerChairNode1,self.dinnerChairNode2) self.setTag(self.itemList,"items") def setTag(self): self.itemList+=(self.paintingNode,self.postNode,self.tvNode, self.bedNode,self.carpetNode,self.tableNode, self.treeNode,self.shelfNode, self.couchNode1,self.couchNode2,self.couchNode3, self.dinnerTable,self.dinnerChairNode1, self.dinnerChairNode2) self.setTag(self.itemList,"items") def setTag(self,node,tagKey): for i in xrange(len(node)): node[i].setTag(tagKey,str(i)) def loadItems(self,modelName,texture=None,scaleX=1,scaleY=1, scale=None,pos=(0,0,0)): if scale==None: scale=self.scale modelName=loader.loadModel(modelName) modelName.setPos(pos) modelName.setScale(scale,scale,scale) ts=TextureStage("ts") if texture!=None: modelTex=loader.loadTexture(texture) modelName.setTexture(ts,modelTex) modelName.setTexScale(ts,scaleX,scaleY) modelName.reparentTo(render) return modelName def loadCollisionPolygon(self,modelName,attachGeom,firstPts, secondPts,thirdPts,fourthPts): modelName=CollisionNode(modelName) quadName=CollisionPolygon(Point3(firstPts),Point3(secondPts), Point3(thirdPts),Point3(fourthPts)) modelName.addSolid(quadName) modelName=attachGeom.attachNewNode(modelName) return modelName def loadCollisionTube(self,modelName,attachGeom,x0,y0,z0,x1,y1,z1, radius): modelName=CollisionNode(modelName) cylinder=CollisionTube(x0,y0,z0,x1,y1,z1,radius) modelName.addSolid(cylinder) modelName=attachGeom.attachNewNode(modelName) return modelName def homePage(self): self.introduction=False #self.setUphomePageSFX() self.introButton=DirectButton( image=("introduction.png"),scale=.5,pos=(-0.8,0,-0.65), relief=None,command=self.startIntro) self.introButton.setTransparency(TransparencyAttrib.MAlpha) self.startButton=DirectButton( image=("beginJourney.png"),scale=.5,pos=(+0.8,0,-0.65), relief=None, command=self.startJourney) self.startButton.setTransparency(TransparencyAttrib.MAlpha) self.cylinder=self.loadItems( "cylinder","wood.png",1,1,2,(9,-1.3,20.8)) self.hexagon=self.loadItems( "hexagon","wood.png",1,1,2.5,(9,1.4,20.8)) taskMgr.add(self.rotateMenuItems, 'rotateMenuItems') #def setUphomePageSFX(self): #self.volume=0 #self.circusInTheSky.setVolume(0) #self.circusInTheSky.setLoop(1) #self.circusInTheSky.play() #taskMgr.doMethodLater(.5, self.playCircusInTheSky, # 'Fade in Music', extraArgs = [self]) #def playCircusInTheSky(self,task): #self.volume+=.00125 #self.circusInTheSky.setVolume(self.volume) #return Task.cont def rotateMenuItems(self,task): self.speed=1.5 radius=.5 angle = radians(self.heading) x = cos(angle) * radius y = sin(angle) * radius z = sin(angle) * radius self.heading+=self.speed self.heading%=360 self.cylinder.setH(self.heading) self.hexagon.setH(self.heading) if self.introduction==True: self.cylinder.remove() self.hexagon.remove() return task.done return Task.cont def startJourney(self): #self.circusInTheSky.stop() self.introButton.destroy() self.startButton.destroy() self.initSetUpAssoc() #self.setUp3DEnvironmentIntro() ###########change here def setUp3DEnvironmentIntro(self): self.camera.setP(25) self.Enviro3DDummy=self.createDummyNode("3DEnviroDummy") self.textBlocks,self.color,self.keyBrightenComplete=[],0.01,False self.displayCards() self.displayHelpPanel() taskMgr.doMethodLater(.05,self.displayUserLocation, 'Track User', extraArgs = [self]) self.setUpDirectionalLight() self.displayPriorityArrow() self.accept("arrow_down",self.playFootSteps) self.accept("arrow_up",self.playFootSteps) self.enviroTextBlocks() self.Enviro3DSupportText() def enviroTextBlocks(self): self.enviroTextBlock1=( "1. Here is the priority queue for the shuffled cards") self.enviroTextBlock2=( "2. Toggle displays to show/hide windows") self.enviroTextBlock3=( "3. See your location in the plan") self.textBlocks+=(self.enviroTextBlock1,self.enviroTextBlock2, self.enviroTextBlock3) self.textPos=[(0,-.6),(-.6,.6),(.7,-.4)] def Enviro3DSupportText(self): for i in xrange(len(self.textBlocks)): self.titleText=OnscreenText(text=self.textBlocks[i], pos=self.textPos[i],scale=.058,fg=(1,1,1,1)) self.titleText.reparentTo(self.Enviro3DDummy) taskMgr.doMethodLater(.1, self.init3DActiveEnviro,'3DEnviroEntry') taskMgr.doMethodLater(.15,self.brightenKey,"brightenKey") def init3DActiveEnviro(self,task): self.keyButton=DirectButton( image = 'key.png',scale=(.5,.2,.15),color=(0,0,0,0),pos=(-.5,0,0), relief=None, command=self.setUp3DEnvironmentActive) self.keyButton.setTransparency(TransparencyAttrib.MAlpha) self.keyButton.reparentTo(self.Enviro3DDummy) self.keyButton['state'] = DGG.DISABLED return task.done def brightenKey(self,task): if self.keyBrightenComplete==False: self.brightenSpeed=0.025 if self.color<1: self.color+=self.brightenSpeed self.keyButton.setColor(0,0,0,self.color) return task.again else: self.entryText=OnscreenText(text="[Click the key to begin]", pos=(-.7,.13),scale=.058,fg=(1,1,1,1)) self.entryText.reparentTo(self.Enviro3DDummy) self.keyButton['state'] = DGG.NORMAL task.done else: task.done def setUp3DEnvironmentActive(self): base.useDrive() self.keyBrightenComplete=True self.Enviro3DDummy.removeNode() def setUpDirectionalLight(self): dlight = DirectionalLight('dlight') dlight.setColor(VBase4(0.8, 0.8, 0.5, 1)) dlnp = render.attachNewNode(dlight) dlnp.setHpr(0, -60, 0) render.setLight(dlnp) render.setShaderAuto() def startIntro(self): self.introduction=True self.introButton.destroy() self.startButton.destroy() self.setUpHelp() def setUpHelp(self): self.titleText=OnscreenText(text="Introduction", pos=(-0.85,0.85),scale=.1) self.text = TextNode('helpText') self.textBlocks() self.text.setText(self.textBlock1) textNodePath = aspect2d.attachNewNode(self.text) textNodePath.setScale(0.07) textNodePath.setPos(-1,0,0) self.text.setWordwrap(30.0) self.nextButton=DirectButton( image = 'arrow.png',scale=.15,pos=(0.8,0,-0.6),relief=None, command=self.nextPage ) self.nextButton.setTransparency(TransparencyAttrib.MAlpha) def textBlocks(self): self.textBlock1=("This project tests the effectiveness" +" of along established 'Method of loci', which is a" +" mnemonic device used for memory enhancement which uses" +" visualization to organize and recall information." +" We will be using this technique to memory a set of 13" +" cards (one suit)") self.textBlock2=( "STEP 1 \n\n We create rooms which are connected " + "and unique. These are provided for you." +"\n\n STEP 2 \n\n Associate each card with visual " +"objects (eg. 2 ---> Swan)" +"\n\n STEP 3 \n\n We 'place' the cards at specific " +"locations in sequence so relationship between " +"the location and item are made." +"\n\n STEP 4 \n\n Test the associations we've made") def nextPage(self): textNodePath = aspect2d.attachNewNode(self.text) textNodePath.setPos(-1,0,.5) self.nextButton.destroy() self.text.setText(self.textBlock2) self.nextButton=DirectButton( image = 'arrow.png',scale=.15,pos=(0.8,0,-0.6),relief=None, command=(self.clear)) self.nextButton.setTransparency(TransparencyAttrib.MAlpha) def clear(self): self.text.clearText() self.titleText.clearText() self.nextButton.destroy() self.homePage() def initSetUpAssoc(self): self.bk=OnscreenImage(image="bk.png",scale=(2,1,1)) self.inputs=dict() self.cardsPositions=[] self.imageListFaces,self.textObjs,self.entries=[],[],[] self.numCardsPage1=7 self.startCard=0 self.endCard=7 self.cardSet=0 self.callCards(self.startCard,self.endCard, self.cardSet) self.goAhead=[] self.button1=loader.loadMusic("button1.wav") self.assocTextBlocks() taskMgr.doMethodLater(.1, lambda task: self.createAssocHelperText( task,self.assocTextBlock1),'assocHelperText') def assocTextBlocks(self): self.assocTextBlock1=( "[Enter a word you strongly associated with each card]" +"\n Helpful Hint: Use less abstract and more descriptive words") self.assocTextBlock2=( "[That's great! Finish up the rest!]") def createAssocHelperText(self,task,text): self.updateFade() try: self.assocText.destroy() self.assocText=OnscreenText( text=text, pos=(0,-.2),scale=.05,fg=(0,0,0,self.fade)) except: self.assocText=OnscreenText( text=text, pos=(0,-.2),scale=.05,fg=(0,0,0,self.fade)) return task.again def callCards(self,startCard,endCard,cardSet,createEntries=1, scaleCards=(0.1,0.1,0.13)): for i in xrange(startCard,endCard): x=2*(i+1)/(self.numCardsPage1+1.0)-1-cardSet*1.75 self.cardsPositions.append(x) self.imageListFaces.append( OnscreenImage(image="%s"%(cardFaces[i]), pos=(x,0,.3),scale=scaleCards)) self.textObjs.append(OnscreenText(text=str(i),pos=(x,0))) #we use middle numbers as coordinates self.cardName=cardNames[i] if createEntries==1: self.createEntries(x, cardSet) def createEntries(self,x, cardSet): self.entries.append( DirectEntry(text = "" ,scale=.02,pos=(x-0.1,0.1,0.1), command=(lambda textEntered: self.storeAssoc (textEntered, x, cardSet)), numLines = 2)) def clearPage(self): for image in self.imageListFaces: image.destroy() for textObj in self.textObjs: textObj.destroy() for entry in self.entries: entry.destroy() for image in self.goAhead: image.destroy() self.assocText.destroy() self.clearBK() def clearBK(self): self.bk.destroy() def storeAssoc(self,textEntered, x, cardSet): index=int((x+cardSet*1.75+.75)/0.25) self.inputs[cardNames[index]]=textEntered self.greenDot=OnscreenImage( image="greenDot.png",pos=(x,0,.55),scale=(.25,1,.25)) self.greenDot.setTransparency(TransparencyAttrib.MAlpha) self.goAhead.append(self.greenDot) self.button1.play() if len(self.inputs)>6 and cardSet==0: taskMgr.remove('assocHelperText') taskMgr.doMethodLater(.1, lambda task: self.createAssocHelperText( task,self.assocTextBlock2),'assocHelperText') self.startCard=7 self.endCard=13 self.clearBK() self.cardSet=1 self.bk=OnscreenImage(image="bk.png",scale=(2,1,1)) self.callCards(self.startCard,self.endCard, self.cardSet) if len(self.inputs)>12 and cardSet==1: taskMgr.remove('assocHelperText') self.clearPage() self.setUp3DEnvironmentIntro() def startGame(self): self.bk.destroy()
class Timer: def __init__(self, style): """ Timer class with fun pictures @param style: 0 = SUN, 1 = MOON, 2 = GUN @type style: int """ self.style = style VirtualFileSystem.getGlobalPtr().mount(Filename("mf/timer.mf"), ".", VirtualFileSystem.MFReadOnly) self.egg = loader.loadModel("timer.egg") self.img = None self.interval = None self.types[style](self) def create_sun(self): """ Creates the sun timer """ # load image self.img = OnscreenImage(image=self.egg.find('**/sun'), pos=(1.15, 0, 0.75), color=(255, 255, 0, 1), scale=0.25) # interval self.interval = LerpFunc(self.run_interval, fromData=1, toData=0, duration=TIME) self.interval.start() return def create_moon(self): """ Creates the moon timer """ # load image self.img = OnscreenImage(image=self.egg.find('**/moon-quarter'), pos=(0, 0, 0), color=(1, 1, 1, 1), scale=0.25) # interval self.interval = LerpFunc(self.run_interval, fromData=1, toData=0, duration=TIME) self.interval.start() return def create_gun(self): """ Creates the gun timer """ # load image self.img = OnscreenImage(image=self.egg.find('**/gun-0'), pos=(1.05, 0, 0.75), scale=0.25) # interval self.interval = LerpFunc(self.run_interval, fromData=1, toData=0, duration=TIME) self.interval.start() return def run_interval(self, c): if self.style == SUN: self.img.setColor((1, c, 0, 1)) self.img.setPos(1.15-(c/4), 0, 0.75+(math.sin(math.pi*c)/10)) elif self.style == MOON: self.img.setColor((1, c, c, 1)) self.img.setPos(0.9+(c/4), 0, 0.75+(math.sin(math.pi*c)/10)) elif self.style == GUN: self.img.setHpr(0, 0, 360*(1-c)-60) if c % (1 / 6) < 0.05: if c % (1 / 6) > 0.025: self.img.setColor((1, 40*(c % (1 / 6)), 40*(c % (1 / 6)), 1)) else: self.img.setImage(self.egg.find('**/gun-{}'.format(6 - (round(c / (1 / 6)))))) self.img.setColor((1, 1-40*(c % (1 / 6)), 1-40*(c % (1 / 6)), 1)) else: self.img.setColor((1, 1, 1, 1)) def annihilate(self): self.interval.finish() self.img.destroy() loader.unloadModel(self.egg) VirtualFileSystem.getGlobalPtr().unmount("mf/timer.mf") del self types = { SUN: create_sun, MOON: create_moon, GUN: create_gun }
class ImagePresenter(MessagePresenter): """ A display that can present images with a fixed (or optionally randomly chosen) position, size and other display properties (e.g. coloring). See also MessagePresenter for usage information. """ def __init__(self, pos=(-0.25,0.5), # position of the image center in the aspect2d viewport # may also be a callable object (e.g.a draw from a random number generator) scale=0.2, # scaling of the image; may also be callable rotation=(0,0,0), # yaw, pitch, roll -- the most relevant is the roll coordinate; may also be callable color=(1,1,1,1), # (r,g,b,a) image color renderviewport=None, # the parent viewport if desired image='blank.tga', # the initial image to present *args,**kwargs ): """Construct a new ImagePresenter.""" MessagePresenter.__init__(self,*args,**kwargs) self.pos = pos self.scale = scale self.rotation = rotation self.color = color self.renderviewport = renderviewport # set up the text panel... #if not (type(self.pos) is List or type(self.pos) is tuple): #pos = self.pos() #if callable(self.scale): #scale = self.scale() #if callable(self.rotation): #rotation = self.rotation() #if callable(self.color): #color = self.color() self.icon = OnscreenImage(image=image,pos=(pos[0],0,pos[1]),scale=scale,hpr=rotation,color= ((0,0,0,0) if image=="blank.tga" else self.color),parent=self.renderviewport) self.icon.setTransparency(TransparencyAttrib.MAlpha) def _present(self,message): self.icon.setImage(message.strip()) self.icon.setTransparency(TransparencyAttrib.MAlpha) # select remaining properties randomly, if applicable # if callable(self.pos): # p = self.pos() # self.icon.setPos(p[0],p[1],p[2]) # if callable(self.scale): # self.icon.setScale(self.scale()) # if callable(self.rotation): # rot = self.rotation() # self.icon.setHpr(rot[0],rot[1],rot[2]) col = self.color #() if callable(self.color) else self.color self.icon.setColor(col[0],col[1],col[2],col[3]) self.marker(222) def _unpresent(self): try: self.marker(223) self.icon.setColor(0,0,0,0) except: pass def destroy(self): self.icon.removeNode() def precache(self,message): loader.loadTexture(message)