Ancillary's Forum Posts

  • 13 posts
  • Use the instance ID (IID) to select them individually in the Pick by Comparison event, or assign each of the instances a unique variable (such as a string variable with some kind of unique name for each of them) and then pick based on that.

  • PSI - I managed to run across the bug again, and posted a pared-down .capx in the Bug Reports forum demonstrating it. I believe it has something to do with the Array object, as attempts to trigger the bug with a Sprite Text object, using a similar comparison, didn't produce an error.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • A brief addendum: I tried altering the Pick by Comparison condition in Event 9 so that it instead picked the TurnPhase object based off of a ParentTag string variable, and it produced no error. I believe that the Array object might be the ultimate culprit.

  • Problem Description

    When attempting to use "Pick by Comparison" on an Array object that's in a container with multiple instances, an error message is returned, but only for one of the instances.

    Attach a Capx

    dropbox.com/s/0u9q51qiuwev6ng/ContainerTest.capx?dl=0

    (Can't attach or do links yet; sorry. Just add the usual https protocol in front of the Dropbox section.)

    Description of Capx

    A pared-down version of an RPG battle system to show the bug. The "Begin" button in the middle will create the Units and the CharacterSheet array that is a part of their container. Two units are created: the Test_Player_1 unit and the Test_Monster_0 unit. The "TestPlayer" button on the left will simulate the player unit performing an attack. The "TestAI" button on the right will simulate an AI-controlled unit performing an attack. In both cases, the attack will create a waypoint next to the target, the unit will move to the waypoint, perform an attack roll, and then return to its starting position.

    Steps to Reproduce Bug

    • Start up the .capx on the Combat Scene - Basic layout.
    • Press the "Begin" button to spawn the Units and start the turn countdown.
    • Press either the "TestPlayer" or "TestAI" buttons. When the turn countdown has finished, it will make the appropriate unit perform an action (the "TestPower1" function in the Powers event sheet), which in this case will make it run up next to an opponent and perform an attack roll.

    Observed Result

    When the Test_Player_1 unit arrives next to Test_Monster_0, it performs the attack roll and returns to its starting position without incident. When Test_Monster_0 arrives next to Test_Player_1, however, an error message involving not being able to find the correct IID pops up. The function continues normally, however.

    I was able to isolate the event that causes this: Event 9 in the Powers event sheet, which is called from Event 3 in the Powers event sheet. This event attempts to pick a CharacterSheet array based on a comparison between a 0-index function parameter and the CharacterSheet's "ParentTag" string variable, which is the same as the "Tag" string variable for its respective Unit object. Disabling this event removes the error message.

    Expected Result

    Both should produce identical results without an error message.

    Affected Browsers

    • Chrome: YES
    • FireFox: YES
    • Internet Explorer: YES

    Operating System and Service Pack

    Windows 7 Home Premium, Service Pack 1

    Construct 2 Version ID

    Release 200 (64-bit/Steam)

  • Buttons are HTML elements that are drawn on the "web page" the game is displayed on, overtop of the canvas. They always ignore the Z-order of anything except other form elements (such as listboxes).

  • I had the same issue pop up when using a Sprite object with two Array objects in a container. Attempting to Pick by Comparison the second Array (based on a shared tag variable) gave me that same error. Picking the first Array gave no error. My attempt to reproduce it under similar conditions in another .capx failed, unfortunately. I eventually got around it by simply creating a separate Array whenever a new Sprite was created and using the same shared tag for them. Weirdly, even with the error message, the Array was still picked correctly and the code otherwise executed without issue.

  • What is the range and cone of view you're using for your LoS behaviours? Are you using the collision cell optimization option for the LoS behaviour?

  • Ashley: Would it be possible to include a "Simulate Touch" action for the Touch object, or something similar? This would let mobile developers trigger a "phantom touch" at an innocuous location in order to then start up the music track.

  • The easiest way to do this is through the creation of arrays and the use of dynamic functions. This will help to reduce the amount of code you'll need to implement, as well as making it easier to add/remove classes or skills. I'm presuming some foreknowledge of arrays and functions on your part. If you don't know a lot about them, check out some of the tutorials or the manual, as they give fairly good overviews of the concepts.

    First, you should establish the arrays that you want to use outside of C2. Editing them by hand this way does require a few more lines of code than normal, but it's far easier than trying to edit them via C2 directly. In this example, there will only be one array, though it's up to you how much you want to subdivide the arrays up.

    The leftmost column is entirely for the benefit of the editor. In actual scripts, it won't be referenced at all. The rightmost one (and any columns after that) contain the data for each class. This involves any stats that you might want to have (such as BaseDefense, BaseAttack, etc.), as well as any skills that a particular class will have.

    The arrays should be saved as .CSV files, which should then be added to your project as project files. I use rexrainbow's CSV2Array plugin (which you can find with a quick Google search) in order to "inject" the data from the .CSV files into an Array object. The method I use is mostly meant to make the injecting of multiple arrays easier, but it's not necessary if you only have a few of them. (It's a bit of a longer explanation, but I can show you an example, if you want.) The important thing is to get the data into an Array, which can be done by requesting the .CSV file using AJAX, checking for when that specific request has finished, and then injecting the data into an Array object using the CSV2Array plugin's features.

    The second step I would do is to set up a separate Array object that will store all of the character's data after they select a class. Set it to the same height as the Array object that contains all of the class information (in the case of my example, to 11). When the player selects a class, you can then copy the basic class data from the class array to the character stat array, like so:

    (Sorry that this got a bit cut off - just check the direct image link to see the full script.)

    In this example script, "MonsterSheet" is the name of the array that contains my class data (ignore the name - just pulling it from a script I already had set up), while "CharacterSheet" is the Array object that I'm injecting the data from MonsterSheet into. The first parameter in this function (the Function.Param(0) call) contains the string reference from my MonsterSheet array. So, if the player selects the Fighter class in the menu screen, you would call the "SetClass" function, with Parameter 0 as "Fighter". The script will look up the x-index in the MonsterSheet array that has "Fighter," and all of the data from that column will be put into the CharacterSheet array.

    You can then use basic scripts and functions to reference or change the data from the CharacterSheet array. If, for example, you have it so that the player character uses their first skill (Skill1 in the array) when they press "1" on the keyboard, you can simply have the script call up a function that references the CharacterSheet, like so:

    This will then, in the case of our example, automatically run the function named Skill_PowerBlow. The main advantage of this array method is that you can very easily move skills around (such as making the player get them at a different level) without having to also move the code around much. Similarly, if you end up patching your game at all, it's much easier for games that are already in-progress to adjust, since they simply have to read from the new array and make adjustments accordingly. This method is also much easier to use when trying to apply things like status effects. When using variables, I had to create individual functions for every status effect that I wanted to apply, whereas, when using an array, it only requires a small handful of functions for applying/stripping status effects.

  • I haven't used Rex's nickname plugin at all. Apologies! The method I normally use is:

    1) Make sure each of the prefabs are gathered together in a Family, and create a family (string) variable called "Tag."

    2) Give all of the backdrop prefabs a "basic" tag (like "Platform Prefab," "Climb Prefab," etc.).

    3) After the backdrop has been spawned in, add the loop index to the tag of the backdrop. If I spawn in a "Platform Prefab" backdrop on the second loop iteration (e.g. LoopIndex = 1), then its tag becomes "Platform Prefab 1". This is for the next step in case you happen to have duplicate prefabs throughout the level. If you end up deleting the backdrops after each of them has spawned in its pieces, adding the loop index is unnecessary (since there will never be more than one backdrop being spawned in at a time).

    4) Create individual spawn-in functions for the pieces. For my method, each function would contain two parameters: an integer for the image point (either drawn from the array, or with the loop index method I described on the previous page), and a string for the tag of the last spawned-in backdrop prefab. The function would first create the piece. Then, it would pick from the backdrop prefab Family using a comparison check (BackdropFamily.Tag = Function.Param(1), or whatever index you selected to inject the backdrop tag into) and attach the newly spawned piece to the picked backdrop prefab's image point (obtained from the function parameters again).

    With rex_nickname, you might not need to create multiple functions, but, instead, a single "master" function for spawning all of the pieces in. You would need a third parameter (the string needed to spawn in the piece, which can also be obtained from the array) for the function. I'm not sure how rex_nickname works with regards to object picking (that is, whether the last-created object is always picked in subsequent events), but the method should be similar to the above.

  • I'm going to do method 2, but I'm not sure how to setup the excel document. The thing that's tripping me up is the image points, there will be different numbers of image points on each prefab, so how exactly do I store it?

    Two methods that you could do:

    1)

    For this method, you state the piece that you want to be created in one cell, and the image point on the backdrop sprite that it should be positioned on in the second cell, repeating until you have all of the pieces that you want for that prefab. The loop will check the cell at 1 (x) for the piece, and the cell at 2 (x) for the image point in order to spawn it in. The loop index that you use to check each of the cells in the array will increase by 2 after every piece is spawned to maintain consistency. To end the loop, simply make the loop conditional on the currently checked cell =/= 0. If you have nothing in the next cell being checked, the engine will always return a 0, so the loop will simply stop dead once it runs out of pieces to spawn with that conditional.

    2)

    Similar to the above, but this method uses the tokenat expression to reduce the amount of clutter in the table. Each of the pieces is followed by the image point after a comma, which a tokenat loop can then take apart in order to read the piece and image point. Valerian has a tutorial (search for "How to do advanced callbacks in Construct 2" in the tutorials section) on how to do a tokenat loop that I've used before successfully. This is mostly an organizational method, however. The first method will work just as well, though with a larger number of cells in the table.

    Edit: Actually, I thought of an even simpler way to do this: if you have the pieces in your CSV table in the same order as your image points (so that Piece 1 corresponds to Image Point 1, etc.), you can make your loop set that piece to position itself according to the loop index.

    An example: assume that your loop index starts at 1, and we're using the table in 2), but without the commas/image points in the table. The loop index will check the first cell (1 (x)) and run the Floor function, passing in the loop index as a parameter to the function, as well as the unique tag of the backdrop prefab. Because the loop index is passed in, it will create the Floor object at image point 1 (the loop index). You can then repeat the loop and spawn each successive piece at its corresponding image point by iterating the loop index by 1 each time.

  • r195 completely fixed the slowdown-over-time for me. Give it a shot.

  • It might be better to simply create your own prefabs, either via individual functions or via CSV arrays. This will require a bit of initial legwork, but should make it relatively easy to create new prefabs in the future. I'll try to describe the two methods a bit more.

    For both methods, you will want to create a "backdrop" sprite that will serve as the base for your prefab. You should try to keep the backdrop sprites relatively consistent in terms of width/height to make it easier to snap them together when the layout starts up. If you expect to have prefabs of varying height, establishing an origin image point that every prefab will adhere to (e.g.: 0, 25, or something similar) will make it easier to position them later on. These backdrop sprites can be destroyed on spawn after all of the prefab pieces are spawned in, or can be made visible and serve as an actual visual backdrop, depending on what you'd prefer.

    For each backdrop sprite, create image points for where you want the "pieces" of the prefab to spawn in, corresponding to the origin points of each piece. For your first prefab (the one highlighted in blue), you would likely want a floor image point, and then three image points for the platforms, for example. It's better for memory reasons to have each of the individual pieces as single objects, rather than duplicating them for every prefab, so we're going to use image points to determine their position when spawned in.

    The method that you choose to you will vary depending on how much code duplication you're willing to do. Here are the two methods:

    1) Individual prefab functions. Each prefab is established as its own particular function. The function parameters are simple: the X (index 0) and Y (index 1) position where the prefab backdrop will be created. These functions will first spawn in the backdrop unique to that prefab, and then all of the component pieces (using the "Create Object" event). The component pieces are then positioned at each of their corresponding image points. This is the easiest method to do in-engine, but will require a decent amount of code duplication, which you may or may not be up for.

    2) Array loop. For this method, the prefabs are established in an array (using something like Excel to create a CSV table, which is then imported in via RexRainbow's nice CSV2Array plugin). The array contains the name of the prefab (for in-engine spawning purposes), and then each of the names of the pieces and their corresponding image point, which can be done in one of several ways (preferably tokenat). In Construct 2 itself, you then create a "master" function that will spawn a particular backdrop prefab. Then, reading the array entry for that prefab, it will spawn in each piece (which, sadly, has to be done by making individual "Create Object" functions for each piece; no way to choose to spawn an object from a Family that I know of) and set it to its specified image point via a loop. This method requires less code duplication, but, as you can probably tell, requires more mucking around outside the engine.

    These two methods should work for your purposes. I'm assuming you're either making some sort of infinite scroller or a randomly-generated platformer?

  • 13 posts