Horror Room - (First Panda 3d Program)

I am new to Panda3d, but not to game development I have been involved in this area for 5 years. I have used many different engines and made a fair share of my own games… I came upon Panda3d and thought I’d give it a try. So this is a Small WIP Demo, to help me learn more about the engine.

What I have so far…

  1. A fully working Menu
  2. Fully animated monsters, A method capable of adding as many as I want
  3. A WASD and FPS camera look
  4. The Room

The screenshot is of level 1, the room is well lit and the monster is easy to kill. This is basically a learning level. Level 2+++ The room is very dark you may only see with your flashlight (Already Implemented), and the number of monsters increases accordingly… What do you think of the Game?

What I need help with…
Bullets/Collisions: With the previous engines that I have used, the method I used was to shoot a ray, check the hit object then spawn the appropriate bullet hole/Blood spot at the correct position and normal…
I would like to do it this way with Panda as well, however I am having difficulty… I can set the ray’s origin point just fine by checking it against the gun’s. SO (Finally) I can get the guns HPR, but the ray wants a vector for the direction??

Thanks a lot!

You can call rayNode.getRelativeVector(gunNode, Vec3(0, 1, 0)) to return the (0, 1, 0) vector–the forward vector–of the gun, expressed in the ray’s coordinate space.

But it’s probably easier to create a fixed ray at point (0, 0, 0) with direction (0, 1, 0), and simply parent that ray to the gun. That way, the ray inherits the position and orientation of the gun, so that a forward-pointing ray really points whichever way the gun is pointing.

Panda’s sophisticated scene graph system allows for many simple shortcuts like this. As you grow more experienced with Panda, you will more readily see how you can use the scene graph to make your life easier. :slight_smile:


Wow, parenting is a nice brilliant solution!.. The funny thing I’ve done it that way before too. LOL… I don’t know why it never hit me before! Thanks alot!

Hey, looks pretty cool so far :smiley: Can’t wait to play it!

When can we expect the first demo?

Hopefully… over the weekend but we’ll see. Another question this time about the collision system I have these lines of code


May Look familiar, I am using the picking examples to try my hand at the ray, so with these lines of code I can see my ray proceeding out of the gun and straight through the wall with no registered collision. Am I missing something? Does something have to be done to the room node?

Again The Help, Comments, and Criticism are all very well appreciated!

if you check the sample models you will see that the model itself (the egg file also has such parameters) is defined to allow collisions. search for “polyset keep descend” in the forums or check the docs. you also you need to the collision bitmask in the file. alternatively, but not recommended because slow you can just use the visual model as collider with a setCollideMask.

Looking good so far!

More Progress, the gun now shoots with the bullets. Another question…

I need to know what “object” the ray has hit. Here is my code

if self.pq.getNumEntries() > 0:
                #if we have hit something, sort the hits so that the closest
                entry = self.pq.getEntry(0).getIntoNodePath()
                number = entry.findNetTag('MonsterTag')

This, as the manual explained, is returning a Geom Node when hitting one of the monsters and model nodes when hitting the room. How do I know which monster I have hit? My Code is as such

self.monsterActors[i].setTag('MonsterTag', str(i))

That being in a for loop of course. How do find the model that is connected to the NodePath? OR… Is there anyway I can skip all this tag business and simply have it return the model name/the model itself???

Thanks for all of your help!

You’ve almost got it. Instead of using with findNetTag(), which returns a NodePath, use getNetTag(), which returns the tag value, e.g.:

number = int(entry.getNetTag('MonsterTag'))
monster = self.monsterActors[number]

Of course, you’ll want to deal with the case of missing a monster and hitting the room, in which case getNetTag(‘MonsterTag’) will return the empty string (unless you also set a MonsterTag on your room).


Well, the Into node should be the collision solid geometry that caused the collision. You can work your way back from there, by using getParent().

It seems you’ve already used tags to flag monsters. You can match up your tags that way, by searching the scenegraph for those tags.

Or, you could do something like assign a Python tag to the collision geometry for your monsters that links back to the higher-order Python representation of your monster. (You need to use a Python tag, because normal tags only hold strings.) Such as:

# in your monster creation, create a Python tag referring to itself:
Monster.collisionNode.setPythonTag ('pObject', Monster)

# then in your collision handler:

# if we get a GeomNode, then bubble one to get the parent Collision Node
if target.node().isGeomNode():
  target = target.getParent()

# look for python object bound to this collision node and then call its collision logic
pObject = target.getPythonTag ('pObject')
if pObject is not None:
  pObject.handleCollision (entry)

Or you could keep a list of the IDs of all monsters in a Python list and search that upon collision.

There are quite a lot of ways to do this.

Thanks for the help everybody! The game is coming along quite well, kiling monsters works, level progression, the start of a health system, and a few bugs were fixed. Still planning on releasing a demo version of the game today or Tomorrow,

Screenshot: This time from level 2.