More OO

Hi,

Is it posible to create a structure like this:

one class called world

one class called player

one class called enemy

then for example do the folowing:

world1 = world()
player1 = player()
world1.add(player, player1) “”“this is a method in world class to add the player to that world”""
enemy1 = enemy()
world1.add(enemy, enemy1)

now both player and enemy will use their methods for collision, ai, sound, animation, health etc…

How should I create these structure? From what do i dirrive from? All from directobject or just the world?

Will I be able to make world, player and enemy classes in difrent files and include them? (probably)

tanks in advance.

Ask two coders about good OO style and you get three answers. At least. Here is one way to do this:

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject

class World:

    def __init__( self, path ):
        self.np = loader.loadModelCopy( path )
        self.np.reparentTo( render )

    def add( self, object ):
        object.np.reparentTo( self.np )

class Player( DirectObject ):

    def __init__( self, path ):
        self.np = loader.loadModelCopy( path )
        self.accept( 'escape', self.exit )

    def exit( self ):
        taskMgr.stop( )

class Enemy:

    def __init__( self, path ):
        self.np = loader.loadModelCopy( path )

world1 = World( '<path to worldFile>' )
player1 = Player( '<path to playerFile>' )
world1.add( player1 )
enemy1 = Enemy( '<path to enemyFile>' )
world1.add( enemy1 )

run( )

I don’t like this very much, since World.add( ) uses implicit knowledge about the objects that is added ( object.np is the NodePath instance ). The python manual says “explicit is better than implicit”, and so perhaps this one is better:

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject

class World:

    def __init__( self, path ):
        self.np = loader.loadModelCopy( path )
        self.np.reparentTo( render )

    def addObject( self, klass, path ):
        object = klass( path )
        object.addTo( self.np )

class Object:

    def __init__( self, path ):
        self.np = loader.loadModelCopy( path )

    def addTo( self, np ):
        self.np.reparentTo( np )

class Player( Object, DirectObject ):

    def __init__( self, path ):
        Object.__init__( self, path )
        self.accept( 'escape', self.exit )

    def exit( self ):
        taskMgr.stop( )

class Enemy( Object ):

    def __init__( self, path ):
        Object.__init__( self, path )

world1 = World( '<path to worldFile>' )
world1.addObject( Player, '<path to playerFile>' )
world1.addObject( Enemy, '<path to enemyFile>' )

run( )

I think it may be possible to derive from the classes provided by Panda (World from NodePath, Player and Enemy from Actor and so on), but since you probably want to have a collision node, exposed joints and several invisible triggers floating around with the player/enemies I think it is a good idea to have a container classes that holds everything together.

In the above examples only Player is derived from DirectObject. DirectObject provides event handling methods like “accept”, “ignore” and so on. Again there are thousands of ways to do it, and perhaps you want to derive Player from FSM (Finite State Machine), and give player a controler attribute the handles input and can be exchanged with other controler instances specialised for walking, swimming, … . In this case Controler would have to be derived from DirectObject.

Hope this help
enn0x