initialising added KX_GameObjects

Hi,

i have some Probelms with initialising added Objects.
So far i used a GameObj class, wich initialises itself when the object is added and runs its code for the first time:


class GameObj(bge.types.KX_GameObject):
    def __init__(self, this):
        bge.types.KX_GameObject.__init__(self)
        self.arguments = "whatever"
        self['this'] = self

# initial

if not 'this' in own:
            obj = GameObj(own)


This works, but the Problem is, if i add the object with the following code:


added = sce.addObject(obj,self,0)

the Object is a KX_GameObject, and has not been converted to a GameObj instance.

I tried to overgive the class like:


if not 'this' in added:
    obj = GameObj(added)


wich actually should be the same as the added Object itself excutes this code, but i get an Error.


def main(cont):
    own =cont.owner
    if cont.sensors["Always"].positive:
        if not 'this' in own:
            obj = GameObj(own)

Hopefully someone can understand my problem and has some hints to solve it…

The goal is to add an Object, overgive it a class and initialise it, and then access direct to its content, without running a code from the Object itself.

I’m slightly confused as to why you’re using this method.
Why not add an object, then set a property as a class
e.g object[‘class’] = MyClass()

Then use that property as a handle.

e.g object[‘class’].name = ‘jim’
Though i’ve never tried this, it ought to work.
Why are you doing this anyway?

well, i’m confused aswell :eyebrowlift2:, i dont know any other ways to do it, and i know this is old fashioned maybe…
I want to overgive the objects functions and variables, to store data in the Objects.
Of course i could use Properties, but this is exactly what i want to avoid.

Might be, i misunderstand the whole thing, i tried your version with same results.

Aslong you don’t overgive a KX_GameObject class, it works.
I want to have the class KX_GameObject and my custom classes to be merged in one, for access to all sensors etc plus the custom Poperties and functions.

Why all this? I try to create a simple GUI for my Game Project, i tought i create several classes with a hirarchy., for example:

the base class is a frame wich gets positions and scaling information about itself and its childrens.
then the next class will be a Button class, wich includes the Frame class,
next could be a Window class, wich contains several classes…

Essentially, you’re trying to emulate the GameObject class, which seems unnecessary.
At the end of the day, i don’t believe that you can access anything of a GameObject without actually storing it in at least one property, unless you edit the attributes in the base code. However, i understand a dislike of properties, i prefer classes etc.

Youre right, it is still stored in self[‘this’]. But the difference is, that in self[‘this’] is a Merge of all overgiven Classes, incluiding the KX_GameObject class. So if i would have a class stored in a property, i must acces through this property, like this i can acces through the game Object itself, means
all variables and functions are listed in dir(cont.owner), otherwise it would be listed in dir(cont.owner[‘this’]) in my example? Right?
I hope i understood what you were telling me…

I don’t believe so - you cannot write to a GameObject class, and so you would be unable to write to it as you’ve done. I may be wrong, but i cannot seem to see how this would work. However, continue to ask until someone else may present a better answer!

Correct, you cannot write to a KX_GameObject class, but yo can overgive this class to another class, wich is writeable…
The dir() function shows me:

[‘MouseEvents’, ‘class’, ‘contains’, ‘delattr’, ‘delitem’, ‘di
ct
’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getit
em
’, ‘gt’, ‘hash’, ‘init’, ‘le’, ‘lt’, ‘module’, ‘__ne
_’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘set
item
’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘actuators’
, ‘addWidget’, ‘addableObjects’, ‘alignAxisToVect’, ‘angularVelocity’, ‘applyFor
ce’, ‘applyImpulse’, ‘applyMovement’, ‘applyRotation’, ‘applyTorque’, ‘attrDict’
, ‘cam’, ‘children’, ‘childrenRecursive’, ‘cleanScene’, ‘color’, 'color
’, ‘colo
r_c’, ‘color_h’, ‘color_s’, ‘colors’, ‘controllers’, ‘createGui’, ‘default’, ‘di
sableRigidBody’, ‘enableRigidBody’, ‘endObject’, ‘get’, ‘getAngularVelocity’, ‘g
etAxisVect’, ‘getDistanceTo’, ‘getLinearVelocity’, ‘getPhysicsId’, ‘getPropertyN
ames’, ‘getReactionForce’, ‘getTheme’, ‘getVectTo’, ‘getVelocity’, ‘height’, 'ho
‘, ‘hover’, ‘hover_obj’, ‘hp’, ‘invalid’, ‘lb’, ‘life’, ‘linVelocityMax’, ‘linVe
locityMin’, ‘linearVelocity’, ‘localAngularVelocity’, ‘localInertia’, ‘localLine
arVelocity’, ‘localOrientation’, ‘localPosition’, ‘localScale’, ‘main’, ‘mass’,
‘mb’, ‘meshes’, ‘name’, ‘occlusion’, ‘orientation’, ‘parent’, ‘position’, ‘rayCa
st’, ‘rayCastTo’, ‘rb’, ‘rebuildScene’, ‘reinstancePhysicsMesh’, ‘relative_x’, ’
relative_y’, ‘removeParent’, ‘replaceMesh’, ‘restoreDynamics’, ‘scaling’, ‘scree
n_x’, ‘screen_y’, ‘sendMessage’, ‘sensors’, ‘setAngularVelocity’, ‘setCollisionM
argin’, ‘setLinearVelocity’, ‘setOcclusion’, ‘setParent’, ‘setVisible’, ‘state’,
‘suspendDynamics’, ‘theme’, ‘timeOffset’, ‘visible’, ‘wd’, ‘widgets’, ‘width’,
‘worldAngularVelocity’, ‘worldLinearVelocity’, ‘worldOrientation’, ‘worldPositio
n’, ‘worldScale’, ‘wu’, ‘x’, ‘y’, ‘z’]

as you can see, it differs from the KX_GameObject class, it simply includes this(and other) class/es.
sefl is own, own is self…

I don’t quite understand why you’re taking this approach, either - why not just have a script that initializes the added object like so with an Always sensor with no pulse settings:


if not 'init' in obj:
     obj['init'] = 1
     if not 'movespd' in obj:
          obj['movespd'] = 0.1

And if you want to pass properties from the creator object to the new one, the initialization script will allow for that:


a = sce.addObject('AddedObject', obj)
a['movespd'] = 0.2 # Differs from its default value of 0.1

anyway, thanks for reply and interest.
I have the feeling, either i misunderstand something, or i get misunderstanded.
Lets take a look on SolarLunes idea.
This comes pretty close, what i want to do.
Even the initial script is dooing his job well, i want to avoid having a creator script plus an initial script. The creator should look like:

frame = addFrame(.....)
frame.rescale()

the frame has no rescale function yet, it has first to initialise itself, this takes some time.
if i want to rescale it, the creator script should wait until the added Object is initialised.
So my idea was to intitialise it:

frame = addFrame(...)
frame.__init__()

of course this doesnt work, because the frame has no init() function yet.

Another idea would be, to let the script wait until the added Object is initialised and then access to it. But how to do this?

Maybe i need an example of your ideas, how you would do it.
Probably im a bit hard understanding…might be i’m thinking in a wrong direction.
But this problem made me think so many times, and always i come to the first solution with an initial script, the only way it works for me…
Maybe someone can suggest me a link to a thread or wiki where to read about it.
By the way, is there any OOP Thread here?

Or in other words, can someone post a code, wich overgives the KX_GameObject to a class, right after adding it.

What Solarlune touched upon, is just a form of a run once script;

Creator code:

import bge
cont = bge.logic.getCurrentController()
own= cont.owner
scene = bge.logic.getCurrentScene()

ob = scene.addObject("ObjectToBeAdded",own,0)


Object code:


import bge
cont = bge.logic.getCurrentController()
own= cont.owner
#this runs once now, because it checks if a property doesn't exist, but the property is added that tick, so it then exists next tick
if not "init" in own:
     #do stuff to object
     own['prop'] = 1
     own['init'] = True
     #now that won't run again
#stuff run every frame
var = 2

Oh, okay, I see. You could also do OOP code inside of the creator script - you don’t need to override the object:



class TheCreated():
    def __init__(self):
        self.initialized = 1

cont = logic.getCurrentController()
obj = cont.owner
sce = logic.getCurrentScene()

c = sce.addObject('CreatedObject', obj)
c['object'] = TheCreated()
print (c['object'].initialized) # The initialized value should be in existence

That should work - you can stick the object into a variable in the created object at creation.

Yes that’s what i meant!

ahh!! i see… i will make some test with this…
Thanks a lot!

Other Question:

is there a change from 2.58 to 2.59 with the Text Obejcts?
I cant colorise them.

text = sce.addObject(“Text”,sefl,0)
text.color = [1.0,1.0,1.0,1.0]
… should not this be white???

the only visible change is the alpha value …
Must it be from 0 to 255?? that didnt work too…

edit:
it works in GLSL… ok…

It does work. I’m using GLSL and Shadeless material.

after some successful tests with solarlunes code, i cant see any disadvantage of this method…
… well i’ll need to rewrite a lot, but will have a better and painless method for classes and KX_GameObjects…
have a look here, testcode and blend.

edit: CaPGeti has posted another way to do it, in my opinion the ultimate method:

http://www.blendpolis.de/viewtopic.php?f=15&t=35544&p=402385#p402385

Great!