示例#1
0
    def setupInput(self):
        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
        # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(
                OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(
                OIS.OISKeyboard, True)
        except Exception:  # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(mouse=self.mouse,
                                         keyboard=self.keyboard,
                                         scene=self,
                                         player=self.player)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)
示例#2
0
文件: playscene.py 项目: parshap/tote
    def __init__(self, sceneManager):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)

        
        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")
        
        self.viewport = self.camera.getViewport()
        
        # Create an empty list of nodes
        self.nodes = []
        
        # Create an empty list of GUI elements.
        self.gui_elements = [] 
        
        # Set up the overlay for the GUI.
        self.setupOverlay()
        
        # Set up the scene.
        self.setupScene()
        
        # Set up the GUI.
        self.setupGUI()
        
        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
                     # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(OIS.OISKeyboard, True)
        except Exception: # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(mouse=self.mouse, keyboard=self.keyboard,
                                         scene=self, player=self.player)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(self.renderWindow, self)
示例#3
0
 def __init__(self, spawn_x=100, spawn_y=100, entity=[]):
     Person.__init__(self, spawn_x, spawn_y, '0.png', 'player\\default')
     self.inputhandler = InputHandler()
     self.admin = self.physics = self.parkour = False
     self.add_basic_movement()
     self.add_physics()
     self.add_parkour()
     self.add_stats(entity)
示例#4
0
def handle_input(thread, screen):
    if thread == None or not running(thread):
        inp = InputHandler(renderer.screen)
        inp.daemon = True
        inp.start()
        return inp
        # return thread
    else: return thread
示例#5
0
    def __init__(self, sceneManager):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)

        
        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")
        
        self.viewport = self.camera.getViewport()
        
        # Create an empty list of nodes
        self.nodes = []
        
        # Create an empty list of GUI elements.
        self.gui_elements = [] 
        
        # Set up the overlay for the GUI.
        self.setupOverlay()
        
        # Set up the scene.
        self.setupScene()
        
        # Set up the GUI.
        self.setupGUI()
        
        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
                     # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(OIS.OISKeyboard, True)
        except Exception: # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(mouse=self.mouse, keyboard=self.keyboard,
                                         scene=self, player=self.player)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(self.renderWindow, self)
示例#6
0
 def __init__(self,spawn_x=100,spawn_y=100,entity = []):
     Person.__init__(self,spawn_x,spawn_y,'0.png', 'player\\default')
     self.inputhandler = InputHandler()
     self.admin = self.physics = self.parkour = False
     self.add_basic_movement()
     self.add_physics()
     self.add_parkour()
     self.add_stats(entity)
示例#7
0
    def __init__(self, spawn_x=100, spawn_y=100, entity=[]):
        Person.__init__(self, spawn_x, spawn_y, '0.png', 'player\\default')
        self.inputhandler = InputHandler()
        self.admin = self.physics = self.parkour = False
        self.add_basic_movement()
        self.add_physics()
        self.add_parkour()
        self.add_stats(entity)
        self.state = 'idle'
        self.stage = 0
        self.next_stage = False
        self.brightness = 50

        #temporary
        self.stamina_regen = True

        self.direc = 1  #right
示例#8
0
 def __init__(self,spawn_x=100,spawn_y=100,entity = []):
     Person.__init__(self,spawn_x,spawn_y,'0.png', 'player\\default')
     self.inputhandler = InputHandler()
     self.admin = self.physics = self.parkour = False
     self.add_basic_movement()
     self.add_physics()
     self.add_parkour()
     self.add_stats(entity)
     self.state = 'idle'
     self.stage = 0
     self.next_stage = False
     self.brightness = 50
     
     #temporary
     self.stamina_regen= True
     
     
     self.direc = 1 #right
示例#9
0
    def setupInput(self):
        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
                     # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(OIS.OISKeyboard, True)
        except Exception: # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(self.mouse, self.keyboard, self)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)
示例#10
0
class PlayScene(ogre.FrameListener, ogre.WindowEventListener):
    """
    This class represents the game's main scene - the play scene. This class
    sets up the initial scene and acts as the main game loop (via
    frameStarted()).
    """

    def __init__(self, sceneManager, address, port):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)
        
        self.address = address
        self.port = port
        
        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")
        
        # Create an empty list of nodes
        self.nodes = []
        
        # Set up the scene.
        self.setupScene()
        
        # Init attributes.
        self.player = None
        self.last_update = None

        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
                     # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(OIS.OISKeyboard, True)
        except Exception: # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(self.mouse, self.keyboard, self)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(self.renderWindow, self)

    def __del__ (self ):
        # Clean up OIS 
        self.inputManager.destroyInputObjectKeyboard(self.keyboard)
        self.inputManager.destroyInputObjectMouse(self.mouse)
        OIS.InputManager.destroyInputSystem(self.inputManager)
        self.inputManager = None

        ogre.WindowEventUtilities.removeWindowEventListener(self.renderWindow, self)
        self.windowClosed(self.renderWindow)
        
    def setupScene(self):
        ## Load the level.
        # @todo: Remove .scene dependancy and move to external file (format?).
        
        # Load some data from the .scene file
        sceneLoader = SceneLoader.DotSceneLoader("media/testtilescene.scene", self.sceneManager)
        sceneLoader.parseDotScene()
        
        # Create the world.
        self.world = gamestate.world.World()
        
        # Create the client and set listeners.
        self.client = net.client.GameClient(self.world, self.address, self.port)
        self.client.connected += self.on_client_connected
        
        # Start the netclient and connect.
        self.client_thread = threading.Thread(target=self.client.go)
        self.client_thread.start()
        
        # Attach a handler to world.object_added
        self.world.object_added += self.on_world_object_added
        
        # Set up the TestScene
        self.scene = gamestate.scenes.TestScene(self.world)

        # Setup camera
        self.camera.nearClipDistance = 1
        self.camera.farClipDistance = 500
        self.camera.setProjectionType(ogre.PT_ORTHOGRAPHIC)

        # THIS SPECIFIES THE HEIGHT OF THE ORTHOGRAPHIC WINDOW
        # the width will be recalculated based on the aspect ratio
        # in ortho projection mode, decreasing the size of the window
        # is equivalent to zooming in, increasing is the equivalent of
        # zooming out.
        self.camera.setOrthoWindowHeight(200)

        # Setup camera node
        self.cameraNode.position = (0, 100, 100)
        self.cameraNode.pitch(ogre.Degree(-45))

    def frameStarted(self, event):
        """ 
        Called before a frame is displayed, handles events
        (also those via callback functions, as you need to call capture()
        on the input objects)

        Returning False here exits the application (render loop stops)
        """
        
        dt = event.timeSinceLastFrame
        
        # Get buffered input from server and process it.
        while not self.client.input.empty():
            packet = self.client.input.get_nowait()
            self.process_packet(packet)

        # Capture any buffered events (and fire any callbacks).
        self.inputHandler.capture()
        
        # Update the game state world.
        self.world.update(dt)
        
        # Send an PlayerUpdate packet to the server if appropriate.
        self._send_update()
        
        # Send buffered output to server.
        reactor.callFromThread(self.client.send)
        
        # Add time to animations.
        for node in self.nodes:
            node.animations_addtime(dt)

        # Neatly close our FrameListener if our renderWindow has been shut down
        # or we are quitting.
        if self.renderWindow.isClosed() or self.quit:
            return False
        
        return True
    
    ## Net event callbacks & helpers
    
    def _send_update(self):
        """ Sends a PlayerUpdate packet to the server if appropriate. """
        if self.player is None:
            return

        update = self._get_update()
        if self.last_update is not None:
            update_time, last_update = self.last_update
            
            # Don't send if we've sent in the last 0.1s.
            if update_time + 0.05 > self.world.time:
                return
                
            # Don't send if info hasn't changed since the last update.
            if last_update.x == update.x and last_update.z == update.z and \
                last_update.rotation == update.rotation and \
                last_update.move_speed == update.move_speed and \
                last_update.move_direction == update.move_direction:
                return
        
        print "Sending player update to server."
        self.client.output.put_nowait(update)
        self.last_update = (self.world.time, update)
    
    def _get_update(self):
        """ Returns a PlayerUpdate packet based on the current player state. """
        update = packets.PlayerUpdate()
        update.x, update.z = self.player.position
        update.rotation = self.player.rotation
        if self.player.is_moving:
            update.move_speed = self.player.move_speed
            update.move_direction = self.player.move_direction
        else:
            update.move_speed = 0
            update.move_direction = 0
        return update
        
    
    def process_packet(self, packet):
        ptype = type(packet)
        print "Processing packet=%s: %s from server." % (packet.id, ptype.__name__)
        
        # JoinResponse
        if ptype is packets.JoinResponse:
            # @todo: handle deny
            # Add a player to the world and set it as our active player.
            print "Creating player in world with id=%s." % packet.player_id
            self.player = gamestate.objects.Player(self.world)
            self.world.add_object(self.player, packet.player_id)
            
            # Listen to the player's position change event so we can mvoe the
            # camera with the player.
            self.player.position_changed += self.on_player_position_changed
        
        # ObjectInit
        elif ptype is packets.ObjectInit:
            if packet.object_type == "player":
                object = gamestate.objects.Player(self.world)
            else:
                raise Exception("Invalid object_type")
            # @todo: implement name, owner_id, ttl

            self.world.add_object(object, packet.object_id)
        
        # ObjectUpdate
        elif ptype is packets.ObjectUpdate:
            if not self.world.objects_hash.has_key(packet.object_id):
                return
            object = self.world.objects_hash[packet.object_id]
            print "Updating object id=%s." % object.object_id
            object.rotation = packet.rotation
            try:
                if packet.move_speed > 0:
                    diff_vector = ogre.Vector3(packet.x - object.position[0], 0, packet.z - object.position[1])
                    move_vector = ogre.Vector3(packet.move_speed * math.cos(packet.rotation), 0,
                                               packet.move_speed * math.sin(packet.rotation))
                    resultant = diff_vector + move_vector
                    angle = math.atan2(resultant.z, resultant.x)
                    object.move_speed = packet.move_speed
                    object.rotation = angle
                    object.move_direction = 0
                    object.is_moving = True
                else:
                    object.position = (packet.x, packet.z)
                    object.is_moving = False
            except:
                object.position = (packet.x, packet.z)
    
    def on_client_connected(self):
        packet = packets.JoinRequest()
        # @todo: Get player_name from somewhere.
        packet.player_name = "Player1"
        self.client.output.put_nowait(packet)
        
    ## Game event callbacks
    def on_world_object_added(self, gameObject):
        if gameObject.type == "player":
            self.nodes.append(nodes.PlayerNode(self.sceneManager, gameObject))
        
    def on_player_position_changed(self, mobileObject, position):
        self.cameraNode.position = (position[0], 100, position[1] + 100)

    ## Window event listener callbacks
    def windowResized(self, renderWindow):
        self.mouse.getMouseState().width = renderWindow.width
        self.mouse.getMouseState().height = renderWindow.height
        vp = self.camera.getViewport()
        self.camera.aspectRatio = vp.actualWidth / vp.actualHeight
        # @todo: Scale the image so viewable area remains the same.

    def windowClosed(self, renderWindow):
        # Only close for window that created OIS
        if(renderWindow == self.renderWindow):
            del self
示例#11
0
class Player(Person):
    
    def __init__(self,spawn_x=100,spawn_y=100,entity = []):
        Person.__init__(self,spawn_x,spawn_y,'0.png', 'player\\default')
        self.inputhandler = InputHandler()
        self.admin = self.physics = self.parkour = False
        self.add_basic_movement()
        self.add_physics()
        self.add_parkour()
        self.add_stats(entity)

        
    def add_animation(self):    
        pass
    def add_basic_movement(self):
        self.jumping = self.onGround = self.running = False
        self.inputhandler.add_button('right')
        self.inputhandler.add_button('left')
        self.inputhandler.add_button('up')
        self.inputhandler.add_button('sprint')
        self.inputhandler.add_button('down')
        self.inputhandler.add_button('jump')
        
    def add_parkour(self):
        self.parkour = True
        self.hanging = self.onWall_R = self.onWall_L = self.climb = False
    
    def reset(self,entity):
        Person.reset(self,entity)
        self.status['health'].set(100)
        self.dead = False
        self.add_physics()
        self.add_parkour()
        
        
    def add_physics(self):
        self.physics = True
        self.acc = 1
        self.speed_limit = 4
        self.walk_limit = 2
        self.run_limit = 4
        self.sprint_limit = 8
        self.fall_time = 0
        self.fall_limit = 20
        self.wall_slide_limit = 25
        self.wall_slide_time = 0
        
        self.control = True
        
    def add_stats(self,entity):
        
        self.status = {}
        #health
        self.status.update({'health':Health()})
        #exp
        self.exp = None
        #self.status.append(self.exp)
        #hunger
        self.hunger = None
        #self.status.append(self.hunger)
        #stamina
        self.status.update({'stamina':Stamina()})

        #money
        self.money = 0
        #danger
        self.danger = 0

        
    def get_button(self,button):
        return self.inputhandler.button_list[button]
    
    def set_button(self,button,state):
        self.inputhandler.button_list[button] = state
        
    def admin_tick(self):
        #allows the player to float around
        self.xvel = self.yvel = 0
        if self.get_button('right'):
            self.xvel = 5
        if self.get_button('left'):
            self.xvel = -5
        if self.get_button('up'):
            self.yvel = -5
        if self.get_button('down'):
            self.yvel = 5
            
        self.rect.left += self.xvel
        self.rect.top += self.yvel
        
    def x_movement(self):
        if self.physics:
            if self.get_button('right') and not self.get_button('left') and self.control:
                if self.xvel <= self.speed_limit:
                    self.xvel += self.acc
                else:
                    self.xvel -= self.acc
            elif self.get_button('left') and not self.get_button('right') and self.control:
                if self.xvel >= -self.speed_limit:
                    self.xvel -= self.acc
                else:
                    self.xvel += self.acc
            elif (self.get_button('left') and self.get_button('right') and self.control) or \
                (not self.get_button('left') and not self.get_button('right') and self.control):
                if self.xvel != 0:
                    self.xvel /= 2
                    if -1< self.xvel < 1:
                        self.xvel = 0
                #allows a player to run
            if self.status['stamina'].state:
                if self.get_button('sprint'):
                    self.speed_limit = self.sprint_limit
                elif self.running:
                    self.speed_limit = self.run_limit
                else:
                    self.speed_limit = self.walk_limit
            else:
                self.speed_limit = self.walk_limit
        else:
            if self.get_button('right') and not self.get_button('left'):
                self.xvel = self.run_limit
            elif not self.get_button('right') and self.get_button('left'):
                self.xvel = -self.run_limit
            else:
                self.xvel = 0
            if self.get_button('sprint'):
                    self.xvel *=2
                
    def wall_movement(self):
        if self.onWall and self.wall_slide_limit > self.wall_slide_time:
            #wall slide
            if self.yvel > 0:
                self.yvel = 2
                self.wall_slide_time += 1
            #if on ground, do nothing
            elif self.yvel==0 and not self.hanging:
                return
            self.jumping = True
            #wall jump
            if self.get_button('jump'):
                if self.status['stamina'].cost(20):
                    if self.onWall_R and self.get_button('right') and not self.get_button('left'):
                        self.yvel = -15
                        self.xvel = -5
                    elif self.onWall_L and not self.get_button('right') and self.get_button('left'):
                        self.yvel = -15
                        self.xvel = 5
            #climb
            if self.get_button('up') and self.hanging:
                if self.status['stamina'].cost(10):
                    self.climb = True
                    self.yvel = -15
                    self.xvel = 0
            
        elif not self.onWall or self.hanging:
            self.wall_slide_time = 0
        elif self.wall_slide_limit <= self.wall_slide_time:
            self.onWall_L = self.onWall_R = self.onWall = False
        
    def tick(self,platforms,entity):
        #check if the character is dead or not
        if self.status['health'].current <= 0:
            self.dead = True
            

        self.onWall = self.onWall_L or self.onWall_R
        #make sure the charater has the control at certain point
        if not self.jumping or self.onWall or self.hanging or self.climb:
            self.control = True
        else:
            self.control = False
        
        
        #all the x-component movements
        self.x_movement()
        #apply gravity
        self.gravity.apply(self)
        #all wall-related movements
        self.wall_movement()
        
        #all the y-component movements    
        if self.onGround:
            self.jumping = self.climb = False
    
        if self.get_button('jump') and self.onGround:
            if self.status['stamina'].cost(20):
                self.yvel = -15
                self.set_button('jump',False)
                self.jumping = True
         
        Person.tick(self,platforms)
        
        if self.yvel > 2 and not self.onWall:
            
            self.fall_time+=1
        elif self.onWall and self.fall_time > 0:
            self.fall_time-=1
        elif self.onGround:
            self.status['health'].current -= int(self.fall_time/self.fall_limit) * 20
        if self.yvel <= 0:
            self.fall_time = 0
        #stamina calculation    
        if self.onGround:
            if abs(self.xvel) > self.run_limit:
                self.status['stamina'].cost(.5)
            elif abs(self.xvel) <= self.run_limit:
                self.status['stamina'].recover(1)
        #make sure status stays updated
        for s in self.status.values():
            s.update()
示例#12
0
class Player(Person):
    def __init__(self, spawn_x=100, spawn_y=100, entity=[]):
        Person.__init__(self, spawn_x, spawn_y, '0.png', 'player\\default')
        self.inputhandler = InputHandler()
        self.admin = self.physics = self.parkour = False
        self.add_basic_movement()
        self.add_physics()
        self.add_parkour()
        self.add_stats(entity)
        self.state = 'idle'
        self.stage = 0
        self.next_stage = False
        self.brightness = 50

        #temporary
        self.stamina_regen = True

        self.direc = 1  #right
        #self.add_animation()

    def add_animation(self):
        self.motion = 'default'

    def set_spawn(self, x, y):
        self.spawn_x = x
        self.spawn_y = y

    def reset_basic_movement(self):
        self.inputhandler = InputHandler()
        self.add_basic_movement()

    def add_basic_movement(self):
        self.jumping = self.onGround = self.running = False
        self.inputhandler.add_button('right')
        self.inputhandler.add_button('left')
        self.inputhandler.add_button('up')
        self.inputhandler.add_button('sprint')
        self.inputhandler.add_button('down')
        self.inputhandler.add_button('jump')

    def add_parkour(self):
        self.parkour = True
        self.hanging = self.onWall_R = self.onWall_L = self.climb = False

    def place(self, entity):
        Person.reset(self, entity)
        self.reset_basic_movement()

    def stamina_reset(self):
        self.status['stamina'].reset()

    def reset(self, entity):
        Person.reset(self, entity)
        self.status['health'].set(self.status['health'].maximum)
        self.status['stamina'].set(self.status['stamina'].maximum)
        self.dead = False
        self.add_physics()
        self.add_parkour()

    def add_physics(self):
        self.physics = True
        self.acc = 1
        self.speed_limit = 4
        self.walk_limit = 2
        self.run_limit = 4
        self.sprint_limit = 8
        self.fall_time = 0
        self.fall_limit = 20
        self.wall_slide_limit = 25
        self.wall_slide_time = 0

        self.control = True

    def add_stats(self, entity):

        self.status = {}
        #health
        self.status.update({'health': Health()})
        #exp
        self.exp = None
        #self.status.append(self.exp)
        #hunger
        self.hunger = None
        #self.status.append(self.hunger)
        #stamina
        self.status.update({'stamina': Stamina()})

        #money
        self.status.update({'money': Money()})
        #danger
        self.danger = 0

    def get_button(self, button):
        return self.inputhandler.button_list[button]

    def set_button(self, button, state):
        self.inputhandler.button_list[button] = state

    def admin_tick(self):
        #allows the player to float around
        self.xvel = self.yvel = 0
        if self.get_button('right'):
            self.xvel = 5
        if self.get_button('left'):
            self.xvel = -5
        if self.get_button('up'):
            self.yvel = -5
        if self.get_button('down'):
            self.yvel = 5

        self.rect.left += self.xvel
        self.rect.top += self.yvel

    def x_movement(self):
        if self.physics:
            if self.get_button(
                    'right') and not self.get_button('left') and self.control:
                if self.xvel <= self.speed_limit:
                    self.xvel += self.acc
                else:
                    self.xvel -= self.acc
            elif self.get_button(
                    'left') and not self.get_button('right') and self.control:
                if self.xvel >= -self.speed_limit:
                    self.xvel -= self.acc
                else:
                    self.xvel += self.acc
            elif (self.get_button('left') and self.get_button('right') and self.control) or \
                (not self.get_button('left') and not self.get_button('right') and self.control):
                if self.xvel != 0:
                    self.xvel /= 2
                    if -1 < self.xvel < 1:
                        self.xvel = 0

                #allows a player to run

            if self.get_button('sprint'):
                self.speed_limit = self.sprint_limit
            elif self.running:
                self.speed_limit = self.run_limit
            else:
                self.speed_limit = self.walk_limit

        else:
            if self.get_button('right') and not self.get_button('left'):
                self.xvel = self.run_limit
            elif not self.get_button('right') and self.get_button('left'):
                self.xvel = -self.run_limit
            else:
                self.xvel = 0
            if self.get_button('sprint'):
                self.xvel *= 2

    def wall_movement(self):
        if self.onWall and self.wall_slide_limit > self.wall_slide_time:
            #wall slide
            if self.yvel > 0:
                self.yvel = 2
                self.wall_slide_time += 1
            #if on ground, do nothing
            elif self.yvel == 0 and not self.hanging:
                return
            self.jumping = True
            #wall jump
            if self.get_button('jump') and not self.onGround:
                if self.status['stamina'].cost(20):
                    if self.onWall_R and self.get_button(
                            'right') and not self.get_button('left'):
                        self.yvel = -15
                        self.xvel = -5
                    elif self.onWall_L and not self.get_button(
                            'right') and self.get_button('left'):
                        self.yvel = -15
                        self.xvel = 5
            #climb
            if self.get_button('up') and self.hanging:
                if self.status['stamina'].cost(10):
                    self.climb = True
                    self.yvel = -15
                    self.xvel = 0

        elif not self.onWall or self.hanging:
            self.wall_slide_time = 0
        elif self.wall_slide_limit <= self.wall_slide_time:
            self.onWall_L = self.onWall_R = self.onWall = False

    def tick(self, platforms, entity):
        if self.status['health'].current <= 0:
            self.dead = True

        if self.parkour:
            self.onWall = self.onWall_L or self.onWall_R
        else:
            self.onWall = self.hanging = self.climb = False
            #make sure the charater has the control at certain point
        if not self.jumping or self.onWall or self.hanging or self.climb:
            self.control = True
        else:
            self.control = False

        #all the x-component movements
        self.x_movement()
        #apply gravity
        self.gravity.apply(self)
        #all wall-related movements
        if self.parkour:
            self.wall_movement()

        #all the y-component movements
        if self.onGround:
            self.jumping = self.climb = False

        if self.get_button('jump') and self.onGround:
            if self.status['stamina'].cost(20):
                self.yvel = -15 + self.stage
                self.set_button('jump', False)
                self.jumping = True

        Person.tick(self, platforms)

        if self.yvel > 2 and not self.onWall:

            self.fall_time += 1
        elif self.onWall and self.fall_time > 0:
            self.fall_time -= 1
        elif self.onGround:
            self.status['health'].current -= int(
                self.fall_time / self.fall_limit) * 20

        if self.yvel <= 0:
            self.fall_time = 0

        #make sure status stays updated
        for s in self.status.values():
            s.update()
示例#13
0
 def reset_basic_movement(self):
     self.inputhandler = InputHandler()
     self.add_basic_movement()
示例#14
0
class PlayScene(ogre.FrameListener, ogre.WindowEventListener):
    """
    This class represents the game's main scene - the play scene. This class
    sets up the initial scene and acts as the main game loop (via
    frameStarted()).
    """

    def __init__(self, sceneManager):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)

        
        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")
        
        # Create an empty list of nodes
        self.nodes = []
        
        # Set up the scene.
        self.setupScene()

        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
                     # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(OIS.OISKeyboard, True)
        except Exception: # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(mouse=self.mouse, keyboard=self.keyboard,
                                         scene=self, player=self.player)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(self.renderWindow, self)

    def __del__ (self ):
        # Clean up OIS 
        self.inputManager.destroyInputObjectKeyboard(self.keyboard)
        self.inputManager.destroyInputObjectMouse(self.mouse)
        OIS.InputManager.destroyInputSystem(self.inputManager)
        self.inputManager = None

        ogre.WindowEventUtilities.removeWindowEventListener(self.renderWindow, self)
        self.windowClosed(self.renderWindow)
        
    def setupScene(self):
        ## Load the level.
        # @todo: Remove .scene dependancy and move to external file (format?).
        
        # Load some data from the .scene file
        sceneLoader = SceneLoader.DotSceneLoader("media/testtilescene.scene", self.sceneManager)
        sceneLoader.parseDotScene()
        
        # Create the world.
        self.world = gamestate.world.World()
        
        # Attach a handler to world.object_added
        self.world.object_added += self.on_world_object_added
        
        # Add a player to the world and set it as our active player.
        self.player = gamestate.objects.Player(self.world)
        self.world.add_object(self.player)
        
        # Add stationary NPC ninja...
        npc = gamestate.objects.Player(self.world)
        self.world.add_object(npc)
        npc.position = (45, 45)
        npc.isPassable = False
        
        # Add boundary lines for map walls.
        # @todo: move this out of here!
        
        # north wall
        boundary1 = gamestate.objects.GameObject(self.world)
        boundary1.position = (-90, -90)
        boundary1.isPassable = False
        boundary1.bounding_shape = gamestate.collision.BoundingLineSegment((-90, -90),
                                                                           (90, -90),
                                                                           (0, 1))
        # south wall
        boundary2 = gamestate.objects.GameObject(self.world)
        boundary2.position = (-90, 90)
        boundary2.isPassable = False
        boundary2.bounding_shape = gamestate.collision.BoundingLineSegment((-90, 90),
                                                                           (90, 90),
                                                                           (0, -1))
        # east wall
        boundary3 = gamestate.objects.GameObject(self.world)
        boundary3.position = (90, -90)
        boundary3.isPassable = False
        boundary3.bounding_shape = gamestate.collision.BoundingLineSegment((90, -90),
                                                                           (90, 90),
                                                                           (-1, 0))
        # west wall
        boundary4 = gamestate.objects.GameObject(self.world)
        boundary4.position = (-90, -90)
        boundary4.isPassable = False
        boundary4.bounding_shape = gamestate.collision.BoundingLineSegment((-90, -90),
                                                                           (-90, 90),
                                                                           (1, 0))
        
        # bounding rectangle for testing
        boundary5 = gamestate.objects.GameObject(self.world)
        boundary5.position = (-30, 0)
        boundary5.isPassable = False
        boundary5.bounding_shape = gamestate.collision.BoundingRectangle(40, 40, 45)
        
        
        self.world.add_object(boundary1)
        self.world.add_object(boundary2)
        self.world.add_object(boundary3)
        self.world.add_object(boundary4)
        self.world.add_object(boundary5)
        
        # Listen to the player's position change event so we can mvoe the
        # camera with the player.
        self.player.position_changed += self.on_player_position_changed

        # Setup camera
        self.camera.nearClipDistance = 1
        self.camera.farClipDistance = 500
        self.camera.setProjectionType(ogre.PT_ORTHOGRAPHIC)

        # THIS SPECIFIES THE HEIGHT OF THE ORTHOGRAPHIC WINDOW
        # the width will be recalculated based on the aspect ratio
        # in ortho projection mode, decreasing the size of the window
        # is equivalent to zooming in, increasing is the equivalent of
        # zooming out.
        self.camera.setOrthoWindowHeight(200)

        # Setup camera node
        self.cameraNode.position = (0, 100, 100)
        self.cameraNode.pitch(ogre.Degree(-45))

    def frameStarted(self, event):
        """ 
        Called before a frame is displayed, handles events
        (also those via callback functions, as you need to call capture()
        on the input objects)

        Returning False here exits the application (render loop stops)
        """
        
        dt = event.timeSinceLastFrame

        # Capture any buffered events (and fire any callbacks).
        self.inputHandler.capture()
        
        # Update the game state world.
        self.world.update(dt)
        
        # Add time to animations.
        for node in self.nodes:
            node.animations_addtime(dt)

        # Neatly close our FrameListener if our renderWindow has been shut down
        # or we are quitting.
        if self.renderWindow.isClosed() or self.quit:
            return False
        
        return True
        
    ## Game event callbacks
    
    def on_world_object_added(self, gameObject):
        if gameObject.type == "player":
            self.nodes.append(nodes.PlayerNode(self.sceneManager, gameObject))
        
    def on_player_position_changed(self, mobileObject, position):
        self.cameraNode.position = (position[0], 100, position[1] + 100)

    ## Window event listener callbacks

    def windowResized(self, renderWindow):
        self.mouse.getMouseState().width = renderWindow.width
        self.mouse.getMouseState().height = renderWindow.height
        vp = self.camera.getViewport()
        self.camera.aspectRatio = vp.actualWidth / vp.actualHeight
        # @todo: Scale the image so viewable area remains the same.

    def windowClosed(self, renderWindow):
        # Only close for window that created OIS
        if(renderWindow == self.renderWindow):
            del self
示例#15
0
class PlayScene(ogre.FrameListener, ogre.WindowEventListener, SchedulerManager):
    """
    This class represents the game's main scene - the play scene. This class
    sets up the initial scene and acts as the main game loop (via
    frameStarted()).
    """

    def __init__(self, sceneManager, address, port, player_name):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)
        SchedulerManager.__init__(self)
        
        self.address = address
        self.port = port
        self.player_name = player_name
        self.is_round_active = False
        
        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")
        
        self.viewport = self.camera.getViewport()
        
        self.player = None
        self.last_update = None
        self.scores = { }
        self.scores_changed = Event()
        self.game_nodes = { }
        self.players = { }
        
        # Come up with a non-static way of doing this.
        self.nodes = []
        nodes.Node.node_created += self.on_node_created
        nodes.Node.node_destroyed += self.on_node_destroyed
        
        # Set up the scene.
        self.setupScene()
        
        # Load sounds.
        self.loadSceneSounds()
        
        # Set up the GUI.
        self.gui = PlaySceneGUI(self)
        self.gui.element_selected += self.on_gui_element_selected
        
        # Show a welcome message.
        self.gui.message.notice("Tides of the Elements")
        
        # Load scene music
        audio.set_background_music("media/sounds/Dispatches+Of+Humanity.wav")
        
        # Set up the input devices.
        self.setupInput()

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(self.renderWindow, self)
        
        # Begin scene music
        audio.play_background_music()

    def __del__ (self ):
        # Clean up OIS 
        self.inputManager.destroyInputObjectKeyboard(self.keyboard)
        self.inputManager.destroyInputObjectMouse(self.mouse)
        OIS.InputManager.destroyInputSystem(self.inputManager)
        self.inputManager = None

        ogre.WindowEventUtilities.removeWindowEventListener(self.renderWindow, self)
        self.windowClosed(self.renderWindow)
        
    def setupScene(self):
        ## Load the level.

        # Create the world.
        self.world = gamestate.world.World()
        
        # Load the scene into the Ogre world.
        # @todo: Remove .scene dependancy and move to external file (format?).
        sceneLoader = SceneLoader.DotSceneLoader("media/testtilescene.scene", self.sceneManager)
        sceneLoader.parseDotScene()
        
        # Attach a handler to world.object_added and removed
        self.world.object_added += self.on_world_object_added
        self.world.object_removed += self.on_world_object_removed
        
        # Load the scene into the game state.
        self.scene = gamestate.scenes.TestScene(self.world)

        # Create the client and set listeners.
        self.client = net.client.GameClient(self.world, self.address, self.port)
        self.client.connected += self.on_client_connected
        
        # Start the netclient and connect.
        self.client_thread = threading.Thread(target=self.client.go)
        self.client_thread.start()
        
        # Setup camera
        self.camera.nearClipDistance = 1
        self.camera.farClipDistance = 500
        self.camera.setProjectionType(ogre.PT_ORTHOGRAPHIC)

        # THIS SPECIFIES THE HEIGHT OF THE ORTHOGRAPHIC WINDOW
        # the width will be recalculated based on the aspect ratio
        # in ortho projection mode, decreasing the size of the window
        # is equivalent to zooming in, increasing is the equivalent of
        # zooming out.
        self.camera.setOrthoWindowHeight(200)

        # Setup camera node
        self.cameraNode.position = (0, 100, 100)
        self.cameraNode.pitch(ogre.Degree(-45))
        
    def loadSceneSounds(self):
        # Air Sounds
        audio.load_source("airshot",        "media/sounds/airshot.wav")
        audio.load_source("gustofwind",     "media/sounds/gustofwind.wav")
        audio.load_source("windwhisk",      "media/sounds/windwhisk.wav")
        audio.load_source("lightningbolt",  "media/sounds/lightningbolt.wav")
        
        # Earth Sounds
        audio.load_source("earthquake",     "media/sounds/earthquake.wav")
        audio.load_source("hook",           "media/sounds/hook.wav")
       
        # Fire Sounds
        audio.load_source("flamerush",      "media/sounds/flamerush.wav") 
        audio.load_source("lavasplash",     "media/sounds/lavasplash.wav")
        audio.load_source("ringoffire",     "media/sounds/ringoffire.wav")
        
        # Water Sounds
        audio.load_source("iceshot",        "media/sounds/iceshot.wav")
        audio.load_source("iceburst",       "media/sounds/iceburst.wav")
        audio.load_source("tidalwave",      "media/sounds/tidalwave.wav")
        audio.load_source("watergush",      "media/sounds/watergush.wav")
        
        # General Sounds
        audio.load_source("weaponswing",    "media/sounds/weaponswing.wav")
        audio.load_source("weaponswingmiss","media/sounds/weaponswingmiss.wav")
        audio.load_source("whiff",          "media/sounds/whiff.wav")
        audio.load_source("impact",         "media/sounds/impact.wav")
    
    def setupInput(self):
        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
                     # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(OIS.OISKeyboard, True)
        except Exception: # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(self.mouse, self.keyboard, self)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

    def frameStarted(self, event):
        """ 
        Called before a frame is displayed, handles events
        (also those via callback functions, as you need to call capture()
        on the input objects)

        Returning False here exits the application (render loop stops)
        """
        
        dt = event.timeSinceLastFrame
        
        # Get buffered input from server and process it.
        while not self.client.input.empty():
            packet = self.client.input.get_nowait()
            self.process_packet(packet)
        
        # Add time to schedulers.
        SchedulerManager.update(self, dt)
        
        # Capture any buffered events (and fire any callbacks).
        self.inputHandler.capture()
        
        # Update our UI Elements
        self.gui.update(dt)
        
        # Update the game state world.
        self.world.update(dt)
        
        # Update the audio module so it can throw its events
        audio.update(dt)
        
        # Send an PlayerUpdate packet to the server if appropriate.
        self._send_update()
        
        # Send buffered output to server.
        reactor.callFromThread(self.client.send)
        
        # Add time to animations.
        for node in self.nodes:
            node.update(dt)

        # Neatly close our FrameListener if our renderWindow has been shut down
        # or we are quitting.
        if self.renderWindow.isClosed() or self.quit:
            return False
        
        return True
        
    def on_node_created(self, node):
        self.nodes.append(node)
        
    def on_node_destroyed(self, node):
        self.nodes.remove(node)
        
    ## Net event callbacks & helpers
    def _send_update(self, check_time=True):
        """ Sends a PlayerUpdate packet to the server if appropriate. """
        if self.player is None or self.player.is_dead:
            return

        update = self._get_update()
        if self.last_update is not None:
            update_time, last_update = self.last_update
            
            # Don't send if we've sent in the last 0.1s.
            if check_time and update_time + 0.05 > self.world.time:
                return
                
            # Don't send if info hasn't changed since the last update.
            if last_update.x == update.x and last_update.z == update.z and \
                last_update.rotation == update.rotation and \
                last_update.move_speed == update.move_speed and \
                last_update.move_direction == update.move_direction:
                return
        
        # print "Sending player update to server."
        self.client.output.put_nowait(update)
        self.last_update = (self.world.time, update)
    
    def _get_update(self):
        """ Returns a PlayerUpdate packet based on the current player state. """
        update = packets.PlayerUpdate()
        update.x, update.z = self.player.position
        update.rotation = self.player.rotation
        if self.player.is_moving:
            update.move_speed = self.player.move_speed
            update.move_direction = self.player.move_direction
        else:
            update.move_speed = 0
            update.move_direction = 0
        return update

    def process_packet(self, packet):
        ptype = type(packet)
        # print "Processing packet=%s: %s from server." % (packet.id, ptype.__name__)
        
        # JoinResponse
        if ptype is packets.JoinResponse:
            # @todo: handle deny
            # Add a player to the world and set it as our active player.
            print "Creating player in world with id=%s." % packet.player_id
            self.player = gamestate.objects.Player(self.world)
            self.player.object_id = packet.player_id
            self.player.is_dead = True
            self.player.name = self.player_name
            self.players[self.player.object_id] = self.player
            self.scores[self.player.object_id] = 0
            self.scores_changed(self.scores)
            
            # Listen to the player's position change event so we can mvoe the
            # camera with the player.
            self.player.position_changed += self.on_player_position_changed
            self.player.element_changed += self.on_player_element_changed
            self.player.ability_requested += self.on_player_ability_requested
            self.player.is_dead_changed += self.on_player_is_dead_changed
            
            self.gui.element_selection.show()
            
        # SpawnResponse
        if ptype is packets.SpawnResponse:
            self.player.change_element(packet.element_type)
            self.player.position = (packet.x, packet.z)
            self.world.add_object(self.player, self.player.object_id)
            self.gui.setup_player_gui(self.player)
            self.is_round_active = True
        
        # ObjectInit
        elif ptype is packets.ObjectInit:
            if packet.object_type == "player":
                object = gamestate.objects.Player(self.world)
                object.name = packet.name
                object.change_element(packet.element_type)
                # @todo: implement owner_id, ttl
                self.world.add_object(object, packet.object_id)
                self.players[packet.object_id] = object
                if not self.scores.has_key(packet.object_id):
                    self.scores[packet.object_id] = 0
                    self.scores_changed(self.scores)
            else:
                raise Exception("Invalid object_type")

        # ObjectUpdate
        elif ptype is packets.ObjectUpdate:
            if not self.world.objects_hash.has_key(packet.object_id):
                # We don't know about this object yet, so we can't update it.
                print "Received ObjectUpdate for unnkown object id=%s" % packet.object_id
            else:
                object = self.world.objects_hash[packet.object_id]
                # print "Updating object id=%s." % object.object_id
                if packet.forced:
                    object.position = (packet.x, packet.z)
                    object.rotation = packet.rotation
                    if packet.move_speed > 0:
                        object.move_speed = packet.move_speed
                    else:
                        object.is_moving = False
                    object.move_direction = packet.move_direction
                    object.force_vector = (packet.force_x, packet.force_z)
                    object.is_dead = packet.is_dead
                else:
                    object.rotation = packet.rotation
                    object.force_vector = (packet.force_x, packet.force_z)
                    if object == self.player:
                        # This is an update about the player. We want to deal with
                        # this case differently so we don't overwrite some client
                        # states such as position.
                        object.is_dead = packet.is_dead
                        if packet.move_speed > 0:
                            object.move_speed = packet.move_speed
                        diff_vector = ogre.Vector2(packet.x - object.position[0],
                                                   packet.z - object.position[1])
                 #       if diff_vector.squaredLength() > 500:
                            # If the server tells us we're far from where we think
                            # we are, then warp to the server's location.
                  #          object.position = (packet.x, packet.z)
                    else:
                        # This is an update for another game object.
                        if packet.move_speed > 0:
                            object.is_moving = True
                            object.move_direction = packet.move_direction
                            object.move_speed = packet.move_speed
                            
                            diff_vector = ogre.Vector3(packet.x - object.position[0], 0, packet.z - object.position[1])
                            if diff_vector.squaredLength() > 500:
                                # If the server's location is far from where we
                                # thinkt his player is, then, then don't smooth.
                                object.position = (packet.x, packet.z)
                                object.rotation = packet.rotation
                            else:
                                # Smooth the difference in locations.
                                move_vector = ogre.Vector3(packet.move_speed * math.cos(packet.rotation + packet.move_direction), 0,
                                                           packet.move_speed * math.sin(packet.rotation + packet.move_direction))
                                resultant = diff_vector + move_vector
                                angle = math.atan2(resultant.z, resultant.x)
                                object.rotation = angle - packet.move_direction
                        else:
                            object.position = (packet.x, packet.z)
                            object.is_moving = False
                    if object.type == "player":
                        if packet.is_dead:
                            object.is_dead = packet.is_dead
        
        # ObjectStatusUpdate
        elif ptype is packets.ObjectStatusUpdate:
            if self.world.objects_hash.has_key(packet.object_id):
                object = self.world.objects_hash[packet.object_id]
                object.health = packet.health
                object.power = packet.power
            else:
                print "Ignoring ObjectStatusUpdate because player is not in world."
        
        # ObjectRemove
        elif ptype is packets.ObjectRemove:
            object = self.world.objects_hash[packet.object_id]
            if object.type == "player" and object.is_dead:
                # This is a player that probably just died. We will delay the
                # object's removal from the world for a short moment so that
                # objects can still collide with it. This is a fix to the
                # killing ability not showing collision with the player.
                # @todo: Fix this bug another way - this is putting the client
                # (slightly) out of synch with the server by keeping the object
                # around in the world.
                self.schedule(.25, self.world.remove_object, object)
            else:
                self.world.remove_object(object)
        
        # AbilityUsed
        elif ptype is packets.AbilityUsed:
            # print "Using ability id=%s on player_id=%s" % (packet.ability_id, packet.object_id)
            player = self.world.objects_hash[packet.object_id]
            player.use_ability(packet.ability_id)
            
        # Message
        elif ptype is packets.Message:
            if packet.type == "error": self.gui.message.error(packet.message)
            elif packet.type == "notice": self.gui.message.notice(packet.message)
            elif packet.type == "death": self.gui.message.death(packet.message)
            elif packet.type == "success": self.gui.message.success(packet.message)
            elif packet.type == "system": self.gui.message.system(packet.message)
            else: self.gui.message.system(packet.message)
            
        # ScoreUpdate
        elif ptype is packets.ScoreUpdate:
            # @todo: Delete these at some point.
            player = self.players[packet.player_id]
            player.score = packet.score
            self.scores[player.object_id] = player.score
            self.scores_changed(self.scores)
            
        # RoundEnd
        elif ptype is packets.RoundEnd:
            self.is_round_active = False
            self.player.is_dead = True
            self.gui.element_selection.hide()
            
        # RoundStart
        elif ptype is packets.RoundStart:
            self.is_round_active = True
            self.gui.element_selection.show()
            
        # ClientDisconnect
        elif ptype is packets.ClientDisconnect:
            if self.game_nodes.has_key(packet.player_id):
                node = self.game_nodes[packet.player_id]
                del self.game_nodes[packet.player_id]
                node.destroy()
            if self.players.has_key(packet.player_id):
                del self.players[packet.player_id]
            if self.scores.has_key(packet.player_id):
                del self.scores[packet.player_id]
                self.scores_changed(self.scores)
    
    def on_client_connected(self):
        packet = packets.JoinRequest()
        # @todo: Get player_name from somewhere.
        packet.player_name = self.player_name
        self.client.output.put_nowait(packet)
        
    ## Game event callbacks
    def on_world_object_added(self, object):
        if object.type == "player":
            if self.game_nodes.has_key(object.object_id):
                # We already have a node for this game object, but it may be
                # represented by another object in memory.
                node = self.game_nodes[object.object_id]
                if node.object == object:
                    # If it's the same object, we don't need a new node.
                    if node.corpse is not None:
                        node.corpse.destroy()
                        node.corpse = None
                    return
                # Otherwise, destroy the current node and create a new one.
                node.destroy()
            node = nodes.PlayerNode(self.sceneManager, object, "ninja.mesh")
            node.set_scale(.1)
            node.rotation -= math.pi/2
            self.game_nodes[object.object_id] = node
        elif object.type == "volcano":
            v = nodes.GameNode(self.sceneManager, object)
            v.set_mesh("volcano.mesh")
            v.set_particle_system("VolcanoEruption", position_offset=(0, 15, -5), scale=10)
            
    def on_world_object_removed(self, object):
        # @todo: Remove nodes at some point for players no longer here.
        pass
        
    def on_player_position_changed(self, mobileObject, position):
        self.cameraNode.position = (position[0], 100, position[1] + 100)
        
    def on_player_element_changed(self, player):
        # Recreate the ability bar GUI.
        self.gui.setup_ability_bar(self.player)
        
    def on_player_ability_requested(self, player, ability_id):
        ar = packets.AbilityRequest()
        ar.object_id = player.object_id
        ar.ability_id = ability_id
        # Send a PlayerUpdate so the server has the most recent information
        # about us when using the ability.
        self._send_update(check_time=False)
        self.client.output.put_nowait(ar)
        
    def on_player_is_dead_changed(self, player):
        if self.player.is_dead and self.is_round_active:
            # Show the element selection screen after 3 seconds.
            self.schedule(3, self.gui.element_selection.show)

    ## GUI event handlers
    def on_gui_element_selected(self, element_type):
        request = packets.SpawnRequest()
        request.element_type = element_type
        self.client.output.put_nowait(request)
        self.gui.element_selection.hide()

    ## Window event listener callbacks
    def windowResized(self, renderWindow):
        self.mouse.getMouseState().width = renderWindow.width
        self.mouse.getMouseState().height = renderWindow.height
        vp = self.viewport
        self.camera.aspectRatio = vp.actualWidth / vp.actualHeight
        # @todo: Scale the image so viewable area remains the same.

    def windowClosed(self, renderWindow):
        # Only close for window that created OIS
        if(renderWindow == self.renderWindow):
            del self
示例#16
0
class PlayScene(ogre.FrameListener, ogre.WindowEventListener):
    """
    This class represents the game's main scene - the play scene. This class
    sets up the initial scene and acts as the main game loop (via
    frameStarted()).
    """
    def __init__(self, sceneManager):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)

        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")

        # Create an empty list of nodes
        self.nodes = []

        # Set up the scene.
        self.setupScene()

        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
        # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(
                OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(
                OIS.OISKeyboard, True)
        except Exception:  # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(mouse=self.mouse,
                                         keyboard=self.keyboard,
                                         scene=self,
                                         player=self.player)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(
            self.renderWindow, self)

    def __del__(self):
        # Clean up OIS
        self.inputManager.destroyInputObjectKeyboard(self.keyboard)
        self.inputManager.destroyInputObjectMouse(self.mouse)
        OIS.InputManager.destroyInputSystem(self.inputManager)
        self.inputManager = None

        ogre.WindowEventUtilities.removeWindowEventListener(
            self.renderWindow, self)
        self.windowClosed(self.renderWindow)

    def setupScene(self):
        ## Load the level.
        # @todo: Remove .scene dependancy and move to external file (format?).

        # Load some data from the .scene file
        sceneLoader = SceneLoader.DotSceneLoader("media/testtilescene.scene",
                                                 self.sceneManager)
        sceneLoader.parseDotScene()

        # Create the world.
        self.world = gamestate.world.World()

        # Attach a handler to world.object_added
        self.world.object_added += self.on_world_object_added

        # Add a player to the world and set it as our active player.
        self.player = gamestate.objects.Player(self.world)
        self.world.add_object(self.player)

        # Add stationary NPC ninja...
        npc = gamestate.objects.Player(self.world)
        self.world.add_object(npc)
        npc.position = (45, 45)
        npc.isPassable = False

        # Add boundary lines for map walls.
        # @todo: move this out of here!

        # north wall
        boundary1 = gamestate.objects.GameObject(self.world)
        boundary1.position = (-90, -90)
        boundary1.isPassable = False
        boundary1.bounding_shape = gamestate.collision.BoundingLineSegment(
            (-90, -90), (90, -90), (0, 1))
        # south wall
        boundary2 = gamestate.objects.GameObject(self.world)
        boundary2.position = (-90, 90)
        boundary2.isPassable = False
        boundary2.bounding_shape = gamestate.collision.BoundingLineSegment(
            (-90, 90), (90, 90), (0, -1))
        # east wall
        boundary3 = gamestate.objects.GameObject(self.world)
        boundary3.position = (90, -90)
        boundary3.isPassable = False
        boundary3.bounding_shape = gamestate.collision.BoundingLineSegment(
            (90, -90), (90, 90), (-1, 0))
        # west wall
        boundary4 = gamestate.objects.GameObject(self.world)
        boundary4.position = (-90, -90)
        boundary4.isPassable = False
        boundary4.bounding_shape = gamestate.collision.BoundingLineSegment(
            (-90, -90), (-90, 90), (1, 0))

        # bounding rectangle for testing
        boundary5 = gamestate.objects.GameObject(self.world)
        boundary5.position = (-30, 0)
        boundary5.isPassable = False
        boundary5.bounding_shape = gamestate.collision.BoundingRectangle(
            40, 40, 45)

        self.world.add_object(boundary1)
        self.world.add_object(boundary2)
        self.world.add_object(boundary3)
        self.world.add_object(boundary4)
        self.world.add_object(boundary5)

        # Listen to the player's position change event so we can mvoe the
        # camera with the player.
        self.player.position_changed += self.on_player_position_changed

        # Setup camera
        self.camera.nearClipDistance = 1
        self.camera.farClipDistance = 500
        self.camera.setProjectionType(ogre.PT_ORTHOGRAPHIC)

        # THIS SPECIFIES THE HEIGHT OF THE ORTHOGRAPHIC WINDOW
        # the width will be recalculated based on the aspect ratio
        # in ortho projection mode, decreasing the size of the window
        # is equivalent to zooming in, increasing is the equivalent of
        # zooming out.
        self.camera.setOrthoWindowHeight(200)

        # Setup camera node
        self.cameraNode.position = (0, 100, 100)
        self.cameraNode.pitch(ogre.Degree(-45))

    def frameStarted(self, event):
        """ 
        Called before a frame is displayed, handles events
        (also those via callback functions, as you need to call capture()
        on the input objects)

        Returning False here exits the application (render loop stops)
        """

        dt = event.timeSinceLastFrame

        # Capture any buffered events (and fire any callbacks).
        self.inputHandler.capture()

        # Update the game state world.
        self.world.update(dt)

        # Add time to animations.
        for node in self.nodes:
            node.animations_addtime(dt)

        # Neatly close our FrameListener if our renderWindow has been shut down
        # or we are quitting.
        if self.renderWindow.isClosed() or self.quit:
            return False

        return True

    ## Game event callbacks

    def on_world_object_added(self, gameObject):
        if gameObject.type == "player":
            self.nodes.append(nodes.PlayerNode(self.sceneManager, gameObject))

    def on_player_position_changed(self, mobileObject, position):
        self.cameraNode.position = (position[0], 100, position[1] + 100)

    ## Window event listener callbacks

    def windowResized(self, renderWindow):
        self.mouse.getMouseState().width = renderWindow.width
        self.mouse.getMouseState().height = renderWindow.height
        vp = self.camera.getViewport()
        self.camera.aspectRatio = vp.actualWidth / vp.actualHeight
        # @todo: Scale the image so viewable area remains the same.

    def windowClosed(self, renderWindow):
        # Only close for window that created OIS
        if (renderWindow == self.renderWindow):
            del self
示例#17
0
 def reset_basic_movement(self):
     self.inputhandler = InputHandler()
     self.add_basic_movement()
示例#18
0
from kivy.app import App
from lanedisplay import LaneDisplay
from lanesliders import LaneSliders
from lanecanvas import LaneCanvas
from gearshift import GearShift
from speedyawadjust import SpeedYawAdjust
from lanecenteringstatus import LaneCenteringStatus
from sliderinput import SliderInput
from inputhandler import InputHandler

input_handler = InputHandler()


class MockUIApp(App):
    def __init__(self, **kwargs):
        super(MockUIApp, self).__init__(**kwargs)
示例#19
0
class PlayScene(ogre.FrameListener, ogre.WindowEventListener):
    """
    This class represents the game's main scene - the play scene. This class
    sets up the initial scene and acts as the main game loop (via
    frameStarted()).
    """
    def __init__(self, sceneManager, address, port):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)

        self.address = address
        self.port = port

        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")

        # Create an empty list of nodes
        self.nodes = []

        # Set up the scene.
        self.setupScene()

        # Init attributes.
        self.player = None
        self.last_update = None

        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
        # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(
                OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(
                OIS.OISKeyboard, True)
        except Exception:  # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(self.mouse, self.keyboard, self)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(
            self.renderWindow, self)

    def __del__(self):
        # Clean up OIS
        self.inputManager.destroyInputObjectKeyboard(self.keyboard)
        self.inputManager.destroyInputObjectMouse(self.mouse)
        OIS.InputManager.destroyInputSystem(self.inputManager)
        self.inputManager = None

        ogre.WindowEventUtilities.removeWindowEventListener(
            self.renderWindow, self)
        self.windowClosed(self.renderWindow)

    def setupScene(self):
        ## Load the level.
        # @todo: Remove .scene dependancy and move to external file (format?).

        # Load some data from the .scene file
        sceneLoader = SceneLoader.DotSceneLoader("media/testtilescene.scene",
                                                 self.sceneManager)
        sceneLoader.parseDotScene()

        # Create the world.
        self.world = gamestate.world.World()

        # Create the client and set listeners.
        self.client = net.client.GameClient(self.world, self.address,
                                            self.port)
        self.client.connected += self.on_client_connected

        # Start the netclient and connect.
        self.client_thread = threading.Thread(target=self.client.go)
        self.client_thread.start()

        # Attach a handler to world.object_added
        self.world.object_added += self.on_world_object_added

        # Set up the TestScene
        self.scene = gamestate.scenes.TestScene(self.world)

        # Setup camera
        self.camera.nearClipDistance = 1
        self.camera.farClipDistance = 500
        self.camera.setProjectionType(ogre.PT_ORTHOGRAPHIC)

        # THIS SPECIFIES THE HEIGHT OF THE ORTHOGRAPHIC WINDOW
        # the width will be recalculated based on the aspect ratio
        # in ortho projection mode, decreasing the size of the window
        # is equivalent to zooming in, increasing is the equivalent of
        # zooming out.
        self.camera.setOrthoWindowHeight(200)

        # Setup camera node
        self.cameraNode.position = (0, 100, 100)
        self.cameraNode.pitch(ogre.Degree(-45))

    def frameStarted(self, event):
        """ 
        Called before a frame is displayed, handles events
        (also those via callback functions, as you need to call capture()
        on the input objects)

        Returning False here exits the application (render loop stops)
        """

        dt = event.timeSinceLastFrame

        # Get buffered input from server and process it.
        while not self.client.input.empty():
            packet = self.client.input.get_nowait()
            self.process_packet(packet)

        # Capture any buffered events (and fire any callbacks).
        self.inputHandler.capture()

        # Update the game state world.
        self.world.update(dt)

        # Send an PlayerUpdate packet to the server if appropriate.
        self._send_update()

        # Send buffered output to server.
        reactor.callFromThread(self.client.send)

        # Add time to animations.
        for node in self.nodes:
            node.animations_addtime(dt)

        # Neatly close our FrameListener if our renderWindow has been shut down
        # or we are quitting.
        if self.renderWindow.isClosed() or self.quit:
            return False

        return True

    ## Net event callbacks & helpers

    def _send_update(self):
        """ Sends a PlayerUpdate packet to the server if appropriate. """
        if self.player is None:
            return

        update = self._get_update()
        if self.last_update is not None:
            update_time, last_update = self.last_update

            # Don't send if we've sent in the last 0.1s.
            if update_time + 0.05 > self.world.time:
                return

            # Don't send if info hasn't changed since the last update.
            if last_update.x == update.x and last_update.z == update.z and \
                last_update.rotation == update.rotation and \
                last_update.move_speed == update.move_speed and \
                last_update.move_direction == update.move_direction:
                return

        print "Sending player update to server."
        self.client.output.put_nowait(update)
        self.last_update = (self.world.time, update)

    def _get_update(self):
        """ Returns a PlayerUpdate packet based on the current player state. """
        update = packets.PlayerUpdate()
        update.x, update.z = self.player.position
        update.rotation = self.player.rotation
        if self.player.is_moving:
            update.move_speed = self.player.move_speed
            update.move_direction = self.player.move_direction
        else:
            update.move_speed = 0
            update.move_direction = 0
        return update

    def process_packet(self, packet):
        ptype = type(packet)
        print "Processing packet=%s: %s from server." % (packet.id,
                                                         ptype.__name__)

        # JoinResponse
        if ptype is packets.JoinResponse:
            # @todo: handle deny
            # Add a player to the world and set it as our active player.
            print "Creating player in world with id=%s." % packet.player_id
            self.player = gamestate.objects.Player(self.world)
            self.world.add_object(self.player, packet.player_id)

            # Listen to the player's position change event so we can mvoe the
            # camera with the player.
            self.player.position_changed += self.on_player_position_changed

        # ObjectInit
        elif ptype is packets.ObjectInit:
            if packet.object_type == "player":
                object = gamestate.objects.Player(self.world)
            else:
                raise Exception("Invalid object_type")
            # @todo: implement name, owner_id, ttl

            self.world.add_object(object, packet.object_id)

        # ObjectUpdate
        elif ptype is packets.ObjectUpdate:
            if not self.world.objects_hash.has_key(packet.object_id):
                return
            object = self.world.objects_hash[packet.object_id]
            print "Updating object id=%s." % object.object_id
            object.rotation = packet.rotation
            try:
                if packet.move_speed > 0:
                    diff_vector = ogre.Vector3(packet.x - object.position[0],
                                               0,
                                               packet.z - object.position[1])
                    move_vector = ogre.Vector3(
                        packet.move_speed * math.cos(packet.rotation), 0,
                        packet.move_speed * math.sin(packet.rotation))
                    resultant = diff_vector + move_vector
                    angle = math.atan2(resultant.z, resultant.x)
                    object.move_speed = packet.move_speed
                    object.rotation = angle
                    object.move_direction = 0
                    object.is_moving = True
                else:
                    object.position = (packet.x, packet.z)
                    object.is_moving = False
            except:
                object.position = (packet.x, packet.z)

    def on_client_connected(self):
        packet = packets.JoinRequest()
        # @todo: Get player_name from somewhere.
        packet.player_name = "Player1"
        self.client.output.put_nowait(packet)

    ## Game event callbacks
    def on_world_object_added(self, gameObject):
        if gameObject.type == "player":
            self.nodes.append(nodes.PlayerNode(self.sceneManager, gameObject))

    def on_player_position_changed(self, mobileObject, position):
        self.cameraNode.position = (position[0], 100, position[1] + 100)

    ## Window event listener callbacks
    def windowResized(self, renderWindow):
        self.mouse.getMouseState().width = renderWindow.width
        self.mouse.getMouseState().height = renderWindow.height
        vp = self.camera.getViewport()
        self.camera.aspectRatio = vp.actualWidth / vp.actualHeight
        # @todo: Scale the image so viewable area remains the same.

    def windowClosed(self, renderWindow):
        # Only close for window that created OIS
        if (renderWindow == self.renderWindow):
            del self
示例#20
0
class PlayScene(ogre.FrameListener, ogre.WindowEventListener):
    """
    This class represents the game's main scene - the play scene. This class
    sets up the initial scene and acts as the main game loop (via
    frameStarted()).
    """

    def __init__(self, sceneManager):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)

        
        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")
        
        self.viewport = self.camera.getViewport()
        
        # Create an empty list of nodes
        self.nodes = []
        
        # Create an empty list of GUI elements.
        self.gui_elements = [] 
        
        # Set up the overlay for the GUI.
        self.setupOverlay()
        
        # Set up the scene.
        self.setupScene()
        
        # Set up the GUI.
        self.setupGUI()
        
        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
                     # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(OIS.OISKeyboard, True)
        except Exception: # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(mouse=self.mouse, keyboard=self.keyboard,
                                         scene=self, player=self.player)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(self.renderWindow, self)

    def __del__ (self ):
        # Clean up OIS 
        self.inputManager.destroyInputObjectKeyboard(self.keyboard)
        self.inputManager.destroyInputObjectMouse(self.mouse)
        OIS.InputManager.destroyInputSystem(self.inputManager)
        self.inputManager = None

        ogre.WindowEventUtilities.removeWindowEventListener(self.renderWindow, self)
        self.windowClosed(self.renderWindow)
        
    def setupScene(self):
        ## Load the level.
        # @todo: Remove .scene dependancy and move to external file (format?).
        
        # Load some data from the .scene file
        sceneLoader = SceneLoader.DotSceneLoader("media/testtilescene.scene", self.sceneManager)
        sceneLoader.parseDotScene()
        
        # Create the world.
        self.world = gamestate.world.World()
        
        # Attach a handler to world.object_added
        self.world.object_added += self.on_world_object_added
        
        # Add a player to the world and set it as our active player.
        self.player = gamestate.objects.Player(self.world)
        self.world.add_object(self.player)
        
        # Add stationary NPC ninja...
        npc = gamestate.objects.Player(self.world)
        self.world.add_object(npc)
        npc.position = (-500, 0)
        npc.isPassable = False
        
        # Add boundary lines for map walls.       
        self.setup_level_boundaries("media/levelbounds.bounds")
        
        # Listen to player events.
        self.player.position_changed += self.on_player_position_changed
        self.player.element_changed += self.on_player_element_changed

        # Setup camera
        self.camera.nearClipDistance = 1
        self.camera.farClipDistance = 500
        self.camera.setProjectionType(ogre.PT_ORTHOGRAPHIC)

        # THIS SPECIFIES THE HEIGHT OF THE ORTHOGRAPHIC WINDOW
        # the width will be recalculated based on the aspect ratio
        # in ortho projection mode, decreasing the size of the window
        # is equivalent to zooming in, increasing is the equivalent of
        # zooming out.
        self.camera.setOrthoWindowHeight(200)

        # Setup camera node
        self.cameraNode.position = (0, 100, 100)
        self.cameraNode.pitch(ogre.Degree(-45))
        
    def setupGUI(self):
        # Set up health and power bars
        health_bar_rect = ogre.Rectangle()
        health_bar_rect.left = self.viewport.actualWidth / 2 - 128
        health_bar_rect.top = self.viewport.actualHeight - 84
        health_bar_rect.right = health_bar_rect.left + 256
        health_bar_rect.bottom = health_bar_rect.top + 10
        health_bar = gui.StatusBar("UI/StatusBars/Health", health_bar_rect, self.player.max_health)
        health_bar.name = "Health"
        
        power_bar_rect = ogre.Rectangle()
        power_bar_rect.left = health_bar_rect.left
        power_bar_rect.top = health_bar_rect.bottom
        power_bar_rect.right = health_bar_rect.right
        power_bar_rect.bottom = power_bar_rect.top + 10
        power_bar = gui.StatusBar("UI/StatusBars/Power", power_bar_rect, self.player.max_power)
        power_bar.name = "Power"
        
        # Add the gui elements to the element list.
        self.gui_elements.append(health_bar)
        self.gui_elements.append(power_bar)
        
        # Add listeners to player's health and power changed events.
        self.player.health_changed += health_bar.on_value_changed
        self.player.power_changed += power_bar.on_value_changed
        
        # Create an FPS label.
        fpslabel = gui.FPSLabel("UI/FPSLabel")
        self.gui_elements.append(fpslabel)
        
        # Set up the ability bar.
        self.setupGUIAbilityBar()
    
    def setupGUIAbilityBar(self):
        player = self.player
        
        # Set up ability cooldown displays        
        ability_keys = player.element.ability_keys
        ability_cooldowns = player.element.ability_cooldowns
        ability1_cooldown = ability_cooldowns[ability_keys[1]]
        ability2_cooldown = ability_cooldowns[ability_keys[2]]
        ability3_cooldown = ability_cooldowns[ability_keys[3]]
        ability4_cooldown = ability_cooldowns[ability_keys[4]]
        
        # Set up ability icons.
        if player.element.type == "fire":
            # Fire
            ability1_icon_mat = "FireIconAbility1"
            ability2_icon_mat = "FireIconAbility2"
            ability3_icon_mat = "FireIconAbility3"
            ability4_icon_mat = "FireIconAbility4"
        elif player.element.type == "earth":
            # Earth
            ability1_icon_mat = "EarthIconAbility1"
            ability2_icon_mat = "EarthIconAbility2"
            ability3_icon_mat = "EarthIconAbility3"
            ability4_icon_mat = "EarthIconAbility4"
        elif player.element.type == "air":
            # Air
            ability1_icon_mat = "AirIconAbility1"
            ability2_icon_mat = "AirIconAbility2"
            ability3_icon_mat = "AirIconAbility3"
            ability4_icon_mat = "AirIconAbility4"
        elif player.element.type == "water":
            # Water
            ability1_icon_mat = "WaterIconAbility1"
            ability2_icon_mat = "WaterIconAbility2"
            ability3_icon_mat = "WaterIconAbility3"
            ability4_icon_mat = "WaterIconAbility4"
        
        # Create UI Elements      
        ability1_cdd_rect = ogre.Rectangle()
        ability1_cdd_rect.left = self.viewport.actualWidth / 2 - 128
        ability1_cdd_rect.top = self.viewport.actualHeight - 64
        ability1_cdd_rect.right = ability1_cdd_rect.left + 64
        ability1_cdd_rect.bottom = ability1_cdd_rect.top + 64
        ability1_cooldown_display = gui.AbilityCooldownDisplay("UI/AbilityBar/Ability1", ability1_cdd_rect, 1, ability1_cooldown)
        ability1_cooldown_display.overlay.setMaterialName(ability1_icon_mat)
        
        ability2_cdd_rect = ogre.Rectangle()
        ability2_cdd_rect.left = ability1_cdd_rect.right
        ability2_cdd_rect.top = ability1_cdd_rect.top
        ability2_cdd_rect.right = ability2_cdd_rect.left + 64
        ability2_cdd_rect.bottom = ability2_cdd_rect.top + 64
        ability2_cooldown_display = gui.AbilityCooldownDisplay("UI/AbilityBar/Ability2", ability2_cdd_rect, 2, ability2_cooldown)
        ability2_cooldown_display.overlay.setMaterialName(ability2_icon_mat)
        
        ability3_cdd_rect = ogre.Rectangle()
        ability3_cdd_rect.left = ability2_cdd_rect.right
        ability3_cdd_rect.top = ability2_cdd_rect.top
        ability3_cdd_rect.right = ability3_cdd_rect.left + 64
        ability3_cdd_rect.bottom = ability3_cdd_rect.top + 64
        ability3_cooldown_display = gui.AbilityCooldownDisplay("UI/AbilityBar/Ability3", ability3_cdd_rect, 3, ability3_cooldown)
        ability3_cooldown_display.overlay.setMaterialName(ability3_icon_mat)
        
        ability4_cdd_rect = ogre.Rectangle()
        ability4_cdd_rect.left = ability3_cdd_rect.right
        ability4_cdd_rect.top = ability3_cdd_rect.top
        ability4_cdd_rect.right = ability4_cdd_rect.left + 64
        ability4_cdd_rect.bottom = ability4_cdd_rect.top + 64
        ability4_cooldown_display = gui.AbilityCooldownDisplay("UI/AbilityBar/Ability4", ability4_cdd_rect, 4, ability4_cooldown)
        ability4_cooldown_display.overlay.setMaterialName(ability4_icon_mat)
        
        # Add the gui elements to the element list.
        self.gui_elements.append(ability1_cooldown_display)
        self.gui_elements.append(ability2_cooldown_display)
        self.gui_elements.append(ability3_cooldown_display)
        self.gui_elements.append(ability4_cooldown_display)
        
        # Listen to player events (why isn't this the same as how
        # StatusBar listens to its events?):
        ability1_cooldown_display.set_player_listener(self.player)
        ability2_cooldown_display.set_player_listener(self.player)
        ability3_cooldown_display.set_player_listener(self.player)
        ability4_cooldown_display.set_player_listener(self.player)
        
    def setupOverlay(self):
        pOver = ogre.OverlayManager.getSingleton().getByName("UI")
        pOver.show()
        
    def setup_level_boundaries(self, filepath):
        """
        Takes an xml-style file that specifies all of the level's static boundinglinesegments, and creates those
        bounds in the world.
        """
        xml_data = minidom.parse(filepath)
        docRoot = xml_data.getElementsByTagName('segments')[0].childNodes
        for segmentNode in docRoot:
            if segmentNode.nodeType == Node.ELEMENT_NODE and segmentNode.nodeName == 'segment':
                point1_data = self.getXMLNode(segmentNode, "point1").attributes
                point2_data = self.getXMLNode(segmentNode, "point2").attributes
                normal_data = self.getXMLNode(segmentNode, "normal").attributes
                
                point1 = (float(point1_data["x"].nodeValue),  -float(point1_data["z"].nodeValue))
                point2 = (float(point2_data["x"].nodeValue),  -float(point2_data["z"].nodeValue))
                normal = (float(normal_data["x"].nodeValue),  float(normal_data["z"].nodeValue))
                
                boundary_wall = gamestate.objects.GameObject(self.world)
                boundary_wall.isPassable = False
                boundary_wall.position = point1
                
                boundary_wall.bounding_shape = gamestate.collision.BoundingLineSegment(point1, point2, normal)
                
                self.world.add_object(boundary_wall)
                
    def getXMLNode(self, base, name):
        """
        This function basically doubles as both a test for element 
        existence and a getter for that element node... used with setup_level_boundaries()
        """
        if base.hasChildNodes:
            baseChildNodes = base.childNodes
            
            for node in baseChildNodes:
                if node.nodeType == Node.ELEMENT_NODE and node.nodeName == name:
                    return node
            
            return False

    def frameStarted(self, event):
        """ 
        Called before a frame is displayed, handles events
        (also those via callback functions, as you need to call capture()
        on the input objects)

        Returning False here exits the application (render loop stops)
        """
        
        dt = event.timeSinceLastFrame
        
        # Capture any buffered events (and fire any callbacks).
        self.inputHandler.capture()
        
        # Update our UI Elements
        for element in self.gui_elements:
            element.update(dt)
        
        # Update the game state world.
        self.world.update(dt)
        
        # Add time to animations.
        for node in self.nodes:
            node.animations_addtime(dt)

        # Neatly close our FrameListener if our renderWindow has been shut down
        # or we are quitting.
        if self.renderWindow.isClosed() or self.quit:
            return False
        
        return True
 
    ## Game event callbacks
    def on_world_object_added(self, gameObject):
        if gameObject.type == "player":
            newPlayerNode = nodes.PlayerNode(self.sceneManager, gameObject, "ninja.mesh")
            newPlayerNode.set_scale(.1)
            self.nodes.append(newPlayerNode)
        
    def on_player_position_changed(self, mobileObject, position):
        self.cameraNode.position = (position[0], 100, position[1] + 100)
        
    def on_player_element_changed(self, player):
        # Remove all current gui.AbilityCooldownDisplay from the current gui.
        self.gui_elements = [element for element in self.gui_elements
            if type(element) is not gui.AbilityCooldownDisplay]
        # Recreate the ability bar GUI.
        self.setupGUIAbilityBar()
        
    def on_static_node_expired(self, static_node):
        print static_node.unique_scene_node_name
        self.sceneManager.destroySceneNode(static_node.unique_scene_node_name)

    ## Window event listener callbacks
    def windowResized(self, renderWindow):
        self.mouse.getMouseState().width = renderWindow.width
        self.mouse.getMouseState().height = renderWindow.height
        vp = self.viewport
        self.camera.aspectRatio = vp.actualWidth / vp.actualHeight
        # @todo: Scale the image so viewable area remains the same.

    def windowClosed(self, renderWindow):
        # Only close for window that created OIS
        if(renderWindow == self.renderWindow):
            del self
示例#21
0
def signal_handler(signum, frame):
    exit(0)


clear()
title = 'Arsatum v0.0.1'
os.system(f'title {title}')

world = World(WIDTH, HEIGHT)
world.init()

# clear()
# print(f'''Welcome to {title}''')
# print('''-------------------''')
# text = '''
# movement          windows                 actions
# 789 \\|/      i - inventory          p - pick up item
# 4.6 -.-      e - charecter window   space - descend/ascend stairs
# 123 /|\\      l - message log        num 5 - pass turn
#              j - journal
#              n - achievements
# '''.strip()
# print(text)

# input('Press [enter] to start.')

InputHandler(world).start()
world.update(False)
signal.signal(signal.SIGINT, signal_handler)
time.sleep(99999)
示例#22
0
class PlayScene(ogre.FrameListener, ogre.WindowEventListener):
    """
    This class represents the game's main scene - the play scene. This class
    sets up the initial scene and acts as the main game loop (via
    frameStarted()).
    """
    def __init__(self, sceneManager):
        # Initialize the various listener classes we are a subclass from
        ogre.FrameListener.__init__(self)
        ogre.WindowEventListener.__init__(self)

        self.renderWindow = ogre.Root.getSingleton().getAutoCreatedWindow()
        self.sceneManager = sceneManager
        self.camera = self.sceneManager.getCamera("PrimaryCamera")
        self.cameraNode = self.sceneManager.getSceneNode("PrimaryCamera")

        self.viewport = self.camera.getViewport()

        # Create an empty list of nodes
        self.nodes = []

        # Create an empty list of GUI elements.
        self.gui_elements = []

        # Set up the overlay for the GUI.
        self.setupOverlay()

        # Set up the scene.
        self.setupScene()

        # Set up the GUI.
        self.setupGUI()

        # Create the inputManager using the supplied renderWindow
        windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")
        paramList = [("WINDOW", str(windowHnd)), \
                     ("w32_mouse", "DISCL_FOREGROUND"), \
                     ("w32_mouse", "DISCL_NONEXCLUSIVE"), \
                     ("w32_keyboard", "DISCL_FOREGROUND"), \
                     ("w32_keyboard", "DISCL_NONEXCLUSIVE"),]
        # @todo: add mac/linux parameters
        self.inputManager = OIS.createPythonInputSystem(paramList)

        # Attempt to get the mouse/keyboard input device objects.
        try:
            self.mouse = self.inputManager.createInputObjectMouse(
                OIS.OISMouse, True)
            self.keyboard = self.inputManager.createInputObjectKeyboard(
                OIS.OISKeyboard, True)
        except Exception:  # Unable to obtain mouse/keyboard input
            raise

        # Use an InputHandler object to handle the callback functions.
        self.inputHandler = InputHandler(mouse=self.mouse,
                                         keyboard=self.keyboard,
                                         scene=self,
                                         player=self.player)
        self.mouse.setEventCallback(self.inputHandler)
        self.keyboard.setEventCallback(self.inputHandler)

        # Set up initial window size.
        self.windowResized(self.renderWindow)

        # Set this to True when we get an event to exit the application
        self.quit = False

        # Listen for any events directed to the window manager's close button
        ogre.WindowEventUtilities.addWindowEventListener(
            self.renderWindow, self)

    def __del__(self):
        # Clean up OIS
        self.inputManager.destroyInputObjectKeyboard(self.keyboard)
        self.inputManager.destroyInputObjectMouse(self.mouse)
        OIS.InputManager.destroyInputSystem(self.inputManager)
        self.inputManager = None

        ogre.WindowEventUtilities.removeWindowEventListener(
            self.renderWindow, self)
        self.windowClosed(self.renderWindow)

    def setupScene(self):
        ## Load the level.
        # @todo: Remove .scene dependancy and move to external file (format?).

        # Load some data from the .scene file
        sceneLoader = SceneLoader.DotSceneLoader("media/testtilescene.scene",
                                                 self.sceneManager)
        sceneLoader.parseDotScene()

        # Create the world.
        self.world = gamestate.world.World()

        # Attach a handler to world.object_added
        self.world.object_added += self.on_world_object_added

        # Add a player to the world and set it as our active player.
        self.player = gamestate.objects.Player(self.world)
        self.world.add_object(self.player)

        # Add stationary NPC ninja...
        npc = gamestate.objects.Player(self.world)
        self.world.add_object(npc)
        npc.position = (-500, 0)
        npc.isPassable = False

        # Add boundary lines for map walls.
        self.setup_level_boundaries("media/levelbounds.bounds")

        # Listen to player events.
        self.player.position_changed += self.on_player_position_changed
        self.player.element_changed += self.on_player_element_changed

        # Setup camera
        self.camera.nearClipDistance = 1
        self.camera.farClipDistance = 500
        self.camera.setProjectionType(ogre.PT_ORTHOGRAPHIC)

        # THIS SPECIFIES THE HEIGHT OF THE ORTHOGRAPHIC WINDOW
        # the width will be recalculated based on the aspect ratio
        # in ortho projection mode, decreasing the size of the window
        # is equivalent to zooming in, increasing is the equivalent of
        # zooming out.
        self.camera.setOrthoWindowHeight(200)

        # Setup camera node
        self.cameraNode.position = (0, 100, 100)
        self.cameraNode.pitch(ogre.Degree(-45))

    def setupGUI(self):
        # Set up health and power bars
        health_bar_rect = ogre.Rectangle()
        health_bar_rect.left = self.viewport.actualWidth / 2 - 128
        health_bar_rect.top = self.viewport.actualHeight - 84
        health_bar_rect.right = health_bar_rect.left + 256
        health_bar_rect.bottom = health_bar_rect.top + 10
        health_bar = gui.StatusBar("UI/StatusBars/Health", health_bar_rect,
                                   self.player.max_health)
        health_bar.name = "Health"

        power_bar_rect = ogre.Rectangle()
        power_bar_rect.left = health_bar_rect.left
        power_bar_rect.top = health_bar_rect.bottom
        power_bar_rect.right = health_bar_rect.right
        power_bar_rect.bottom = power_bar_rect.top + 10
        power_bar = gui.StatusBar("UI/StatusBars/Power", power_bar_rect,
                                  self.player.max_power)
        power_bar.name = "Power"

        # Add the gui elements to the element list.
        self.gui_elements.append(health_bar)
        self.gui_elements.append(power_bar)

        # Add listeners to player's health and power changed events.
        self.player.health_changed += health_bar.on_value_changed
        self.player.power_changed += power_bar.on_value_changed

        # Create an FPS label.
        fpslabel = gui.FPSLabel("UI/FPSLabel")
        self.gui_elements.append(fpslabel)

        # Set up the ability bar.
        self.setupGUIAbilityBar()

    def setupGUIAbilityBar(self):
        player = self.player

        # Set up ability cooldown displays
        ability_keys = player.element.ability_keys
        ability_cooldowns = player.element.ability_cooldowns
        ability1_cooldown = ability_cooldowns[ability_keys[1]]
        ability2_cooldown = ability_cooldowns[ability_keys[2]]
        ability3_cooldown = ability_cooldowns[ability_keys[3]]
        ability4_cooldown = ability_cooldowns[ability_keys[4]]

        # Set up ability icons.
        if player.element.type == "fire":
            # Fire
            ability1_icon_mat = "FireIconAbility1"
            ability2_icon_mat = "FireIconAbility2"
            ability3_icon_mat = "FireIconAbility3"
            ability4_icon_mat = "FireIconAbility4"
        elif player.element.type == "earth":
            # Earth
            ability1_icon_mat = "EarthIconAbility1"
            ability2_icon_mat = "EarthIconAbility2"
            ability3_icon_mat = "EarthIconAbility3"
            ability4_icon_mat = "EarthIconAbility4"
        elif player.element.type == "air":
            # Air
            ability1_icon_mat = "AirIconAbility1"
            ability2_icon_mat = "AirIconAbility2"
            ability3_icon_mat = "AirIconAbility3"
            ability4_icon_mat = "AirIconAbility4"
        elif player.element.type == "water":
            # Water
            ability1_icon_mat = "WaterIconAbility1"
            ability2_icon_mat = "WaterIconAbility2"
            ability3_icon_mat = "WaterIconAbility3"
            ability4_icon_mat = "WaterIconAbility4"

        # Create UI Elements
        ability1_cdd_rect = ogre.Rectangle()
        ability1_cdd_rect.left = self.viewport.actualWidth / 2 - 128
        ability1_cdd_rect.top = self.viewport.actualHeight - 64
        ability1_cdd_rect.right = ability1_cdd_rect.left + 64
        ability1_cdd_rect.bottom = ability1_cdd_rect.top + 64
        ability1_cooldown_display = gui.AbilityCooldownDisplay(
            "UI/AbilityBar/Ability1", ability1_cdd_rect, 1, ability1_cooldown)
        ability1_cooldown_display.overlay.setMaterialName(ability1_icon_mat)

        ability2_cdd_rect = ogre.Rectangle()
        ability2_cdd_rect.left = ability1_cdd_rect.right
        ability2_cdd_rect.top = ability1_cdd_rect.top
        ability2_cdd_rect.right = ability2_cdd_rect.left + 64
        ability2_cdd_rect.bottom = ability2_cdd_rect.top + 64
        ability2_cooldown_display = gui.AbilityCooldownDisplay(
            "UI/AbilityBar/Ability2", ability2_cdd_rect, 2, ability2_cooldown)
        ability2_cooldown_display.overlay.setMaterialName(ability2_icon_mat)

        ability3_cdd_rect = ogre.Rectangle()
        ability3_cdd_rect.left = ability2_cdd_rect.right
        ability3_cdd_rect.top = ability2_cdd_rect.top
        ability3_cdd_rect.right = ability3_cdd_rect.left + 64
        ability3_cdd_rect.bottom = ability3_cdd_rect.top + 64
        ability3_cooldown_display = gui.AbilityCooldownDisplay(
            "UI/AbilityBar/Ability3", ability3_cdd_rect, 3, ability3_cooldown)
        ability3_cooldown_display.overlay.setMaterialName(ability3_icon_mat)

        ability4_cdd_rect = ogre.Rectangle()
        ability4_cdd_rect.left = ability3_cdd_rect.right
        ability4_cdd_rect.top = ability3_cdd_rect.top
        ability4_cdd_rect.right = ability4_cdd_rect.left + 64
        ability4_cdd_rect.bottom = ability4_cdd_rect.top + 64
        ability4_cooldown_display = gui.AbilityCooldownDisplay(
            "UI/AbilityBar/Ability4", ability4_cdd_rect, 4, ability4_cooldown)
        ability4_cooldown_display.overlay.setMaterialName(ability4_icon_mat)

        # Add the gui elements to the element list.
        self.gui_elements.append(ability1_cooldown_display)
        self.gui_elements.append(ability2_cooldown_display)
        self.gui_elements.append(ability3_cooldown_display)
        self.gui_elements.append(ability4_cooldown_display)

        # Listen to player events (why isn't this the same as how
        # StatusBar listens to its events?):
        ability1_cooldown_display.set_player_listener(self.player)
        ability2_cooldown_display.set_player_listener(self.player)
        ability3_cooldown_display.set_player_listener(self.player)
        ability4_cooldown_display.set_player_listener(self.player)

    def setupOverlay(self):
        pOver = ogre.OverlayManager.getSingleton().getByName("UI")
        pOver.show()

    def setup_level_boundaries(self, filepath):
        """
        Takes an xml-style file that specifies all of the level's static boundinglinesegments, and creates those
        bounds in the world.
        """
        xml_data = minidom.parse(filepath)
        docRoot = xml_data.getElementsByTagName('segments')[0].childNodes
        for segmentNode in docRoot:
            if segmentNode.nodeType == Node.ELEMENT_NODE and segmentNode.nodeName == 'segment':
                point1_data = self.getXMLNode(segmentNode, "point1").attributes
                point2_data = self.getXMLNode(segmentNode, "point2").attributes
                normal_data = self.getXMLNode(segmentNode, "normal").attributes

                point1 = (float(point1_data["x"].nodeValue),
                          -float(point1_data["z"].nodeValue))
                point2 = (float(point2_data["x"].nodeValue),
                          -float(point2_data["z"].nodeValue))
                normal = (float(normal_data["x"].nodeValue),
                          float(normal_data["z"].nodeValue))

                boundary_wall = gamestate.objects.GameObject(self.world)
                boundary_wall.isPassable = False
                boundary_wall.position = point1

                boundary_wall.bounding_shape = gamestate.collision.BoundingLineSegment(
                    point1, point2, normal)

                self.world.add_object(boundary_wall)

    def getXMLNode(self, base, name):
        """
        This function basically doubles as both a test for element 
        existence and a getter for that element node... used with setup_level_boundaries()
        """
        if base.hasChildNodes:
            baseChildNodes = base.childNodes

            for node in baseChildNodes:
                if node.nodeType == Node.ELEMENT_NODE and node.nodeName == name:
                    return node

            return False

    def frameStarted(self, event):
        """ 
        Called before a frame is displayed, handles events
        (also those via callback functions, as you need to call capture()
        on the input objects)

        Returning False here exits the application (render loop stops)
        """

        dt = event.timeSinceLastFrame

        # Capture any buffered events (and fire any callbacks).
        self.inputHandler.capture()

        # Update our UI Elements
        for element in self.gui_elements:
            element.update(dt)

        # Update the game state world.
        self.world.update(dt)

        # Add time to animations.
        for node in self.nodes:
            node.animations_addtime(dt)

        # Neatly close our FrameListener if our renderWindow has been shut down
        # or we are quitting.
        if self.renderWindow.isClosed() or self.quit:
            return False

        return True

    ## Game event callbacks
    def on_world_object_added(self, gameObject):
        if gameObject.type == "player":
            newPlayerNode = nodes.PlayerNode(self.sceneManager, gameObject,
                                             "ninja.mesh")
            newPlayerNode.set_scale(.1)
            self.nodes.append(newPlayerNode)

    def on_player_position_changed(self, mobileObject, position):
        self.cameraNode.position = (position[0], 100, position[1] + 100)

    def on_player_element_changed(self, player):
        # Remove all current gui.AbilityCooldownDisplay from the current gui.
        self.gui_elements = [
            element for element in self.gui_elements
            if type(element) is not gui.AbilityCooldownDisplay
        ]
        # Recreate the ability bar GUI.
        self.setupGUIAbilityBar()

    def on_static_node_expired(self, static_node):
        print static_node.unique_scene_node_name
        self.sceneManager.destroySceneNode(static_node.unique_scene_node_name)

    ## Window event listener callbacks
    def windowResized(self, renderWindow):
        self.mouse.getMouseState().width = renderWindow.width
        self.mouse.getMouseState().height = renderWindow.height
        vp = self.viewport
        self.camera.aspectRatio = vp.actualWidth / vp.actualHeight
        # @todo: Scale the image so viewable area remains the same.

    def windowClosed(self, renderWindow):
        # Only close for window that created OIS
        if (renderWindow == self.renderWindow):
            del self