Object Manipulation with Python

This forum is currently in read-only mode.
0 favourites
From the Asset Store
This is a single chapter from the "Construct Starter Kit Collection". It is the Student Workbook for its Workshop.
  • Alright, I'm creating a lot of objects from within Python, and I was wondering if there was a more reliable way to keep track of all of them than just keeping a running track of the index of the last one. (Sprite[5]) or whatever, as I create them.

    I noticed there was an object type in the script editor, and I tried messing with it to store an actual reference to each object in a list, but no dice.

    I tried something like this:

    Bob = object()

    Bob = Create("Sprite", 1, System.MouseX, System.MouseY)

    Bob.Angle = 5

    I need to store a bunch of these in a list/array...so some actual concrete references would be nice..."create" creates one, but does not hold it as the event sheet does, so references would rock. I'm trying to write a custom data structure to hold a bunch of line objects and describe them in a relationship.

  • I don't think u need the object()

    Also, I believe the py plugin which allows you to use picking data in python might solve this problem for you,

  • Well if I try just Bob = System.Create it gives me a NoneType error when I try to set the angle. No error on the actual creation, heh...

    I'd seen the object picking fix, but I don't think that will help me in this particular case, since everything will be handled within the python.

    Is there some way to do this?

  • I was annoyed that the pyfix plugin didn't work for this, so I made you another one:

    http://dl.dropbox.com/u/1013446/pycreate.rar

    (plug and example cap included)

  • The normal return value of System.Create is None, which is python's null value.

    All of my past attempts to store a direct, persistent reference to a single instance of a multi-instance Construct object have failed. Many of the python methods for Construct objects don't work properly, if they are even there, and work at all. It definitely needs some work.

    As far as the index number goes, they are practically scrambled every time an instance is destroyed, so they can't be counted on to point to the same instance under all circumstances. Here's the output of a quick test with my PyShell.cap:

    >>> ls = []
    
    

    for i in range(5):

    ls.append(System.CreateByName('Sprite',1,i*36+16,16))

    ls

    [None, None, None, None, None]

    for i, s in enumerate(Sprite):

    print i, s.uid

    0 1

    1 3

    2 4

    3 5

    4 6

    5 7

    Sprite[2].uid

    4

    Sprite[2].Destroy()

    > for i, s in enumerate(Sprite):

    print i, s.uid

    0 1

    1 3

    2 7

    3 5

    4 6

    Sprite[2].uid

    7[/code:4py0sf3d]

    I'm afraid that this affects your above plugin's function as well, Lucid, though I really like the idea.

    Not saying that there isn't a better way that I haven't found, but the only way I know of to reliably reference an instance is to store it's uid, as you might do with events. Then, you can use something like so:

    def rotateInstance(obj, uid, deg):
       for i in obj:
          if i.uid = uid:
             i.angle += deg[/code:4py0sf3d]
    
    ... which kind of sucks. I keep hoping that I stumble across a clever way to eliminate that loop. 
    
    That said, I still find Python quite useful for many things in Construct, but you may need to interface it with normal events for some things. Construct's function object can help with that.
  • I'm afraid that this affects your above plugin's function as well, Lucid, though I really like the idea.

    if he only needs store the objects python index temporarily this should work fine, which I assumed was the case given his bob example

    however, if he needs to store many instances long term, you can already manipulate large arrays of objects using python with s

    also, btw arsonide, if you just want to create the object and assign it all the various dimension, position, information etc, I could just add that to the create function, so you don't have to worry about storing instance data at all

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • if he only needs store the objects python index temporarily this should work fine, which I assumed was the case given his bob example

    however, if he needs to store many instances long term, you can already manipulate large arrays of objects using python with s

    True, it would work fine as long as you don't use the reference past the point that an instance may be destroyed, which could be never in some cases. This would be great for setting up initial values, as you mentioned.

    Thanks for the tip on your S plugin. I had been using python for my complicated data structure needs. That comment just opened my eyes to some new possibilities. I'll be checking S out, soon.

    Seems as though one (or both) of those two solutions pretty much covers it, hopefully.

  • With the the latest version of Construct(0.99.93) you can reference a newly created object in python like so:

    System.Create('Sprite',1,0,0)
    objRef=SOL.Sprite  #this gets the reference of the new Sprite. 
    
    objRef.x=400
    objRef.y=300
    objRef.angle=30
    objRef.skewy=20[/code:27wv8267]
  • What dowry do you require in order for me to marry you, R0J0hound?

  • With the the latest version of Construct(0.99.93) you can reference a newly created object in python like so:

    System.Create('Sprite',1,0,0)
    objRef=SOL.Sprite  #this gets the reference of the new Sprite. 
    
    objRef.x=400
    objRef.y=300
    objRef.angle=30
    objRef.skewy=20[/code:1w1dg6o9]
    

    Excellent! Any caveats to this? I assume you can do

    System.Create('Sprite', 1, 0, 0)
    objRef = SOL.Sprite
    objRef.x = 300
    System.Create('Sprite', 1, 0, 0)
    objRef = SOL.sprite
    objRef.x = 600
    [/code:1w1dg6o9]
  • Luomu, that will work no problem. Also you can eliminate the "objref" variable and do it directly:

    System.Create('Sprite', 1, 0, 0)
    SOL.Sprite.x =300[/code:32mlmfm3]
  • Luomu, that will work no problem. Also you can eliminate the "objref" variable and do it directly:

    System.Create('Sprite', 1, 0, 0)
    SOL.Sprite.x =300[/code:2btwhewz]
    

    So, can this be used in the fashion of the py fix plugin?

    Is there a len() operator of any fashion?

    Is this correct?

    import random
    
    for x in range(10):
    	System.CreateByName("spr", 1, random.randint(10,400), random.randint(10,400))
    
    for i in range(10):
        spr[i].X = random.randint(10,400)
        spr[i].Y = random.randint(10,400)
    [/code:2btwhewz]
    
    Just wondering.  I couldn't figure out how to use the SOL class for iterating, but the above works (not sure if it's intentional or not, or if that was always functional).
  • SOL stands for "selected object list" and it allows you to access the objects picked via events. When an object is created it becomes the only picked object of that type. Also the created object will not be accessible via "Sprite[index]" until the next frame.

    Say there are no instances of the "Sprite" object.

    System.Create('Sprite', 1, 45, 45)
    Sprite.x=22   #this will cause an index error[/code:25n0pb6b]
    [code:25n0pb6b]System.Create('Sprite', 1, 45, 45)
    SOL.Sprite.x=22   #this will work[/code:25n0pb6b]
    
    Your example will create 10 sprites and move the first 10 sprites not the created ones.
    
    Ideally new objects are modified right after each are created.  You can however create multiple objects save their references and modify them later.
    [code:25n0pb6b]import random
    newObjs=[]
    
    for x in range(10):
       System.CreateByName("spr", 1, random.randint(10,400), random.randint(10,400))
       newObjs.append(SOL.spr[0])
    
    for obj in newObjs:
        obj.X = random.randint(10,400)
        obj.Y = random.randint(10,400)[/code:25n0pb6b]
    
    [quote:25n0pb6b]Is there a len() operator of any fashion?
    
    len(Sprite) returns the number of Sprite objects excluding objects created that frame.
    len(SOL.Sprite) returns the number of picked Sprite objects.  It will return 1 after a sprite object is created.
  • I suppose I don't see how that is a list, though. You're saying I have to make my own list and store the references returned by SOL... so is it a misnomer? Should it be called LastObjectRef instead?

    A list would be.. a list. Not a single reference after 10 calls of Create*()

    It would probably be prudent to do a write up on all the functionality of SOL... lest we all sit around trying to figure out it's actual functionality. As it stands, the Lucid's plugin is more useful for picking objects. I must be confused, I thought this was proper built in support for that bandaid fix.

    As it stands it seems like a wrapper to get the last object created, and not a list at all.

    Surely I am mistaken?

  • In a nutshell

    "Sprite" is a list of all the sprite instances.

    "SOL.Sprite" is a list of all the picked sprite instances.

    The reason "System.Create()" picks only the new object is because that's what happens in events.

    Here's an example:

    http://dl.dropbox.com/u/5426011/examples/pythonSOL.cap

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