How to attach new member to instance of sprite in python?

This forum is currently in read-only mode.
From the Asset Store
Create your game with this complete pack of images and animations!
  • Here is the test cap file:

    http://dl.dropbox.com/u/5779181/objspv_access.zip

    There are many instances of objA. I try to attach a new member named "_value" on each instance.

    for _obj in objA:
        _obj._value = 10
    _obj = objA[0]
    output.SetText("%d"%(_obj._value))[/code:vvgcwmd3]
    And get the error message:
    [quote:vvgcwmd3]TypeError: %d format: a number is required, not NoneType
    
    from the last one "output.SetText("%d"%(_obj._value))".
    It seems I can not attach new member to each instance.
    
    Another way, 
    [code:vvgcwmd3]objA._value = 10
    output.SetText("%d"%(objA._value))[/code:vvgcwmd3]
    It works. I can attach new member to objA (not objA[0]).
    
    What's different between "objA._value" and "objA[0]._value" in this case?
  • [quote:2py1z69r]What's different between "objA._value" and "objA[0]._value" in this case?

    objA is the class to access objA instances and exists for the duration of the application. objA[0] creates a temporary class to access that instance.

    Here is a fix:

    Add this code to 'Start of Layout' before you run any other code to be able to attach new members to instances.

    class _instance_values:
    	pass
    
    _Instances._vals_=dict()
    for _ot in _Instances.__dict__.items():
    	if _ot[0][0]=='_':
    		continue
    	_ot[1]._oldgetattr=_ot[1].__getattr__
    	def mygetattr(this, attr):
    		objkey=this.__dict__['__instance__']
    		if _Instances._vals_.has_key(objkey):
    			if hasattr(_Instances._vals_[objkey],attr):
    				return getattr(_Instances._vals_[objkey],attr)
    		return this._oldgetattr(attr)
    	_ot[1].__getattr__=mygetattr
    	
    	_ot[1]._oldsetattr=_ot[1].__setattr__
    	def mysetattr(this, attr, value):
    		objkey=this.__dict__['__instance__']
    		if not _Instances._vals_.has_key(objkey):
    			_Instances._vals_[objkey]=_instance_values()
    		if not hasattr(this.__class__, attr) and attr not in this.__class__._otherAttrib:
    				return setattr(_Instances._vals_[objkey], attr, value)
    		return this._oldsetattr(attr,value)
    	_ot[1].__setattr__=mysetattr[/code:2py1z69r]
  • Hi, Master of Python,

    This code works in my case. Thanks.

    New member is stored into global (hash)table _Instances._vals_

    If an instance has been destroyed, the member of this dead instance in _Instances._vals_ will not be released automatic.

    Btw, the variable type in construct only support "Number" and "String", so that I can not store instance directly.

    I save the UID of instance and find it from adding an "compared" event, if I only use built-in event sheet (w/o python support).

    Question:

    Is there a faster way to keep the selected instances (w/o python support)?

    With python, I save the {UID:instance} in a (hash)table, and clean the {UID:instance} pair if the instance has been destroyed.

    Humm... Maybe I can cover the 'Destroy' method in objAInstance in _Instances to hang my clean method.

    Question:

    1. What is _Instances?

    2. Will objA[0].Destroy() call objAInstance.Destroy()? Is objAInstance the class of objA[0]?

    Thank you for your help

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I test the "objA[0].Destroy() call objAInstance.Destroy()" is success. Now I can override Destroy method for doing some clean-up processes.

  • [quote:14olccbt]1. What is _Instances?

    It's basically just to hide\organize instance classes from the main global dict. It should never need to be accessed directly. Basically every object type causes 2 classes to be generated ex. Sprite and SpriteInstance. SpriteInstance is a class that points to a particular instance of sprite.

    [quote:14olccbt]2. Will objA[0].Destroy() call objAInstance.Destroy()? Is objAInstance the class of objA[0]?

    es for the first. For the second objA[0] is a objAInstance.

    The only issue is if you destroy the object with events, the python destroy() is not called and the custom methods will not be cleaned up.

  • Thanks, it's very clear.

    Sorry for another question, I try to override System.Create() for the same reason, to add some custom initialize. How to get the class of "System"?

  • System is a bit different since there is only one instance of System.

    get the system class with this:

    System.__class__[/code:29imus8b]
  • It works. Thank you again.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)