roboscan's Forum Posts

  • dop2000 - Thank you very much for the detailed example!

    I think I'm getting this.

    I program in PHP, JS as well as microcontrollers (variants of C, I suppose) on a pretty regular basis so a lot of my "flow logic" comes from those experiences. I have been scripting on Construct using the same logic, until I run into snags.

    I believe I have an understanding of the "nesting" of sub-events: They're like the Construct equivalent of putting an IF Statement (or any statement) inside of another IF statement?

    Example:

    //This is the first top-level event
    IF (the button is pressed){
    
    	Create SOMETHING; //this action will happen immediately.
    
    	//This is a sub-event
    	IF (a second button is pressed){
    
    		Create SOMETHING ELSE; //only if the other button is already being held down.
    	
    	} //end sub-event
    
    } //end FIRST top-level event
    
    //SECOND Top-Level Event:
    Change SOMETHING ELSE into ONE MORE THING;
    
    

    IF NO WAIT actions are involved, I would expect the sub-event inside the first top-level event will take place before the second-top-level event is executed:

    "SOMETHING" would be created, followed by "SOMETHING ELSE" (so long as the condition that made "SOMETHING" happen is still being met) and finally "SOMETHING ELSE" would be changed into "ONE MORE THING." - BY the time we get to the second top-level event, I would expect that SOMETHING and SOMETHING ELSE have been created.

    Again, without any WAIT actions, would this be correct, or would "Change SOMETHING ELSE into ONE MORE THING" still take place before the sub-event "Create SOMETHING ELSE" and thus fail?

    If this would work, then I think I can say I am getting it.

    Thank you, again!

  • rojohound, Thank you...

    I understand the concept of needing to wait until the next top-level event before the object that was created is "available." Well, I sort of do, lol. I can understand it conceptually, although I suppose I don't really understand what is actually happening under the hood.

    I've garnered that it's something like, since the events are happening asynchronously, whatever is happening in "this thread" doesn't know what's happening in "that thread" until both are finished and we hit the next tick.

    I keep running into scenarios where I THINK what I've scripted is going to run sequentially (for example, a For-Loop sub-event running within a For-Loop super-event) but the result I observe more often than not seems to be the outer loop and inner loop running concurrently.

    The Wait 0.0 is one of those things that falls into that category - As I've read, adding a "Wait" will put off the next action until after the Wait, but it will not pause the whole script (as in the case of, say, Adruino Programming). If I have in my script:

    Do Thing 1

    Wait 1.0

    Do Thing 2

    Do Thing 3

    What I would expect logically is that it will do exactly that... Thing 1, Wait 1.0sec, then do Thing 2 followed by Thing 3.

    If understand what I've read, however, what will really happen is:

    Thing 1, Thing 3 and then do Thing 2 when the Wait 1.0 time is up (which may or may not be before Thing 3 depending on how long the Wait Time is vs how long it takes to get to Thing 3).

    What I've experienced (or at least it seems) is that I end up with Thing 1, Wait Time, Thing 2 and then it's anyone's guess whether or not Thing 3 will ever happen.

    I'm sure that is not actually what is happening, but it certainly seems that way.

  • Could someone explain to me how using "Wait 0.0" to force an action into the next tick is supposed to help (work)?

    I've encountered another issue that is probably the same issue as above... I am populating a list from JSON, and while it populates, gets created and appears on screen just fine, the list items are not "available" to the system actions.

    I populate the "roomList" list from a "roomList.json" file early on.

    Then I am iterating over another JSON file, "strands.json," which contains details for cable strands containing a reference to a "locationA" that is in the roomList.

    Inside that second loop, I am attempting to create an instance of "roomList" for each item and pre-selecting the appropriate "room" in that "roomList" from the "locationA" field in the "strands.json" file.

    In a sub-event of the block that "creates roomList object" I am trying to make the selection... The logic to compare the list is not the issue as if I hard-code "roomList.selectItem(5)" I still get nothing selected.

    If I attempt to run a for-loop over the list (for 0 to 10: Log "roomList.ItemTextAt(loopindex))" I will get zero 11 times.

    If, however, I add a Wait 0.0 after the "create roomList object" block, I WILL get a selected item. (and my 0-10 loop will log each item in the list) but no other parts of my script will run after that.

    It is my understanding that adding a "Wait 0.0" forces the next action to execute on the next tick, but I really can't understand the flow and why it seems to "break" the loop that I put it in.

    I suppose I have 2 objectives: One is to really understand what is happening so I can, generally speaking, properly script in Construct. The other, of course, is to achieve my objective of creating, populating and pre-selecting an item from a list. It seems like I am jumping through way too many hoops to do something so simple - I've gotta be going about things the wrong way.

    Thank you!

  • I do (now) understand this, however what I experienced seems like the opposite of what you are showing here... The new instances were NOT available to my sub-event right away, but they WERE available to other events.

    In actuality, it may just be the new instances' properties that were not available (I could position a new instance immediately in the same event, but I couldn't read that position in the same or a sub-event.)

    I have an on-screen button that kicks off the loops creating objects... If I clicked it once they would be created, but the sub-events didn't "work." If I clicked it a second time, even though the very first thing I had it do was "destroy" any existing objects before re-creating them, the sub-event would work. I believe this happened "coincidentally" because the sub-event was able to read the properties of the existing instances before they were destroyed (I'm guessing because it probably takes a short amount of time to destroy instances as well)

    dop2000, Thanks again 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
  • Update: I have it working.

    I had a ForLoop searching the JSON file for a specific entry... within that loop, I had a ForLoop generating the objects found on a schematic... within that loop, I was trying to overlay a test graphic (eventually to be a connecting line) at a specific ImagePoint on the schematic objects.

    As I said I would do in my previous post, I separated the nested ForLoop (for the test graphic) from the outer loop and placed it on the script outside of the outermost ForLoop. This is working!

    I was also able to go back to using "ForEach" loops for all of my loops and built-in references like "device.ImagePoint(0)" are working without the need for adding loop names and indexes.

    I removed all "Wait"s.

    (See screenshots below).

    I am still wondering why I have to do it this way. There really does not seem to be a way to effectively "pause" the script long-enough to instantiate the objects before their properties became available to the next part of the script. Is that not possible, or, again, was I doing something wrong? No matter where I placed a "WAIT", it would "un-order" my subsequent actions.

    What I have now should work for my purposes, but I would be interested in knowing if there is a better way or if I am misunderstanding something. (I produce small applications - some games, others utilities or front-end GUIs in Construct - as I am doing here - often, so I'm trying to get better and better at using the program.)

    Thank you all, for your assistance and input!

  • EDITED

    I wrote a whole long post, but I've been trying different things for a while and think I have a better assessment of what is going on so I deleted what I wrote earlier.

    What I think IS happening is exactly what you said earlier about the instantiation of sprites taking some time...

    My sub-event (inner ForLoop) is executing before the devices family members are finished being created so the references to the "last object created" (eg. familyName.ImagePoint(0)) don't work because they probably don't exist yet.

    The problem is that if I add the "Wait 0" anywhere, it causes my inner loop to fire after the outer loop is finished repeating so my loops end up not being nested. This means loop indices don't flow form outer to inner and variable auto-incrementation falls out of order.

    Ideally I would like to do things sequentially:

    Create an instance of a device -> Draw something at an image point belonging to that device -> repeat for next device. But it looks like that can't happen.

    It looks like I will have to do things in two separate (un-nested) loops.

    1) Instantiate all of the devices that are in my JSON file and place them on screen.

    2) Iterate over all of the newly created devices... compare each one to each of the devices in my JSON file... when there is a match, draw the appropriate object at the appropriate image point for that object.

    Does this sound like I am understanding things correctly?

    Thanks.

  • dop2000

    So I've made some progress. Adding the Wait 0.0 made a world of difference in terms of getting output that I was looking for, but I found that I have to add indexes to the devices family in order to reference its members.

    I added the lines you suggested for logging. Nothing in the log would appear until I added wait after creating the objects.

    My order is:

    For each entry in ".path" (from my JSON file) Create object (sprite name from JSON file) Create textbox Set textbox to (title from JSON file) Wait: 0.0

    My x position calculation stopped working which takes place after all of the inner-loop actions so I found that moving to above the Wait function solved that issue. (I keep having to reorganize my thinking around the concept that Construct executes everything more or less simultaneously and not sequentially - I suppose each iteration of the outer "For Each Entry Loop" executes before the subsequent "For Each devices" sub-event actions. (Hence adding the Wait in the first place, yes?)

    But what I also found through trial and error is that I have to add "indexes" to the "devices" family whenever I am referencing it ("devices(1)").

    So devices.ImagePointX(0) will only reference the very first object created from the family, but devices(7).ImagePointX(0) will reference the 8th object created from the family.

    I have not seen this anywhere in the documentation, but it does seem to be working.

    I also had to create my own index (deviceIndex) as the "For each entry in ".path" does not seem to create a loopindex. (it always evaluates to 0). So I have a variable, "deviceIndex" which advances by 1 for each object created.

    So now, after adding the Wait 0.0 and then changing my subsequent loop to:

    For Each devices: if devices(loopIndex).ObjectTypeName="ccehd": { //DO STUFF - place my test image, output the imagePoint coordinates, etc }

    It looks like I will be able to reference the image points that I need to reference.

  • I've tried doing that but it didn't seem to give me the correct image point location..

    I instantiated my sprites like this:

    This places the sprites named in my JSON test file from left to right on screen, calculating their position from a variable devImageWidth = 1200.

    (8 sprites load, each one is given a space of 1200px w to sit in and all 9600px worth of images are centered on the layout. I'm using scrollX to slide left to right.)

    For testing, I then tried to place another sprite at the same X location as the desired imagePoint (I haven't started scripting the connecting lines I ultimately wish to make).

    When I do this with no conditions, it places 8 "statusLed" sprites in line with the very center of all 8 sprites directly on top of each other (I can see the 8 of them in debug.)

    When I add either of the commented out "devices.ObjectTypeName = " conditions (both are same condition, tested one from JSON reference and the other typed just in case I was having a JSON issue) the "statusLed" sprites do not get created.

    I have also tried changing the ImagePoint() number but that does not change anything.

    When I append ImagePointX() to my testing text area, it shows as "0" which is where the center of all 8 sprites is. If I mess with my placement math so the images skew left or right of center, devices.ImagePointX(0) remains at 0px for all 8 instances.

    I thought I might have to do a "for each devices" and then have the "if ObjectTypeName =" condition, however that does not seem to generate the desired result either.

    Am I making some other glaring mistake?

    Thanks again.

  • rojohound & dop2000 Thanks again for your input. My day didn't go as planned (took my car in for a new tire this morning and ended up waiting around 3 more hours than I had expected) so I didn't have time to work more on this project today. I will roll your suggestions into my trials and errors tomorrow.

    Earlier today I conceived the idea of using a 3D array to store all of the image points (X and Y locations) for all of my device sprites upon starting the layout (there are a lot of them, some of my "devices" have 80 image points) and then cross-referencing them in the array for the devices I need to draw on, but then it occurred to me that if that array is filled before the sprites are positioned on the page, the X and Y locations in the array will not match the "new" x and y positions of the placed sprites. :-(

    Just as there is "Create Object (by name)", it would be so simple if there were only a "Pick Object (by name).ImagePointX(0)"

  • So I think I confirmed that running a forEach on a family just counts the number of instances of that family, not the members of that family. I'm still working on how to properly reference its children.

    I tried doing a for loop from 0 to family.AllChildCount but this only returned a single iteration of the loop. It is not properly counting (or detecting) the family's children. Perhaps I am not understanding how families are supposed to work.

  • Thanks for your reply.

    So far it seems that my family idea is not going to work. I created a family called "devices" and put 10 device sprites into it.

    I am loading 8 of those sprites onto the layout using the Create Object (by name) from my JSON file which is working perfectly well.

    When I try to run a For each on the "devices" family, I am not getting any actions to work despite adding family members to the layout.

    Until a few minutes ago, I had all of the sprites I've created sitting on the layer, outside the layout area. When I was running the for each

    For each "devices": devices.ObjectTypeName = "ccehd":

    ("ccehd" is the name of one of my sprites that I was testing with)

    For testing, I was appending some text and "devices.ObjectTypeName" to a text box.

    It was iterating 8 times (the number of sprite family members in "devices" that were created on the layout). Which almost made sense, execpt it meant that my second condition, "devices.ObjectTypeName = "ccehd", was not evaluating true.

    For another test, I toggled the second condition off and my test text iterated 10-times. The total number of family members; not just the number currently on the layout.

    It then occurred to me that technically I DID have all 10 sprites on the layout, they were just off screen, so I removed them, but after I removed them, the loop stopped iterating altogether. So despite dynamically creating 8 family-member instances, the "for each devices" loop was not seeing those sprites as family members.

    Doesn't look like this is going to work as I hoped.

    Further, the second part - figuring out a way to reference them is still unclear... I can incorporate "devices.ImagePointX(0)" in an action, but that is not the reference point I am looking for. There does not seem to be a way to drill down to the specific family member. (I tried "devices.ObjectTypeName" - which does print the sprite name in text - but there is no ".ImagePointX()" that I can append to it.

    I am thinking I may have to build an array that links references that I will use in my JSON file to objects in the array. I am guessing this may be what is in the capx you posted, but I haven't had a chance to look at that, yet. That's for tomorrow morning.

  • Greetings once again,

    I am using a JSON file to feed the name of an object (a sprite) into my script. I am then using Create object (by name) to instantiate that object in my application.

    I do not, however, know how to then reference that instance of that sprite. Can anyone help?

    More details:

    I have many different sprites with image points on them. The goal of my application is to dynamically draw a schematic showing how one device (referenced by a sprite) connects to another (referenced by another sprite) by drawing a line from image point on the first sprite to a different image point on the second sprite.

    All of the information is stored in a JSON file. (The sprite names, the referenced image points for the respective sprite, etc.)

    I query the JSON file, use the Create Object (by name) function to instantiate the sprite and then I am stuck.

    I need to be able to reference [the image I just created's] image point, however I do not know how to reference the [image I just created].

    Normally, when using the fixed Create Object function where we choose the object to create, the subsequent reference would simply be [that known object].imagePoint or whatever, of course, but in this case I can't do that.

    I know there is the "pick last created," but that too, requires the manual selection of the object type.

    One thought is to put all my sprites into a family and then trying pick last created [family] and seeing if that works, but I don't know if families work that way, or if Construct will be looking for the *last family* that was created. (I am about to try this.)

    If anyone has experience with this, I would greatly appreciate the help.

    Thank you.

  • YES! That did the trick! Thank you very much!!!

    How does one get their brain to think of those alternative work-arounds? LOL

  • Would I do this by using an "if statement" (sub-event)?

    Put a for-loop inside the On Any Error as a sub-event and then in that for-loop do:

    if AJAX.tag == statusLed.ledID

    ?

  • A Clue!

    dop2000 - So I just ran it a few times looking at the console.

    When I used onError, I get this in the console:

    I confirmed these two lines are referencing my "status check" AJAX calls by disabling / enabling the call in my script. Since I am previewing, it appears that the call is actually being made to Scirra's servers (preview.construct.net/local.html) instead of my actual URL and is completing successfully as a result.

    So I changed my condition to onComplete, checked the Console again and found this!

    It would appear that even though Construct let me put the AJAX.onError inside the loop, it doesn't actually want me to do that. I believe this could certainly explain why my actions aren't firing.

    So I guess now I have to figure out another way to get it to check the result for each of my individual AJAX calls. (I will my idea of advancing a variable).

    If you or anyone has a good way of doing this, I would be greatly appreciative.

    Thank you!