1
$\begingroup$

Pretend we have a simple class; "Hero" will be our class. Here's an example of a simple class:

class Hero:

    def __init__(self, max_health):
        self.health = max_health

    def regen(self, amount):
        if (max_health - amount) > 100:
            self.health = max_health
        else:
            self.health += amount

    def die(self):
        self.health = 0
        self.alive = False

Above is a simple class not assigned to any objects. I am a bit puzzled on how I would "assign" a class to an object. When the script reads self.health = max_health, would I change it to self["health"] = max_health? Also, how would I apply the entire class to a specific object? I can do player = Hero(100), which would make "player" be class "Hero" with 100 as the max_health, but I am not assigning this specific "player" to a BGE object. Would I call the object and assign it: main.objects["player"] = Hero (assuming I've defined "main" and "player" exists)? How can I have class attributed be connected to properties of objects, and how can I have the objects be assigned to a class?

$\endgroup$
1
$\begingroup$

Composition

You can assign an object (instance of a class) by referring from the game object to your instance e.g. by assigning it as value to a property.

import bge
from myClassDefinitions import MyClass


myInstance = MyClass()

owner = bge.logic.getCurrentController().owner
gameObject = owner
gameObject["myClass"] = myInstance # assign object to game object

print(gameObject["myClass"]) # get object via game object

Explanation

The game object and the instance of your class (object) are two separate objects.

After creation you assign your object (as reference) to a property of the game object. This means the game object knows how to get the object at any time later via gameObject["myClass"].

The object does not need to know the game object. If you really need you can create a cross reference (e.g. by storing a reference of the game object as attribute of the object).

Advantages

  • any number of objects can be assigned to the same game object
  • any number of game objects can refer to the same object
  • the property name indicates the purpose of the referred object
  • the property can be exchanged or even removed
  • allows to avoid dependencies to BGE from within your own classes (you can test it with unittest, you can use it outside the BGE)
  • can survive game object remove (e.g. on scene switch) when referred from outside the scene.

(this is another option)

Object replacement

The BGE allows to "replace an existing game object". It is a strange idea but allows to feel like subclassing. It is descibed in the BGE API.

Explanation

You create an instance of your class which subclasses KX_GameObject (or whatever you told your class should inherit from).

The game object in the scene will be replaced by the BGE when instantiating your class (that is why you need to deliver a game object to be replaced).

Your object inherits all attributes from the game object you delivered at instantiation.

When the game object dies your object dies too as it is the game object now.

Advantage

  • single class
  • can still use properties
  • feels like a class

Disadvantage

  • single class only
  • replaces the game object (any previously made references to this object become invalid)
  • dependency to a single game object type branch (you can't use the same inheritance for KX_Camera and KX_FontObject)
  • will not survive ending the game object (e.g. on scene switch).
$\endgroup$
  • $\begingroup$ Thanks for the answer. In the disadvantages, "single class only," does this mean that it will no longer be of bge.types.KX_GameObject? Or can it be both (hero and gameobj)? I see "single class" in both the advantages and disadvantages. Also, you say "myInstance = MyClass()," "owner = bge.logic.getCurrentController().owner," and "gameObject = owner" "gameObject["myClass"] = myInstance." This is transition -- can we not say "gameObject = MyClass()"? I see you've written "gameObject["myClass"] = myInstance," but is ["myClass"] an attribute of gameObject? = $\endgroup$ – blackhole Feb 17 '16 at 21:42
  • $\begingroup$ It will still be a KX_GameObject as it inherits from it. I do not think you can apply another class (with additional behavior) ... I might be wrong as Python supports multi-inheritence. --- it is both an advantage (just one class) and an disadvantage (if you want to encapsulate into several classes). $\endgroup$ – Monster Feb 18 '16 at 6:35
  • $\begingroup$ I updated the answer to create better contrast on the two options. $\endgroup$ – Monster Feb 18 '16 at 6:48
0
$\begingroup$

you can pass the game object to your custom class object as follows:

class hero(object):
    def __init__(self, game_object):
        self.gameObject = game_object
        self.health = self.gameObject.get("health")

now you can create objects from your cusom class 'hero' in the game code

# getting all the current scene objects
scene = bge.logic.getCurrentScene()
source = scene.objects

#'superman_object_name' is your object name in blender current scene
superman = hero(source.get('superman_object_name')) 

#now you can access your game property within the object 
print (superman.health)
$\endgroup$
  • $\begingroup$ If my object had a property (logic bricks) named "health," would this work? Would I need self["health"], or is self.health fine? Thanks. $\endgroup$ – blackhole Feb 17 '16 at 21:37
  • $\begingroup$ you know what, I've just discovered that inheritance is not necessary :) check out my corrected answer, I hope this is not confusing $\endgroup$ – Ahmed Ali Feb 18 '16 at 5:47
  • $\begingroup$ A property remains a property with key access. self["property"] is the access method (since BGE2.49). $\endgroup$ – Monster Feb 19 '16 at 6:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.