Beispiel #1
0
class Game():

    def __init__(self, _parent=None):
        self.parent = _parent

        # Containers
        self.game_objects = {}
        self.game_doors = {}
        self.game_objects_np = render.attachNewNode("Game_Objects")
        self.game_doors_np = render.attachNewNode("Player_Doors")
        self.game_doors_np.setPos(0, 0, 0)
        self.game_counter_node = None
        self.game_collector_nodes = []

        self.redDudesCount = 0
        self.blueDudesCount = 0

        # Physics world
        self.physics_world = None
        self.builder = Builder(self)

        # level lights
        self.directLight = None

        # Dude class
        self.dude = None
        self.spawnPoints = self.builder.spawnPoints

        # HUD
        self.hud = Hud()

        # Lightshow
        self.elapsed = 0.0



    def start(self, levelID, winCondition=25):
        self.winCondition = winCondition

        self.loadLevel("assets/level{}".format(levelID))
        self.loadLights()

        # player
        self.loadPlayer("default")
        self.loadDude()

        # Timer
        taskMgr.add(self.update, "Game_Update_Task", 0)

        self.hud.show()

        # start the Lightshow
        taskMgr.add(self.discoLightTask, "the lightshow")

    def stop(self):
        self.player.stop()
        self.dude.stop()
        self.builder.cleanup()
        self.physics_world = None
        render.clearLight()
        self.directLight = None
        self.hud.hide()
        taskMgr.remove("the lightshow")

    def update(self, task):

        if self.game_counter_node is None:
            return

        ghost = self.game_counter_node.node()
        for node in ghost.getOverlappingNodes():

            if "red" in node.name:
                self.redDudesCount += 1
                self.physics_world.removeRigidBody(self.dude.dudes[node.name].node())
                self.dude.dudes[node.name].removeNode()
                self.hud.update(self.redDudesCount, self.blueDudesCount)
                del self.dude.dudes[node.name]
                break


            elif "blue" in node.name:
                self.blueDudesCount += 1
                self.physics_world.removeRigidBody(self.dude.dudes[node.name].node())
                self.dude.dudes[node.name].removeNode()
                self.hud.update(self.redDudesCount, self.blueDudesCount)
                del self.dude.dudes[node.name]
                break

        if self.redDudesCount > self.blueDudesCount:
            base.messenger.send("lostGame")
            return Task.done
        elif self.blueDudesCount >= self.winCondition:
            base.messenger.send("wonGame")
            return Task.done

        for collectorGhostNP in self.game_collector_nodes:
            collectorGhost = collectorGhostNP.node()
            for node in collectorGhost.getOverlappingNodes():
                if "red" in node.name:
                    self.physics_world.removeRigidBody(self.dude.dudes[node.name].node())
                    self.dude.dudes[node.name].removeNode()
                    self.hud.update(self.redDudesCount, self.blueDudesCount)
                    del self.dude.dudes[node.name]

        return Task.cont

    def setPhysicsWorld(self, _physicsworld):
    	self.physics_world = _physicsworld

    #### LOADERS ####
    def loadLevel(self, _filename):
        self.builder.parseEggFile(_filename)


    def loadLights(self):
        # Set a simple light
        dlight = DirectionalLight('DirectLight')
        dlnp = render.attachNewNode(dlight)
        dlnp.setHpr(-30, 0, 0)
        render.setLight(dlnp)
        self.directLight = dlnp

        self.discoLights = []

        p1 = PointLight("PointLight1")
        p1.setColor(VBase4(1, 0, 0, 1))
        p1.setAttenuation((0.08, 0, 0.05))
        p1np = render.attachNewNode(p1)
        p1np.setPos(0, -5, 0)
        render.setLight(p1np)
        self.discoLights.append(p1)

        p2 = PointLight("PointLight2")
        p2.setColor(VBase4(0, 1, 0, 1))
        p2.setAttenuation((0.08, 0, 0.05))
        p2np = render.attachNewNode(p2)
        p2np.setPos(5, -5, 0)
        render.setLight(p2np)
        self.discoLights.append(p2)

        p3 = PointLight("PointLight3")
        p3.setColor(VBase4(0, 0, 1, 1))
        p3.setAttenuation((0.08, 0, 0.05))
        p3np = render.attachNewNode(p3)
        p3np.setPos(-5, -5, 0)
        render.setLight(p3np)
        self.discoLights.append(p3)

        p4 = PointLight("PointLight4")
        p4.setColor(VBase4(0, 0, 1, 1))
        p4.setAttenuation((0.08, 0, 0.05))
        p4np = render.attachNewNode(p4)
        p4np.setPos(-5, -5, 5)
        render.setLight(p4np)
        self.discoLights.append(p4)

        p5 = PointLight("PointLight1")
        p5.setColor(VBase4(0, 0, 1, 1))
        p5.setAttenuation((0.08, 0, 0.05))
        p5np = render.attachNewNode(p5)
        p5np.setPos(0, -5, 5)
        render.setLight(p5np)
        self.discoLights.append(p5)

        p6 = PointLight("PointLight1")
        p6.setColor(VBase4(0, 0, 1, 1))
        p6.setAttenuation((0.08, 0, 0.05))
        p6np = render.attachNewNode(p6)
        p6np.setPos(5, -5, 5)
        render.setLight(p6np)
        self.discoLights.append(p6)

    def discoLightTask(self, task):
        self.elapsed += globalClock.getDt()

        if self.elapsed > 0.75:
            for light in self.discoLights:
                newcolor = choice(
                    [VBase4(0, 0, 1, 1),
                    VBase4(0, 1, 0, 1),
                    VBase4(1, 0, 0, 1),
                    VBase4(0, 1, 1, 1),
                    VBase4(1, 0, 1, 1),
                    VBase4(1, 1, 0, 1),]
                    )
                light.setColor(newcolor)
            self.elapsed = 0.0
        return task.cont

    def loadPlayer(self, _name):
        self.player = Player(self)
        self.player.start()

    def loadDude(self):
        self.dude = Dude(self)
        self.dude.start()
Beispiel #2
0
class Main(ShowBase, FSM):
    """Main function of the application
    initialise the engine (ShowBase)"""
    def __init__(self):
        """initialise the engine"""
        ShowBase.__init__(self)
        FSM.__init__(self, "FSM-Game")

        #
        # BASIC APPLICATION CONFIGURATIONS
        #
        # disable pandas default camera driver
        self.disableMouse()
        # set background color to black
        self.setBackgroundColor(0, 0, 0)
        # set antialias for the complete sceen to automatic
        self.render.setAntialias(AntialiasAttrib.MAuto)
        # shader generator
        render.setShaderAuto()

        #
        # CONFIGURATION LOADING
        #
        # load given variables or set defaults
        # check if audio should be muted
        mute = ConfigVariableBool("audio-mute", False).getValue()
        if mute:
            self.disableAllAudio()
        else:
            self.enableAllAudio()
        # check if particles should be enabled
        particles = ConfigVariableBool("particles-enabled", True).getValue()
        if particles:
            self.enableParticles()
        # check if the config file hasn't been created
        if not os.path.exists(prcFile):
            # get the displays width and height
            w = self.pipe.getDisplayWidth()
            h = self.pipe.getDisplayHeight()
            # set window properties
            # clear all properties not previously set
            base.win.clearRejectedProperties()
            # setup new window properties
            props = WindowProperties()
            # Fullscreen
            props.setFullscreen(True)
            # set the window size to the screen resolution
            props.setSize(w, h)
            # request the new properties
            base.win.requestProperties(props)
        elif base.appRunner:
            # As when the application is started as appRunner instance
            # it doesn't respect our loadPrcFile configurations specific
            # to the window, hence we need to manually set them here.
            for dec in range(mainConfig.getNumDeclarations()):
                #TODO: Check for all window specific variables like
                #      fullscreen, screen size, title and window
                #      decoration that you have in your configuration
                #      and set them by your own.
                if mainConfig.getVariableName(dec) == "fullscreen":
                    if not mainConfig.getDeclaration(dec).getBoolWord(0): break
                    # get the displays width and height
                    w = self.pipe.getDisplayWidth()
                    h = self.pipe.getDisplayHeight()
                    # set window properties
                    # clear all properties not previously set
                    base.win.clearRejectedProperties()
                    # setup new window properties
                    props = WindowProperties()
                    # Fullscreen
                    props.setFullscreen(True)
                    # set the window size to the screen resolution
                    props.setSize(w, h)
                    # request the new properties
                    base.win.requestProperties(props)
                    break

        # automatically safe configuration at application exit
        base.exitFunc = self.__writeConfig

        # due to the delayed window resizing and switch to fullscreen
        # we wait some time until everything is set so we can savely
        # proceed with other setups like the menus
        if base.appRunner:
            # this behaviour only happens if run from p3d files and
            # hence the appRunner is enabled
            taskMgr.doMethodLater(0.5,
                                  self.postInit,
                                  "post initialization",
                                  extraArgs=[])
        else:
            self.postInit()

    def postInit(self):
        #
        # initialize game content
        #
        base.cTrav = CollisionTraverser("base collision traverser")
        base.pusher = CollisionHandlerPusher()
        self.menu = Menu()
        self.credits = Credits()
        self.charSelection = CharacterSelection()
        self.levelSelection = LevelSelection()
        self.koScreen = KoScreen()
        self.hud = Hud()
        self.menuMusic = loader.loadMusic("assets/audio/menuMusic.ogg")
        self.menuMusic.setLoop(True)
        self.fightMusic = loader.loadMusic("assets/audio/fightMusic.ogg")
        self.fightMusic.setLoop(True)
        base.audio3d = Audio3DManager(base.sfxManagerList[0], camera)

        #
        # Event handling
        #
        self.accept("escape", self.__escape)

        #
        # Start with the menu
        #
        self.request("Menu")

    #
    # FSM PART
    #
    def enterMenu(self):
        show_cursor()
        self.accept("Menu-Start", self.request, ["CharSelection"])
        self.accept("Menu-Credits", self.request, ["Credits"])
        self.accept("Menu-Quit", self.quit)
        self.ignore("KoScreen-Back")
        self.koScreen.hide()
        self.menu.show()
        if self.menuMusic.status() != AudioSound.PLAYING:
            self.menuMusic.play()
        if self.fightMusic.status() == AudioSound.PLAYING:
            self.fightMusic.stop()

    def exitMenu(self):
        self.ignore("Menu-Start")
        self.ignore("Menu-Credits")
        self.ignore("Menu-Quit")
        self.menu.hide()

    def enterCredits(self):
        self.accept("Credits-Back", self.request, ["Menu"])
        self.koScreen.hide()
        self.credits.show()

    def exitCredits(self):
        self.ignore("Credits-Back")
        self.credits.hide()

    def enterCharSelection(self):
        self.accept("CharSelection-Back", self.request, ["Menu"])
        self.accept("CharSelection-Start", self.request, ["LevelSelection"])
        self.charSelection.show()

    def exitCharSelection(self):
        self.ignore("CharSelection-Start")
        self.ignore("CharSelection-Back")
        self.charSelection.hide()
        self.selectedChar1 = self.charSelection.selectedCharacter1
        self.selectedChar2 = self.charSelection.selectedCharacter2

    def enterLevelSelection(self):
        self.accept("LevelSelection-Back", self.request, ["CharSelection"])
        self.accept("LevelSelection-Start", self.request, ["Game"])
        self.levelSelection.show()

    def exitLevelSelection(self):
        self.ignore("LevelSelection-Start")
        self.ignore("LevelSelection-Back")
        self.levelSelection.hide()

    def enterGame(self):
        # main game code should be called here
        self.arena = Arena(self.levelSelection.selectedLevel)
        self.arena.start()
        self.camera.setPos(0, -5, 1.25)
        self.player = Player(0, self.selectedChar1, "p1")
        self.player2 = Player(1, self.selectedChar2, "p2")
        self.player.setEnemy(self.player2.collisionNodeName)
        self.player2.setEnemy(self.player.collisionNodeName)
        self.player.start(self.arena.getStartPos(1))
        self.player2.start(self.arena.getStartPos(2))
        self.taskMgr.add(self.updateWorldCam, "world camera update task")
        self.accept("gameOver", self.gameOver)
        self.hud.show()

        def lifeChanged(charId, health):
            base.messenger.send("hud_setLifeBarValue", [charId, health])

        self.accept("lifeChanged", lifeChanged)
        hide_cursor()
        if self.fightMusic.status() != AudioSound.PLAYING:
            self.fightMusic.play()
        if self.menuMusic.status() == AudioSound.PLAYING:
            self.menuMusic.stop()

    def exitGame(self):
        # cleanup for game code
        self.taskMgr.remove("world camera update task")
        self.player.stop()
        self.player2.stop()
        del self.player
        del self.player2
        self.arena.stop()
        self.ignore("gameOver")
        self.ignore("lifeChanged")
        self.hud.hide()

    #
    # FSM PART END
    #

    #
    # BASIC FUNCTIONS
    #
    def gameOver(self, LoosingCharId):
        show_cursor()
        winningChar = 1
        if LoosingCharId == 0:
            winningChar = 2
        self.accept("KoScreen-Back", self.request, ["Credits"])
        self.koScreen.show(winningChar)

    def updateWorldCam(self, task):
        playerVec = self.player.getPos() - self.player2.getPos()
        playerDist = playerVec.length()
        x = self.player.getX() + playerDist / 2.0
        self.camera.setX(x)

        zoomout = False
        if not self.cam.node().isInView(self.player.getPos(self.cam)):
            camPosUpdate = -2 * globalClock.getDt()
            self.camera.setY(self.camera, camPosUpdate)
            zoomout = True
        if not self.cam.node().isInView(self.player2.getPos(self.cam)):
            camPosUpdate = -2 * globalClock.getDt()
            self.camera.setY(self.camera, camPosUpdate)
            zoomout = True
        if not zoomout:
            if self.camera.getY() < -5:
                camPosUpdate = 2 * globalClock.getDt()
                self.camera.setY(self.camera, camPosUpdate)
        return task.cont

    def __escape(self):
        if self.state == "Menu":
            self.quit()
        elif self.state == "LevelSelection":
            self.request("CharSelection")
        else:
            self.request("Menu")

    def quit(self):
        """This function will stop the application"""
        self.userExit()

    def __writeConfig(self):
        """Save current config in the prc file or if no prc file exists
        create one. The prc file is set in the prcFile variable"""
        page = None

        #TODO: get values of configurations here
        particles = "#f" if not base.particleMgrEnabled else "#t"
        volume = str(round(base.musicManager.getVolume(), 2))
        mute = "#f" if base.AppHasAudioFocus else "#t"
        #TODO: add any configuration variable name that you have added
        customConfigVariables = [
            "", "particles-enabled", "audio-mute", "audio-volume"
        ]
        if os.path.exists(prcFile):
            # open the config file and change values according to current
            # application settings
            page = loadPrcFile(Filename.fromOsSpecific(prcFile))
            removeDecls = []
            for dec in range(page.getNumDeclarations()):
                # Check if our variables are given.
                # NOTE: This check has to be done to not loose our base or other
                #       manual config changes by the user
                if page.getVariableName(dec) in customConfigVariables:
                    decl = page.modifyDeclaration(dec)
                    removeDecls.append(decl)
            for dec in removeDecls:
                page.deleteDeclaration(dec)
            # NOTE: particles-enabled and audio-mute are custom variables and
            #       have to be loaded by hand at startup
            # Particles
            page.makeDeclaration("particles-enabled", particles)
            # audio
            page.makeDeclaration("audio-volume", volume)
            page.makeDeclaration("audio-mute", mute)
        else:
            # Create a config file and set default values
            cpMgr = ConfigPageManager.getGlobalPtr()
            page = cpMgr.makeExplicitPage("%s Pandaconfig" % appName)
            # set OpenGL to be the default
            page.makeDeclaration("load-display", "pandagl")
            # get the displays width and height
            w = self.pipe.getDisplayWidth()
            h = self.pipe.getDisplayHeight()
            # set the window size in the config file
            page.makeDeclaration("win-size", "%d %d" % (w, h))
            # set the default to fullscreen in the config file
            page.makeDeclaration("fullscreen", "1")
            # particles
            page.makeDeclaration("particles-enabled", "#t")
            # audio
            page.makeDeclaration("audio-volume", volume)
            page.makeDeclaration("audio-mute", "#f")
        # create a stream to the specified config file
        configfile = OFileStream(prcFile)
        # and now write it out
        page.write(configfile)
        # close the stream
        configfile.close()
Beispiel #3
0
class Game(GameState):
    def do_setup(self, level):
        super(Game, self).do_setup()

        self.level = level

        self.setup_panda()
        self.level.setup_entities(self.entities)
        self.setup_input()
        self.setup_controllers()
        self.setup_hud()
        self.setup_logic()
        self.enter_transition()

        self.events.event('panda-escape').connect(self.enter_menu)
        self.events.event('panda-p').connect(self.toggle_pause)

        self.manager.enter_state(
            GameMessage,
            message=(('You have to kill %i pigeons in this level...\n' +
                      'Can you make it?') % self.total_pigeons))

    def enter_transition(self):
        self._transition_bg = ui.ImageEntity(entities=self.entities,
                                             image='hud/red-bg.png')
        self._transition_bg.alpha = 1.0
        self._transition_bg.fade_out()

    def leave_transition(self, next_st='menu'):
        self._transition_bg.fade_in().add_next(
            task.run(lambda: self.manager.leave_state(last_state=next_st)))

    def enter_menu(self):
        self.manager.enter_state('menu-noload', None, 'ingame')

    @weak_slot
    def on_kill_pigeon(self):
        self.hud.dec_counter('pigeons', 1)
        self.dead_pigeons += 1
        if self.dead_pigeons >= self.total_pigeons:
            self.win_game()

    @weak_slot
    def on_kill_boy(self):
        self.fail_game(
            random.choice([
                'You are dead!', 'Was it that hard to stay alive?',
                "Your soul is burning in hell..."
            ]))

    @weak_slot
    def on_finish_time(self):
        self.fail_game(
            random.choice([
                'No more time for you!', 'Too slow man...',
                'Hurry up the next time!'
            ]))

    def win_game(self):
        if self.manager.current == self:
            self.manager.enter_state(
                GameMessage, 'YOU WON!\n'
                'This was a show-case level of an in-development game,\n'
                'there is more to come in the future.', 'quit')

    def fail_game(self, reason):
        if self.manager.current == self:
            msg = random.choice([
                'LOOOOOOOOSER', 'You lost!', 'What a pity!',
                'Hey, no luck today!'
            ])
            self.manager.enter_state(GameMessage, reason + '\n' + msg, 'retry')

    @weak_slot
    def on_place_stick(self):
        if self.player_ctl.can_place_stick:
            self.num_sticks -= 1
            if self.num_sticks == 0:
                self.player_ctl.can_place_stick = False
            self.hud.set_counter('sticks', self.num_sticks)

    def highlight_stick_task(self, timer):
        pos = self.player_ctl.get_place_position(5)
        best = self.player_ctl.laser.best_stick(pos)
        if best != self._curr_best_stick:
            if self._curr_best_stick:
                self._curr_best_stick.unhighlight()
            if self.player_ctl.can_place_stick:
                self._curr_best_stick = best
                if best:
                    best.highlight()
        return task.running

    def do_update(self, timer):
        super(Game, self).do_update(timer)

    @weak_slot
    def on_shader_change(self, cfg):
        if cfg.value:
            self.glow_filter.enable(self.manager.panda)
        else:
            self.glow_filter.disable()

    @weak_slot
    def on_control_change(self, cfg):
        self.player_input.unassoc_action(cfg.name)
        if cfg.value:
            self.player_input.assoc(cfg.name, cfg.value)

    def setup_panda(self):
        self.glow_filter = shader.GlowFilter()

        panda = self.manager.panda
        if GlobalConf().path('game.shader').value:
            self.glow_filter.enable(panda)
        panda.relative_mouse()
        panda.loop_music(self.level.music)

    def setup_input(self):
        self.player_input = GameInput()
        self.camera_input = GameInput(CAMERA_INPUT_MAP)
        self.events.connect(self.player_input)
        self.events.connect(self.camera_input)
        self.tasks.add(self.player_input)
        self.tasks.add(self.camera_input)

        self.player_input.assoc('on_steer', 'panda-mouse-move')

        cfg = GlobalConf().path('game.player0.keys')
        for c in cfg.childs():
            if c.value:
                self.player_input.assoc(c.name, c.value)
            c.on_conf_change += self.on_control_change
        GlobalConf ().path ('game.shader').on_conf_change += \
            self.on_shader_change

    def setup_controllers(self):
        self.camera_ctl = CameraController(entities=self.entities,
                                           camera=base.camera)
        self.player_ctl = PlayerController(entities=self.entities,
                                           delegate=self.level.boy)
        self.level.boy.connect(self.camera_ctl)
        self.camera_input.connect(self.camera_ctl)
        self.player_input.connect(self.player_ctl)

    def setup_hud(self):
        self.hud = Hud(entities=self.entities)
        self.hud.add_counter('clock', 'hud/clock.png')
        self.hud.add_counter('pigeons', 'hud/pigeon.png')
        self.hud.add_counter('sticks', 'hud/stick.png')
        self.hud.hide()

    def setup_logic(self):
        total_pigeons = 0
        for f in self.level.flocks:
            total_pigeons += len(f.boids)
            for b in f.boids:
                b.on_death += self.on_kill_pigeon

        self.total_pigeons = total_pigeons
        self.dead_pigeons = 0
        self.level.boy.on_death += self.on_kill_boy

        self.num_sticks = self.level.max_sticks
        self.player_ctl.on_place_stick_down += self.on_place_stick
        self.hud.set_counter('sticks', self.num_sticks)

        self.timer = self.tasks.add(
            task.TimerTask(duration=self.level.max_time))
        self.timer.on_tick = lambda: self.hud.set_counter(
            'clock', int(self.timer.remaining))
        self.timer.on_finish = self.on_finish_time

        self.tasks.add(self.highlight_stick_task)
        self._curr_best_stick = None

        self.pigeon_food = []

    def do_sink(self):
        super(Game, self).do_sink()
        if self.manager.current.state_name == 'menu-noload':
            for x in self.entities.entities:
                if isinstance(x, task.Task):
                    x.pause()
        self.events.quiet = True
        self.hud.soft_hide()
        self.timer.pause()

    def do_unsink(self, action='continue'):
        super(Game, self).do_unsink()
        self.manager.panda.relative_mouse()
        self.tasks.resume()
        for x in self.entities.entities:
            if isinstance(x, task.Task):
                x.resume()
        if action == 'continue':
            self.events.quiet = False
            self.hud.soft_show()
            self.timer.resume()
        elif action == 'quit':
            self.leave_transition()
        elif action == 'retry':
            self.leave_transition('game')

    def do_release(self):
        self.level.dispose()  # TODO: To entity!
        self.glow_filter.disable()
        super(Game, self).do_release()
Beispiel #4
0
class Game (GameState):

    def do_setup (self, level):
        super (Game, self).do_setup ()
                
        self.level = level
        
        self.setup_panda ()
        self.level.setup_entities (self.entities)
        self.setup_input ()
        self.setup_controllers ()
        self.setup_hud ()
        self.setup_logic ()
        self.enter_transition ()
        
        self.events.event ('panda-escape').connect (self.enter_menu)
        self.events.event ('panda-p').connect (self.toggle_pause)

        self.manager.enter_state (
            GameMessage, message =
            (('You have to kill %i pigeons in this level...\n' +
             'Can you make it?') % self.total_pigeons))

    def enter_transition (self):
        self._transition_bg = ui.ImageEntity (entities = self.entities,
                                              image    = 'hud/red-bg.png')
        self._transition_bg.alpha = 1.0
        self._transition_bg.fade_out ()

    def leave_transition (self, next_st = 'menu'):
        self._transition_bg.fade_in ().add_next (task.run (lambda:
            self.manager.leave_state (last_state = next_st)))

    def enter_menu (self):
        self.manager.enter_state ('menu-noload', None, 'ingame')        
        
    @weak_slot
    def on_kill_pigeon (self):
        self.hud.dec_counter ('pigeons', 1)
        self.dead_pigeons += 1
        if self.dead_pigeons >= self.total_pigeons:
            self.win_game ()

    @weak_slot
    def on_kill_boy (self):
        self.fail_game (random.choice (['You are dead!',
                                        'Was it that hard to stay alive?',
                                        "Your soul is burning in hell..."]))

    @weak_slot
    def on_finish_time (self):
        self.fail_game (random.choice (['No more time for you!',
                                        'Too slow man...',
                                        'Hurry up the next time!']))
        
    def win_game (self):
        if self.manager.current == self:
            self.manager.enter_state (
                GameMessage,
                'YOU WON!\n'
                'This was a show-case level of an in-development game,\n'
                'there is more to come in the future.',
                'quit')
            
    def fail_game (self, reason):
        if self.manager.current == self:
            msg = random.choice (['LOOOOOOOOSER', 'You lost!', 'What a pity!',
                                  'Hey, no luck today!'])
            self.manager.enter_state (GameMessage, reason + '\n' + msg, 'retry')
    
    @weak_slot
    def on_place_stick (self):
        if self.player_ctl.can_place_stick:
            self.num_sticks -= 1
            if self.num_sticks == 0:
                self.player_ctl.can_place_stick = False
            self.hud.set_counter ('sticks', self.num_sticks)

    def highlight_stick_task (self, timer):
        pos = self.player_ctl.get_place_position (5)
        best = self.player_ctl.laser.best_stick (pos)
        if best != self._curr_best_stick:
            if self._curr_best_stick:
                self._curr_best_stick.unhighlight ()
            if self.player_ctl.can_place_stick:
                self._curr_best_stick = best
                if best:
                    best.highlight ()
        return task.running
    
    def do_update (self, timer):
        super (Game, self).do_update (timer)

    @weak_slot
    def on_shader_change (self, cfg):
        if cfg.value:
            self.glow_filter.enable (self.manager.panda)
        else:
            self.glow_filter.disable ()
    
    @weak_slot
    def on_control_change (self, cfg):
        self.player_input.unassoc_action (cfg.name)
        if cfg.value:
            self.player_input.assoc (cfg.name, cfg.value)
    
    def setup_panda (self):
        self.glow_filter = shader.GlowFilter ()
        
        panda = self.manager.panda
        if GlobalConf ().path ('game.shader').value:
            self.glow_filter.enable (panda)        
        panda.relative_mouse ()
        panda.loop_music (self.level.music)

    def setup_input (self):
        self.player_input = GameInput ()
        self.camera_input = GameInput (CAMERA_INPUT_MAP)
        self.events.connect (self.player_input)
        self.events.connect (self.camera_input)
        self.tasks.add (self.player_input)
        self.tasks.add (self.camera_input)        

        self.player_input.assoc ('on_steer', 'panda-mouse-move')

        cfg = GlobalConf ().path ('game.player0.keys')
        for c in cfg.childs ():
            if c.value:
                self.player_input.assoc (c.name, c.value)
            c.on_conf_change += self.on_control_change
        GlobalConf ().path ('game.shader').on_conf_change += \
            self.on_shader_change

    def setup_controllers (self):
        self.camera_ctl = CameraController (
            entities = self.entities,
            camera = base.camera)
        self.player_ctl = PlayerController (
            entities = self.entities,
            delegate = self.level.boy)
        self.level.boy.connect (self.camera_ctl)
        self.camera_input.connect (self.camera_ctl)
        self.player_input.connect (self.player_ctl)
    
    def setup_hud (self):
        self.hud = Hud (entities = self.entities)
        self.hud.add_counter ('clock',   'hud/clock.png')
        self.hud.add_counter ('pigeons', 'hud/pigeon.png')
        self.hud.add_counter ('sticks',  'hud/stick.png')
        self.hud.hide ()
    
    def setup_logic (self):
        total_pigeons = 0
        for f in self.level.flocks:
            total_pigeons += len (f.boids)
            for b in f.boids:
                b.on_death += self.on_kill_pigeon
        
        self.total_pigeons = total_pigeons
        self.dead_pigeons = 0
        self.level.boy.on_death += self.on_kill_boy

        self.num_sticks = self.level.max_sticks
        self.player_ctl.on_place_stick_down += self.on_place_stick
        self.hud.set_counter ('sticks', self.num_sticks)
        
        self.timer = self.tasks.add (
            task.TimerTask (duration = self.level.max_time))
        self.timer.on_tick = lambda: self.hud.set_counter (
            'clock', int (self.timer.remaining))
        self.timer.on_finish = self.on_finish_time

        self.tasks.add (self.highlight_stick_task)
        self._curr_best_stick = None

        self.pigeon_food = []
        
    def do_sink (self):
        super (Game, self).do_sink ()
        if self.manager.current.state_name == 'menu-noload':
            for x in self.entities.entities:
                if isinstance (x, task.Task):
                    x.pause ()        
        self.events.quiet = True
        self.hud.soft_hide ()
        self.timer.pause ()
        
    def do_unsink (self, action = 'continue'):
        super (Game, self).do_unsink ()
        self.manager.panda.relative_mouse ()
        self.tasks.resume ()
        for x in self.entities.entities:
            if isinstance (x, task.Task):
                x.resume ()
        if action == 'continue':
            self.events.quiet = False
            self.hud.soft_show ()
            self.timer.resume ()
        elif action == 'quit':
            self.leave_transition ()
        elif action == 'retry':
            self.leave_transition ('game')
        
    def do_release (self):
        self.level.dispose () # TODO: To entity!
        self.glow_filter.disable ()
        super (Game, self).do_release ()
Beispiel #5
0
class Main(ShowBase, FSM):
    """Main function of the application
    initialise the engine (ShowBase)"""
    def __init__(self):
        """initialise the engine"""
        ShowBase.__init__(self)
        base.notify.info("Version {}".format(versionstring))
        FSM.__init__(self, "FSM-Game")

        #
        # BASIC APPLICATION CONFIGURATIONS
        #
        # disable pandas default camera driver
        self.disableMouse()
        # set antialias for the complete sceen to automatic
        self.render.setAntialias(AntialiasAttrib.MAuto)
        # shader generator
        render.setShaderAuto()
        # Enhance font readability
        DGG.getDefaultFont().setPixelsPerUnit(100)
        # get the displays width and height for later usage
        self.dispWidth = self.pipe.getDisplayWidth()
        self.dispHeight = self.pipe.getDisplayHeight()

        #
        # CONFIGURATION LOADING
        #
        # load given variables or set defaults
        # check if particles should be enabled
        # NOTE: If you use the internal physics engine, this always has
        #       to be enabled!
        particles = ConfigVariableBool("particles-enabled", True).getValue()
        if particles:
            self.enableParticles()

        def setFullscreen():
            """Helper function to set the window fullscreen
            with width and height set to the screens size"""
            # set window properties
            # clear all properties not previously set
            base.win.clearRejectedProperties()
            # setup new window properties
            props = WindowProperties()
            # Fullscreen
            props.setFullscreen(True)
            # set the window size to the screen resolution
            props.setSize(self.dispWidth, self.dispHeight)
            # request the new properties
            base.win.requestProperties(props)
            # Set the config variables so we correctly store the
            # new size and fullscreen setting later
            winSize = ConfigVariableString("win-size")
            winSize.setValue("{} {}".format(self.dispWidth, self.dispHeight))
            fullscreen = ConfigVariableBool("fullscreen")
            fullscreen.setValue(True)
            # Render a frame to make sure the fullscreen is applied
            # before we do anything else
            self.taskMgr.step()
            # make sure to propagate the new aspect ratio properly so
            # the GUI and other things will be scaled appropriately
            aspectRatio = self.dispWidth / self.dispHeight
            self.adjustWindowAspectRatio(aspectRatio)

        # check if the config file hasn't been created
        if not os.path.exists(prcFile):
            setFullscreen()
        # automatically safe configuration at application exit
        #base.exitFunc = self.__writeConfig

        #
        # INITIALIZE GAME CONTENT
        #
        base.cTrav = CollisionTraverser("base collision traverser")
        base.pusher = CollisionHandlerPusher()
        self.menu = Menu()
        self.credits = Credits()
        self.charSelection = CharacterSelection()
        self.levelSelection = LevelSelection()
        self.koScreen = KoScreen()
        self.hud = Hud()
        self.menuMusic = loader.loadMusic("assets/audio/menuMusic.ogg")
        self.menuMusic.setLoop(True)
        self.fightMusic = loader.loadMusic("assets/audio/fightMusic.ogg")
        self.fightMusic.setLoop(True)
        base.audio3d = Audio3DManager(base.sfxManagerList[0], camera)

        #
        # EVENT HANDLING
        #
        # By default we accept the escape key
        self.accept("escape", self.__escape)

        #
        # ENTER GAMES INITIAL FSM STATE
        #
        self.request("Menu")

    #
    # FSM PART
    #
    def enterMenu(self):
        show_cursor()
        self.accept("Menu-Start", self.request, ["CharSelection"])
        self.accept("Menu-Credits", self.request, ["Credits"])
        self.accept("Menu-Quit", self.userExit)
        self.ignore("KoScreen-Back")
        self.koScreen.hide()
        self.menu.show()
        if self.menuMusic.status() != AudioSound.PLAYING:
            self.menuMusic.play()
        if self.fightMusic.status() == AudioSound.PLAYING:
            self.fightMusic.stop()

    def exitMenu(self):
        self.ignore("Menu-Start")
        self.ignore("Menu-Credits")
        self.ignore("Menu-Quit")
        self.menu.hide()

    def enterCredits(self):
        self.accept("Credits-Back", self.request, ["Menu"])
        self.koScreen.hide()
        self.credits.show()

    def exitCredits(self):
        self.ignore("Credits-Back")
        self.credits.hide()

    def enterCharSelection(self):
        self.accept("CharSelection-Back", self.request, ["Menu"])
        self.accept("CharSelection-Start", self.request, ["LevelSelection"])
        self.charSelection.show()

    def exitCharSelection(self):
        self.ignore("CharSelection-Start")
        self.ignore("CharSelection-Back")
        self.charSelection.hide()
        self.selectedChar1 = self.charSelection.selectedCharacter1
        self.selectedChar2 = self.charSelection.selectedCharacter2

    def enterLevelSelection(self):
        self.accept("LevelSelection-Back", self.request, ["CharSelection"])
        self.accept("LevelSelection-Start", self.request, ["Game"])
        self.levelSelection.show()

    def exitLevelSelection(self):
        self.ignore("LevelSelection-Start")
        self.ignore("LevelSelection-Back")
        self.levelSelection.hide()

    def enterGame(self):
        # main game code should be called here
        self.arena = Arena(self.levelSelection.selectedLevel)
        self.arena.start()
        self.camera.setPos(0, -5, 1.25)
        self.player = Player(0, self.selectedChar1, "p1")
        self.player2 = Player(1, self.selectedChar2, "p2")
        self.player.setEnemy(self.player2.collisionNodeName)
        self.player2.setEnemy(self.player.collisionNodeName)
        self.player.start(self.arena.getStartPos(1))
        self.player2.start(self.arena.getStartPos(2))
        self.taskMgr.add(self.updateWorldCam, "world camera update task")
        self.accept("gameOver", self.gameOver)
        self.hud.show()

        def lifeChanged(charId, health):
            base.messenger.send("hud_setLifeBarValue", [charId, health])

        self.accept("lifeChanged", lifeChanged)
        hide_cursor()
        if self.fightMusic.status() != AudioSound.PLAYING:
            self.fightMusic.play()
        if self.menuMusic.status() == AudioSound.PLAYING:
            self.menuMusic.stop()

    def exitGame(self):
        # cleanup for game code
        self.taskMgr.remove("world camera update task")
        self.player.stop()
        self.player2.stop()
        del self.player
        del self.player2
        self.arena.stop()
        self.ignore("gameOver")
        self.ignore("lifeChanged")
        self.hud.hide()

    #
    # FSM PART END
    #

    #
    # BASIC FUNCTIONS
    #
    def gameOver(self, LoosingCharId):
        show_cursor()
        winningChar = 1
        if LoosingCharId == 0:
            winningChar = 2
        self.accept("KoScreen-Back", self.request, ["Credits"])
        self.koScreen.show(winningChar)

    def updateWorldCam(self, task):
        playerVec = self.player.getPos() - self.player2.getPos()
        playerDist = playerVec.length()
        x = self.player.getX() + playerDist / 2.0
        self.camera.setX(x)

        zoomout = False
        if not self.cam.node().isInView(self.player.getPos(self.cam)):
            camPosUpdate = -2 * globalClock.getDt()
            self.camera.setY(self.camera, camPosUpdate)
            zoomout = True
        if not self.cam.node().isInView(self.player2.getPos(self.cam)):
            camPosUpdate = -2 * globalClock.getDt()
            self.camera.setY(self.camera, camPosUpdate)
            zoomout = True
        if not zoomout:
            if self.camera.getY() < -5:
                camPosUpdate = 2 * globalClock.getDt()
                self.camera.setY(self.camera, camPosUpdate)
        return task.cont

    def __escape(self):
        """Handle user escape key klicks"""
        if self.state == "Menu":
            # In this state, we will stop the application
            self.userExit()
        elif self.state == "LevelSelection":
            self.request("CharSelection")
        else:
            # In every other state, we switch back to the Menu state
            self.request("Menu")

    def __writeConfig(self):
        """Save current config in the prc file or if no prc file exists
        create one. The prc file is set in the prcFile variable"""
        page = None

        #
        #TODO: add any configuration variable names that you have added
        #      to the dictionaries in the next lines. Set the current
        #      configurations value as value in this dictionary and it's
        #      name as key.
        configVariables = {
            # set the window size in the config file
            "win-size":
            ConfigVariableString(
                "win-size", "{} {}".format(self.dispWidth,
                                           self.dispHeight)).getValue(),
            # set the default to fullscreen in the config file
            "fullscreen":
            "#t"
            if ConfigVariableBool("fullscreen", True).getValue() else "#f",
            # particles
            "particles-enabled":
            "#t" if self.particleMgrEnabled else "#f",
            # audio
            "audio-volume":
            str(round(self.musicManager.getVolume(), 2)),
            "audio-music-active":
            "#t"
            if ConfigVariableBool("audio-music-active").getValue() else "#f",
            "audio-sfx-active":
            "#t"
            if ConfigVariableBool("audio-sfx-active").getValue() else "#f",
            # logging
            "notify-output":
            os.path.join(basedir, "game.log"),
            # window
            "framebuffer-multisample":
            "#t" if ConfigVariableBool("framebuffer-multisample").getValue()
            else "#f",
            "multisamples":
            str(ConfigVariableInt("multisamples", 8).getValue()),
            "texture-anisotropic-degree":
            str(ConfigVariableInt("texture-anisotropic-degree").getValue()),
            "textures-auto-power-2":
            "#t" if ConfigVariableBool("textures-auto-power-2",
                                       True).getValue() else "#f",
        }

        page = None
        # Check if we have an existing configuration file
        if os.path.exists(prcFile):
            # open the config file and change values according to current
            # application settings
            page = loadPrcFile(Filename.fromOsSpecific(prcFile))
            removeDecls = []
            for dec in range(page.getNumDeclarations()):
                # Check if our variables are given.
                # NOTE: This check has to be done to not loose our base or other
                #       manual config changes by the user
                if page.getVariableName(dec) in configVariables.keys():
                    removeDecls.append(page.modifyDeclaration(dec))
            for dec in removeDecls:
                page.deleteDeclaration(dec)
        else:
            # Create a config file and set default values
            cpMgr = ConfigPageManager.getGlobalPtr()
            page = cpMgr.makeExplicitPage("Application Config")

        # always write custom configurations
        for key, value in configVariables.items():
            page.makeDeclaration(key, value)
        # create a stream to the specified config file
        configfile = OFileStream(prcFile)
        # and now write it out
        page.write(configfile)
        # close the stream
        configfile.close()
Beispiel #6
0
class Main(ShowBase, FSM):
    """Main function of the application
    initialise the engine (ShowBase)"""

    def __init__(self):
        """initialise the engine"""
        ShowBase.__init__(self)
        FSM.__init__(self, "FSM-Game")

        #
        # BASIC APPLICATION CONFIGURATIONS
        #
        # disable pandas default camera driver
        self.disableMouse()
        # set background color to black
        self.setBackgroundColor(0, 0, 0)
        # set antialias for the complete sceen to automatic
        self.render.setAntialias(AntialiasAttrib.MAuto)
        # shader generator
        render.setShaderAuto()

        #
        # CONFIGURATION LOADING
        #
        # load given variables or set defaults
        # check if audio should be muted
        mute = ConfigVariableBool("audio-mute", False).getValue()
        if mute:
            self.disableAllAudio()
        else:
            self.enableAllAudio()
        # check if particles should be enabled
        particles = ConfigVariableBool("particles-enabled", True).getValue()
        if particles:
            self.enableParticles()
        # check if the config file hasn't been created
        if not os.path.exists(prcFile):
            # get the displays width and height
            w = self.pipe.getDisplayWidth()
            h = self.pipe.getDisplayHeight()
            # set window properties
            # clear all properties not previously set
            base.win.clearRejectedProperties()
            # setup new window properties
            props = WindowProperties()
            # Fullscreen
            props.setFullscreen(True)
            # set the window size to the screen resolution
            props.setSize(w, h)
            # request the new properties
            base.win.requestProperties(props)
        elif base.appRunner:
            # As when the application is started as appRunner instance
            # it doesn't respect our loadPrcFile configurations specific
            # to the window, hence we need to manually set them here.
            for dec in range(mainConfig.getNumDeclarations()):
                #TODO: Check for all window specific variables like
                #      fullscreen, screen size, title and window
                #      decoration that you have in your configuration
                #      and set them by your own.
                if mainConfig.getVariableName(dec) == "fullscreen":
                    if not mainConfig.getDeclaration(dec).getBoolWord(0): break
                    # get the displays width and height
                    w = self.pipe.getDisplayWidth()
                    h = self.pipe.getDisplayHeight()
                    # set window properties
                    # clear all properties not previously set
                    base.win.clearRejectedProperties()
                    # setup new window properties
                    props = WindowProperties()
                    # Fullscreen
                    props.setFullscreen(True)
                    # set the window size to the screen resolution
                    props.setSize(w, h)
                    # request the new properties
                    base.win.requestProperties(props)
                    break

        # automatically safe configuration at application exit
        base.exitFunc = self.__writeConfig

        # due to the delayed window resizing and switch to fullscreen
        # we wait some time until everything is set so we can savely
        # proceed with other setups like the menus
        if base.appRunner:
            # this behaviour only happens if run from p3d files and
            # hence the appRunner is enabled
            taskMgr.doMethodLater(0.5, self.postInit,
                "post initialization", extraArgs=[])
        else:
            self.postInit()

    def postInit(self):
        #
        # initialize game content
        #
        base.cTrav = CollisionTraverser("base collision traverser")
        base.pusher = CollisionHandlerPusher()
        self.menu = Menu()
        self.credits = Credits()
        self.charSelection = CharacterSelection()
        self.levelSelection = LevelSelection()
        self.koScreen = KoScreen()
        self.hud = Hud()
        self.menuMusic = loader.loadMusic("assets/audio/menuMusic.ogg")
        self.menuMusic.setLoop(True)
        self.fightMusic = loader.loadMusic("assets/audio/fightMusic.ogg")
        self.fightMusic.setLoop(True)
        base.audio3d = Audio3DManager(base.sfxManagerList[0], camera)

        #
        # Event handling
        #
        self.accept("escape", self.__escape)

        #
        # Start with the menu
        #
        self.request("Menu")

    #
    # FSM PART
    #
    def enterMenu(self):
        show_cursor()
        self.accept("Menu-Start", self.request, ["CharSelection"])
        self.accept("Menu-Credits", self.request, ["Credits"])
        self.accept("Menu-Quit", self.quit)
        self.ignore("KoScreen-Back")
        self.koScreen.hide()
        self.menu.show()
        if self.menuMusic.status() != AudioSound.PLAYING:
            self.menuMusic.play()
        if self.fightMusic.status() == AudioSound.PLAYING:
            self.fightMusic.stop()

    def exitMenu(self):
        self.ignore("Menu-Start")
        self.ignore("Menu-Credits")
        self.ignore("Menu-Quit")
        self.menu.hide()

    def enterCredits(self):
        self.accept("Credits-Back", self.request, ["Menu"])
        self.koScreen.hide()
        self.credits.show()

    def exitCredits(self):
        self.ignore("Credits-Back")
        self.credits.hide()

    def enterCharSelection(self):
        self.accept("CharSelection-Back", self.request, ["Menu"])
        self.accept("CharSelection-Start", self.request, ["LevelSelection"])
        self.charSelection.show()

    def exitCharSelection(self):
        self.ignore("CharSelection-Start")
        self.ignore("CharSelection-Back")
        self.charSelection.hide()
        self.selectedChar1 = self.charSelection.selectedCharacter1
        self.selectedChar2 = self.charSelection.selectedCharacter2

    def enterLevelSelection(self):
        self.accept("LevelSelection-Back", self.request, ["CharSelection"])
        self.accept("LevelSelection-Start", self.request, ["Game"])
        self.levelSelection.show()

    def exitLevelSelection(self):
        self.ignore("LevelSelection-Start")
        self.ignore("LevelSelection-Back")
        self.levelSelection.hide()

    def enterGame(self):
        # main game code should be called here
        self.arena = Arena(self.levelSelection.selectedLevel)
        self.arena.start()
        self.camera.setPos(0, -5, 1.25)
        self.player = Player(0, self.selectedChar1, "p1")
        self.player2 = Player(1, self.selectedChar2, "p2")
        self.player.setEnemy(self.player2.collisionNodeName)
        self.player2.setEnemy(self.player.collisionNodeName)
        self.player.start(self.arena.getStartPos(1))
        self.player2.start(self.arena.getStartPos(2))
        self.taskMgr.add(self.updateWorldCam, "world camera update task")
        self.accept("gameOver", self.gameOver)
        self.hud.show()
        def lifeChanged(charId, health):
            base.messenger.send(
                "hud_setLifeBarValue",
                [charId, health])
        self.accept("lifeChanged", lifeChanged)
        hide_cursor()
        if self.fightMusic.status() != AudioSound.PLAYING:
            self.fightMusic.play()
        if self.menuMusic.status() == AudioSound.PLAYING:
            self.menuMusic.stop()

    def exitGame(self):
        # cleanup for game code
        self.taskMgr.remove("world camera update task")
        self.player.stop()
        self.player2.stop()
        del self.player
        del self.player2
        self.arena.stop()
        self.ignore("gameOver")
        self.ignore("lifeChanged")
        self.hud.hide()

    #
    # FSM PART END
    #

    #
    # BASIC FUNCTIONS
    #
    def gameOver(self, LoosingCharId):
        show_cursor()
        winningChar = 1
        if LoosingCharId == 0:
            winningChar = 2
        self.accept("KoScreen-Back", self.request, ["Credits"])
        self.koScreen.show(winningChar)

    def updateWorldCam(self, task):
        playerVec = self.player.getPos() - self.player2.getPos()
        playerDist = playerVec.length()
        x = self.player.getX() + playerDist / 2.0
        self.camera.setX(x)

        zoomout = False
        if not self.cam.node().isInView(self.player.getPos(self.cam)):
            camPosUpdate = -2 * globalClock.getDt()
            self.camera.setY(self.camera, camPosUpdate)
            zoomout = True
        if not self.cam.node().isInView(self.player2.getPos(self.cam)):
            camPosUpdate = -2 * globalClock.getDt()
            self.camera.setY(self.camera, camPosUpdate)
            zoomout = True
        if not zoomout:
            if self.camera.getY() < -5:
                camPosUpdate = 2 * globalClock.getDt()
                self.camera.setY(self.camera, camPosUpdate)
        return task.cont

    def __escape(self):
        if self.state == "Menu":
            self.quit()
        elif self.state == "LevelSelection":
            self.request("CharSelection")
        else:
            self.request("Menu")

    def quit(self):
        """This function will stop the application"""
        self.userExit()

    def __writeConfig(self):
        """Save current config in the prc file or if no prc file exists
        create one. The prc file is set in the prcFile variable"""
        page = None

        #TODO: get values of configurations here
        particles = "#f" if not base.particleMgrEnabled else "#t"
        volume = str(round(base.musicManager.getVolume(), 2))
        mute = "#f" if base.AppHasAudioFocus else "#t"
        #TODO: add any configuration variable name that you have added
        customConfigVariables = [
            "", "particles-enabled", "audio-mute", "audio-volume"]
        if os.path.exists(prcFile):
            # open the config file and change values according to current
            # application settings
            page = loadPrcFile(Filename.fromOsSpecific(prcFile))
            removeDecls = []
            for dec in range(page.getNumDeclarations()):
                # Check if our variables are given.
                # NOTE: This check has to be done to not loose our base or other
                #       manual config changes by the user
                if page.getVariableName(dec) in customConfigVariables:
                    decl = page.modifyDeclaration(dec)
                    removeDecls.append(decl)
            for dec in removeDecls:
                page.deleteDeclaration(dec)
            # NOTE: particles-enabled and audio-mute are custom variables and
            #       have to be loaded by hand at startup
            # Particles
            page.makeDeclaration("particles-enabled", particles)
            # audio
            page.makeDeclaration("audio-volume", volume)
            page.makeDeclaration("audio-mute", mute)
        else:
            # Create a config file and set default values
            cpMgr = ConfigPageManager.getGlobalPtr()
            page = cpMgr.makeExplicitPage("%s Pandaconfig"%appName)
            # set OpenGL to be the default
            page.makeDeclaration("load-display", "pandagl")
            # get the displays width and height
            w = self.pipe.getDisplayWidth()
            h = self.pipe.getDisplayHeight()
            # set the window size in the config file
            page.makeDeclaration("win-size", "%d %d"%(w, h))
            # set the default to fullscreen in the config file
            page.makeDeclaration("fullscreen", "1")
            # particles
            page.makeDeclaration("particles-enabled", "#t")
            # audio
            page.makeDeclaration("audio-volume", volume)
            page.makeDeclaration("audio-mute", "#f")
        # create a stream to the specified config file
        configfile = OFileStream(prcFile)
        # and now write it out
        page.write(configfile)
        # close the stream
        configfile.close()
Beispiel #7
0
class Game(GameBase, FSM):
    def __init__(self):
        GameBase.__init__(self, debug=False)
        FSM.__init__(self, "GUI FSM")
        base.disableMouse()

        self.menu = Menu()
        self.missionScreen = MissionScreen()
        self.debrief = Debrief()
        self.hud = Hud()
        self.missionSelect = MissionSelect()

        base.camLens.setFov(90)

        self.setMusic("audio/music.mp3", volume=0.5)
        self.setMusic("audio/engine1.wav", volume=0.3)

        self.request("Menu")
        base.taskMgr.add(self.missionOverTask, "is mission over")

    def enterMenu(self):
        self.menu.show()
        self.accept("menu-start", self.request, ["MissionSelect"])
        self.accept("menu-instructions", self.request, ["Instructions"])
        self.accept("menu-quit", sys.exit)

    def exitMenu(self):
        self.menu.hide()
        self.ignore("menu-start")
        self.ignore("menu-instructions")
        self.ignore("menu-quit")

    def enterMissionSelect(self):
        self.missionSelect.show()
        self.accept("missionselect-m1", self.setMission, ["m1"])
        self.accept("missionselect-m2", self.setMission, ["m2"])
        self.accept("missionselect-test", self.setMission, ["test"])

    def exitMissionSelect(self):
        self.missionSelect.hide()
        self.ignore("missionselect-m1")
        self.ignore("missionselect-m2")

    def enterMissionScreen(self):
        self.missionScreen.showWithTitle(self.currentMission.objective)
        self.accept("mission-start", self.request, ["Game"])

    def exitMissionScreen(self):
        self.missionScreen.hide()
        self.ignore("mission-start")

    def enterGame(self):
        self.world = World(self.currentMission.mapName)
        self.startTime = "Not yet set - not loaded"  #set in self.missionOverTask
        self.player = Player(self.world)
        self.accept("player-into-Collision", self.player.reset)
        self.accept("game-quit", self.request, ["Menu"])

    def exitGame(self):
        self.world.destroy()
        self.player.model.removeNode()
        del self.player
        base.taskMgr.remove("hud update")
        self.hud.timer.setText("")
        self.hud.hide()
        base.taskMgr.remove("update player")
        self.ignore("game-quit")

    def enterDebrief(self):
        self.debrief.show()
        self.debrief.setTitle(self.currentMission.question, isAnswer=False)
        self.debrief.setButtons(self.currentMission.options)
        self.accept("debrief-correct", self.debrief.setTitle, ["Correct"])
        self.accept("debrief-wrong", self.debrief.setTitle, ["Wrong"])
        self.accept("debrief-back", self.request, ["Menu"])
        self.accept("debrief-restart", self.request, ["Game"])

    def exitDebrief(self):
        self.debrief.hide()
        self.ignore("debrief-correct")
        self.ignore("debrief-wrong")
        self.debrief.initialise(
        )  #clear all settings on it, ie title and buttons, as they are mission specific

    def setMission(self, name):
        self.currentMission = missions[name]
        self.request("MissionScreen")

    def missionOverTask(self, task):
        if self.state == "Game" and self.world.loaded and self.startTime == "Not yet set - not loaded":
            self.startTime = time.time()
            self.hud.show()
            self.hud.initialise(self.currentMission.objective,
                                self.currentMission.timeAllowed)
            base.taskMgr.add(self.hud.hudTask, "hud update")
        if self.state == "Game" and self.world.loaded:
            if time.time() - self.startTime > self.currentMission.timeAllowed:
                self.request("Debrief")
        return task.cont
Beispiel #8
0
class Player(DirectObject):
    def __init__(self, _main):
        self.main = _main
        self.name = ""
        self.points = 0
        self.health = 100.0
        self.runSpeed = 1.8
        self.keyMap = {
            "left":False,
            "right":False,
            "up":False,
            "down":False
            }
        base.camera.setPos(0,0,0)
        self.model = loader.loadModel("Player")
        self.model.find('**/+SequenceNode').node().stop()
        self.model.find('**/+SequenceNode').node().pose(0)
        base.camera.setP(-90)
        self.playerHud = Hud()
        self.playerHud.hide()
        self.model.hide()

        # Weapons: size=2, 0=main, 1=offhand
        self.mountSlot = []
        self.activeWeapon = None
        self.isAutoActive = False
        self.trigger = False
        self.lastShot = 0.0
        self.fireRate = 0.0

        self.playerTraverser = CollisionTraverser()
        self.playerEH = CollisionHandlerEvent()
        ## INTO PATTERNS
        self.playerEH.addInPattern('intoPlayer-%in')
        #self.playerEH.addInPattern('colIn-%fn')
        self.playerEH.addInPattern('intoHeal-%in')
        self.playerEH.addInPattern('intoWeapon-%in')
        ## OUT PATTERNS
        self.playerEH.addOutPattern('outOfPlayer-%in')
        playerCNode = CollisionNode('playerSphere')
        playerCNode.setFromCollideMask(BitMask32.bit(1))
        playerCNode.setIntoCollideMask(BitMask32.bit(1))
        self.playerSphere = CollisionSphere(0, 0, 0, 0.6)
        playerCNode.addSolid(self.playerSphere)
        self.playerNP = self.model.attachNewNode(playerCNode)
        self.playerTraverser.addCollider(self.playerNP, self.playerEH)
        #self.playerNP.show()

        self.playerPusher = CollisionHandlerPusher()
        self.playerPusher.addCollider(self.playerNP, self.model)
        self.playerPushTraverser = CollisionTraverser()
        self.playerPushTraverser.addCollider(self.playerNP, self.playerPusher)

    def acceptKeys(self):
        self.accept("w", self.setKey, ["up", True])
        self.accept("w-up", self.setKey, ["up", False])
        self.accept("a", self.setKey, ["left", True])
        self.accept("a-up", self.setKey, ["left", False])
        self.accept("s", self.setKey, ["down", True])
        self.accept("s-up", self.setKey, ["down", False])
        self.accept("d", self.setKey, ["right", True])
        self.accept("d-up", self.setKey, ["right", False])

        # Add mouse btn for fire()
        self.accept("mouse1", self.setWeaponTrigger, [True])
        self.accept("mouse1-up", self.setWeaponTrigger, [False])

        # Killed enemies
        self.accept("killEnemy", self.addPoints)

        # Game states
        self.accept("doDamageToPlayer", self.doDamage)

    def ignoreKeys(self):
        self.ignore("w")
        self.ignore("a")
        self.ignore("s")
        self.ignore("d")
        self.ignore("killEnemy")
        self.ignore("mouse1")
        self.ignore("mouse1-up")

        for item in self.main.itemList:
            if item.type == "heal":
                self.ignore("intoHeal-" + "itemHeal" + str(item.id))
            elif item.type == "gun":
                self. ignore("intoWeapon-" + "itemWeapon" + str(item.id))

        for enemy in self.main.enemyList:
            self.ignore("intoPlayer-" + "colEnemy" + str(enemy.id))

        # Add mouse btn for fire to ignore

    def setKey(self, action, pressed):
        self.keyMap[action] = pressed

    def start(self, startPos, playerName):
        self.name = playerName
        self.points = 0
        self.health = 100
        self.model.reparentTo(render)
        self.model.setPos(startPos.x,
                          startPos.y,
                          0)
        for slot in self.mountSlot[:]:
            self.mountSlot.remove(slot)
        # Create a basic weapon
        self.mountSlot.append(Weapon(self.main, "Pistol", 0.30, 25, weaponType="Pistol"))
        # Mount the players default weapon
        self.mountWeapon(self.mountSlot[0])
        self.playerHud.setWeapon("Pistol")

        self.acceptKeys()
        self.playerHud.show()

        taskMgr.add(self.move, "moveTask")

    def stop(self):
        taskMgr.remove("moveTask")
        self.ignoreKeys()
        self.unmountWeapon()
        self.playerHud.hide()
        self.model.hide()

    def addPoints(self, args):
        self.points += 10
        base.messenger.send("setHighscore", [self.points])

    def move(self, task):
        elapsed = globalClock.getDt()
        #self.playerTraverser.traverse(self.main.enemyParent)
        #self.playerTraverser.traverse(self.main.itemParent)

        # set headding
        pos = self.main.mouse.getMousePos()
        pos.setZ(0)
        self.model.lookAt(pos)
        self.model.setP(-90)

        # new player position
        if self.keyMap["up"]:
            # follow mouse mode
            #self.model.setZ(self.model, 5 * elapsed * self.runSpeed)
            # axis move mode
            self.model.setY(self.model.getY() + elapsed * self.runSpeed)
        elif self.keyMap["down"]:
            #self.model.setZ(self.model, -5 * elapsed * self.runSpeed)
            self.model.setY(self.model.getY() - elapsed * self.runSpeed)

        if self.keyMap["left"]:
            # follow mouse mode
            #self.model.setX(self.model, -5 * elapsed * self.runSpeed)
            # axis move mode
            self.model.setX(self.model.getX() - elapsed * self.runSpeed)
        elif self.keyMap["right"]:
            #self.model.setX(self.model, 5 * elapsed * self.runSpeed)
            self.model.setX(self.model.getX() + elapsed * self.runSpeed)

        # actualize cam position
        base.camera.setPos(self.model.getPos())
        base.camera.setZ(20)
        return task.cont

    def mountWeapon(self, _weaponToMount):
        self.activeWeapon = _weaponToMount # self.mountSlot[0]
        if self.activeWeapon.style == "TwoHand":
            self.model.find('**/+SequenceNode').node().pose(0)
        else:
            self.model.find('**/+SequenceNode').node().pose(1)
        self.activeWeapon.model.reparentTo(self.model)
        self.activeWeapon.model.setY(self.model.getY() - 0.1)
        self.model.show()
        self.activeWeapon.model.show()
        self.fireRate = self.activeWeapon.fireRate

    def unmountWeapon(self):
        self.activeWeapon.model.hide()

    def setWeaponTrigger(self, _state):
        self.trigger = _state

        if _state:
            mpos = self.main.mouse.getMousePos()
            self.activeWeapon.doFire(mpos)
            if self.activeWeapon.weaponType == "MG":
                self.fireActiveWeapon()
            else:
                self.activeWeapon.stopFire()
        else:
            self.activeWeapon.stopFire()
            taskMgr.remove("Fire")

    def fireActiveWeapon(self):
        if self.activeWeapon:
            #mpos = self.main.mouse.getMousePos()
            taskMgr.add(self.fireUpdate, "Fire")
            #self.activeWeapon.doFire(mpos)

    def fireUpdate(self, task):
        dt = globalClock.getDt()
        self.lastShot += dt
        mpos = self.main.mouse.getMousePos()
        #print self.lastShot
        if self.lastShot >= self.fireRate:
            self.lastShot -= self.fireRate

            if self.trigger:
                self.activeWeapon.doFire(mpos)
                #task.delayTime += self.fireRate
        return task.again

    def setMouseBtn(self):
        self.trigger = False

        print "Mouse Released"

    def addEnemyDmgEvent(self, _id):
        self.accept("intoPlayer-" + "colEnemy" + str(_id), self.setEnemyAttack)
        #self.accept("outOfPlayer-" + "colEnemy" + str(_id), self.setEnemyAttackOutOfRange)

    def setEnemyAttack(self, _entry):
        enemyColName = _entry.getIntoNodePath().node().getName()
        base.messenger.send("inRange-" + enemyColName, [True])

    def setEnemyAttackOutOfRange(self, _entry):
        enemyColName = _entry.getIntoNodePath().node().getName()
        base.messenger.send("inRange-" + enemyColName, [False])

    def doDamage(self, _dmg):

        if self.health <= 0:
            #print "KILLED IN ACTION"
            self.main.stop()
        else:
            self.health -= _dmg
            #print "Remaining Health: ", self.health
        base.messenger.send("setHealth", [self.health])

    def addHealItemEvent(self, _id):
        self.accept("intoHeal-" + "itemHeal" + str(_id), self.healPlayer)

    def healPlayer(self, _entry):
        itemColName = _entry.getIntoNodePath().node().getName()

        if self.health == 100:
            pass

        else:
            self.health += 50
            base.messenger.send("into-" + itemColName)
            if self.health > 100:
                self.health = 100

        print self.health

    def addWeaponItemEvent(self, _id):
        self.accept("intoWeapon-" + "itemWeapon" + str(_id), self.changeWeapon)

    def changeWeapon(self, _entry):
        itemColName = _entry.getIntoNodePath().node().getName()
        base.messenger.send("into-" + itemColName)
        for weapon in self.mountSlot:
            if weapon.name == "MachineGun":
                return
        self.unmountWeapon()
        self.mountSlot.append(Weapon(self.main, "MachineGun", 0.15, 50, weaponType="MG"))
        self.playerHud.setWeapon("MG")
        self.mountWeapon(self.mountSlot[len(self.mountSlot) - 1])
        self.activeWeapon.model.show()