.x file not having collisions

Hello! i was recently working on an FPS game that works off of an fps base made by someone else (cant remember who made it) and that i have modded heavily. i have been trying to make my own environment to move around/play in, but no matter what i do, it dosent have any collisions. as far as the world goes, the only thing that i have changed is the name of the world model.

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.gui.OnscreenText import OnscreenText
import sys
from pandac.PandaModules import WindowProperties

class FPS(object):
        This is a very simple FPS like -
         a building block of any game i guess
    def __init__(self):
        """ create a FPS type game """
        base.accept( "escape" , sys.exit)
        OnscreenText(text="Simple FPS Movement", style=1, fg=(1,1,1,1),
                    pos=(1.3,-0.95), align=TextNode.ARight, scale = .07)
        OnscreenText(text=__doc__, style=1, fg=(1,1,1,1),
            pos=(-1.3, 0.95), align=TextNode.ALeft, scale = .05)
        props = WindowProperties()
    def initCollision(self):
        """ create the collision system """
        base.cTrav = CollisionTraverser()
        base.pusher = CollisionHandlerPusher()
    def loadLevel(self):
        """ load the self.level 
            must have
            <Group> *something* { 
              <Collide> { Polyset keep descend } 
            in the egg file
        self.level = loader.loadModel('FPS_map_v1.x')
    def initPlayer(self):
        """ loads the player and creates all the controls for him"""
        self.node = Player()
class Player(object):
        Player is the main actor in the fps game
    speed = 25
    FORWARD = Vec3(0,2,0)
    BACK = Vec3(0,-1,0)
    LEFT = Vec3(-1,0,0)
    RIGHT = Vec3(1,0,0)
    STOP = Vec3(0)
    run = Vec3 (0,2,0)
    walk = STOP
    strafe = STOP
    run = STOP
    readyToJump = False
    jump = 0
    def __init__(self):
        """ inits the player """
        # init mouse update task
        taskMgr.add(self.mouseUpdate, 'mouse-task')
        taskMgr.add(self.moveUpdate, 'move-task')
        taskMgr.add(self.jumpUpdate, 'jump-task')
    def loadModel(self):
        """ make the nodepath for player """
        self.node = NodePath('player')
    def setUpCamera(self):
        """ puts camera at the players node """
        pl =  base.cam.node().getLens()
    def createCollisions(self):
        """ create a collision solid and ray for the player """
        cn = CollisionNode('player')
        solid = self.node.attachNewNode(cn)
        base.pusher.addCollider(solid,self.node, base.drive.node())
        # init players floor collisions
        ray = CollisionRay()
        cn = CollisionNode('playerRay')
        solid = self.node.attachNewNode(cn)
        self.nodeGroundHandler = CollisionHandlerQueue()
        base.cTrav.addCollider(solid, self.nodeGroundHandler)
    def attachControls(self):
        """ attach key events """
        base.accept( "space" , self.__setattr__,["readyToJump",True])
        base.accept( "space-up" , self.__setattr__,["readyToJump",False])
        base.accept( "s" , self.__setattr__,["walk",self.STOP] )
        base.accept( "w" , self.__setattr__,["walk",self.FORWARD])
        base.accept( "s" , self.__setattr__,["walk",self.BACK] )
        base.accept( "s-up" , self.__setattr__,["walk",self.STOP] )
        base.accept( "w-up" , self.__setattr__,["walk",self.STOP] )
        base.accept( "a" , self.__setattr__,["strafe",self.LEFT])
        base.accept( "d" , self.__setattr__,["strafe",self.RIGHT] )
        base.accept( "a-up" , self.__setattr__,["strafe",self.STOP] )
        base.accept( "d-up" , self.__setattr__,["strafe",self.STOP] )
        base.accept( "w-up" , self.__setattr__,["walk",self.STOP])
        base.accept( "shift" , self.__setattr__,["run",self.FORWARD])
        base.accept( "shift-up" , self.__setattr__,["run",self.STOP] )
        base.accept( "s" , self.__setattr__,["run",self.STOP] )

    def mouseUpdate(self,task):
        """ this task updates the mouse """
        md = base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        if base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2):
            self.node.setH(self.node.getH() -  (x - base.win.getXSize()/2)*0.1)
            base.camera.setP(base.camera.getP() - (y - base.win.getYSize()/2)*0.1)
        return task.cont
    def moveUpdate(self,task): 
        """ this task makes the player move """
        # move where the keys set it
        return task.cont
    def jumpUpdate(self,task):
        """ this task simulates gravity and makes the player jump """
        # get the highest Z from the down casting ray
        highestZ = -100
        for i in range(self.nodeGroundHandler.getNumEntries()):
            entry = self.nodeGroundHandler.getEntry(i)
            z = entry.getSurfacePoint(render).getZ()
            if z > highestZ and entry.getIntoNode().getName() == "Cube":
                highestZ = z
        # gravity effects and jumps
        self.jump -= 2*globalClock.getDt()
        if highestZ > self.node.getZ()-0.3:
            self.jump = 0
            if self.readyToJump:
                self.jump = 1
        return task.cont

help is extremely appreciated.

Your loadLevel() method includes the comment:

This seems like an accurate comment. However, it is not possible to have this syntax in an .x file.

You could use x2egg to convert your .x file to an .egg file, and then hand-edit the .egg file to add the appropriate lines to the appropriate place. But you’ll have to understand what the appropriate place is.


thanks david, i still have an issue though- i havent the foggiest as to where to add those lines and it corrupts my file 100% of the time when i attempt it.

Try reading through the manual section about collisions; it might give you some insight. You can also try looking at simpler programs to get some idea of how the collision system is intended to work.


i combed the collisions section of the manual, and i learned a bit i didnt already know- however, i couldent find anything on making it so that a model automatically supports collisions. Another question- what is a good method of making a large playing area (map) that has many MANY faces, like a very large city?

Generally you will have a separate, much simpler mesh, which is used only for collisions.
This is as much for performance reasons as gameplay reasons, for example you will not have collision for every little plant or piece of litter or pipe on a wall that could make make your character get stuck.
If the world is very large it might help to break it up into pieces that can be enabled and disabled depending if the player is near or not.

i havent made a large area before, i have just been experimenting in the mesh that came with the FPS base, as i could not figure out where to add the collision code to the .egg . exactly how expensive are collision meshes? i want to be able to have a rather large city for a multiplayer game- im just worried that the engines limits would collapse.

Well to give you an idea, in my own game I have a server and a client program. I choose to do all the collision on the server since I want the client to run as fast as possible. On the server, collision and collision tests take up more time than all other tasks combined. This is because I use the collision mesh to do not only physics simulation but also vision checks, projectiles, etc.
If I keep increasing the size of the level, eventually the server will not be able to keep up a high enough frame rate. You could force all players to be within a certain range, allowing you to disable the rest of the level.
Another way is to have each client do at least some of the collision tests and/or physics and then try to merge that data from the various clients. Many RTS and open world games for example do something like this. If one person is far off in one corner of the map, the physics for that area is being calculated on their own machine. This makes the game scale very well since as the number of clients increases the work done by the server is not much more. The main downside of this is it is easier for the client to cheat and send false data.

thanks for your help, and ill be sure to implement that once i make the change from singleplayer to client/server. however, i still am really curious about were i need to put that collision code in the level .egg file.

ill just make a new topic as i now fully understand how different my problem is than it originally was.