Exemple #1
0
 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()
Exemple #2
0
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)
Exemple #3
0
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()
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
    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) 
Exemple #7
0
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
    }
Exemple #10
0
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)