Dalal's Forum Posts

  • You could use the Array.At(x) expression, where x is the index you'd like to get the value for and 'Array' is the name of your Array.

    Assuming you have a global variable called "CurrentIndex", you could do something like this:

    Every 30 seconds:

    -- Set text to Array.At(CurrentIndex)

    -- Add 1 to CurrentIndex

  • Hmm, I don't quite follow. This is the way I'm envisioning the basic events if you used a function. What will not work here?

    YOUR LOOP:

    For "" from x to y:

    -- Call "AddValue" (ArrayA.UID, ValueForA)

    -- Call "AddValue" (ArrayB.UID, ValueForB)

    -- Call "AddValue" (ArrayC.UID, ValueForC)

    YOUR FUNCTION:

    On "AddValue", Pick ArrayFamily by UID Function.Param(0)

    -- If ArrayFamily.Back IS NOT EQUAL TO Function.Param(1)

    ----- ArrayFamily.Push(Function.Param(1))

  • You can simulate adding/removing members from a family by adding a boolean to your family's instance variables called "Active". When you'd like to 'remove' an object from the family, set Active to False. To add it back again, set Active to True. To make this work, whenever you perform family specific events, add a condition to make sure that Active is True.

  • Does it have to be done in the expression itself, or would it be okay to use a function (e.g "AddValue") that accepts the Array.UID as a param? This would involve adding all arrays you operate on to an ArrayFamily, and the function would pick the appropriate instance using the UID. It would definitely simplify your events on one end, but I'm not sure if that's what you're after.

  • Worse advice you can give to a mobile dev.

    Don't you see this forum is constantly filled by complaints of poor performance? 99% of the time its because mobile devs failed to optimize their games ground up.

    Even for the PC, it's best practice to always optimize your game and design it around extracting peak efficiency. This is especially true for mobiles, even if your game runs 60 fps. If its efficient, it runs 60 fps while using less CPU cycles, resulting in less "battery draining" or "overheating devices".

    ps. Setting A = B every tic doesn't matter much, but repeat those wasteful events enough, it becomes bloated, poorly optimized and then it truly matters.

    It wasn't my intention to say that optimization on the whole should be ignored. My response was towards this tendency of "blindly optimizing" the game logic, which causes folks to spend eons tweaking their events, without taking care to develop a genuine understanding of what truly makes games performant.

    The way I see it, there are two extremes in high-level development, both which fail to capture reality: The first ignores optimization altogether, thinking the framework will handle it all. The second is obsessive compulsive, and convolutes the code in the name of optimization and peak performance, ignoring so much of what the framework is already doing behind the scenes to make it easier for developers.

    Obviously, there's a wiser approach that strikes a balance and gives peace of mind, allowing you to use your framework the way it was intended to be used for code clarity and organization, and yet get desirable performance out of your game. It doesn't do away with optimization, but uses genuine knowledge (as opposed to simplistic philosophy) to decide what to spend time on, and what things to let the framework handle as it already does so well.

    In the spirit of discovering this wiser approach, we could say that villainizing 'Every Tick' events solely on the basis of them being 'Every Tick' events is blind optimization of logic, which in this case ignores Construct 2's already well-optimized logic engine and steals some emphasis away from real performance culprits, notably graphics intensive operations. You could spend a week hacking 10 events into a single efficient one, but the wisdom of reducing readability and maintainability for the few percentage points of performance you gain would be questionable. To quote Ashley from the "Optimisation: don't waste your time" blog post:

    [quote:1egqpwd8]

    Our profiling has shown it's not unusual for even a fairly complex game to spend 10% of the time on the logic, and 90% of the time on rendering - even when hardware accelerated! In other words, if you're not getting 60 FPS, the #1 thing to do is think about how to speed up the drawing of the game. That might mean having fewer sprites on-screen, avoiding heavy particle effects, and so on. Remember your events and behaviors are part of the logic, which only takes 10% of the time. So even if you went to extreme pains and managed to get all your events and behaviors to run ten times faster overall, which is typically an impossible goal, you will just be reducing that 10% to 1%. The overall performance will just be a few percent better for hours and hours of work, and you could probably have got the same speed-up by reducing the rate of one of your particle effects.

  • Use sub-events to nest loops (you can create a sub-event by right-mouse clicking on an event and clicking Add > Subevent). Name each loop and then use the expression "loopindex([loopname])" to get the loop index for a given loop.

  • ludei,

    Will start saying CJS Canvas+ from now on. Sorry about that!

  • I don't think it's all about their "relationship". Having read some of Ashley's posts on other forums, I get the sense that it's deprecated because of Scirra's new philosophy with this tool: They want to stick to real browser wrappers only. CocoonJS Canvas+ isn't a browser wrapper; it's a specialized environment made for HTML-5 games, and so it has a non-standard way of implementing certain functionality.

    Since Construct 2 is made to work with standard browsers, to officially support Canvas+ would mean having to maintain a separate batch of workarounds just to get things to work within it. And if they go this route (which they already tried), if Ludei decides to change something in their framework and it doesn't get clearly/accurately communicated to Scirra, there will be a bunch of angry users complaining that Canvas+ support is broken in Construct 2.

    So Scirra gets the blame, and it affects people's impression of the product and the company. This is why Ashley has deprecated it, and this is why he is deprecating all export options that are non-standard, because all of them carry this risk. By choosing to focus on wrappers that support the standard browser protocol, Ashley can be sure that if he's got it to work in a browser, it should work in these wrappers, which promise to follow the same protocol rather than inventing their own.

    That said, CocoonJS Canvas+ is still the best option to export for mobile. The fact that it's non-browser is what allows games to run so performantly through it. I think it was a worthy tradeoff, and as sad as I am that there is no longer an "official" export option, I think I can understand Ashley's reasoning.

  • Construct 3 might change things. Maybe.

  • +1. Let's keep this going!

  • Wise choice to develop for desktop. Mobile can be a painful, heartwrenching journey

    ... but now I have two people saying two different things.

    Hehe, well not necessarily. I was talking more about the logic side of it. To say that "Every Tick" on its own is a 'bad' event is misleading, as it implies that merely executing some logic every frame can cause slowdown. What's true is that using Every Tick for intensive graphical operations could be a bad idea, which is where he may have extracted that rule-of-thumb.

    Rotating objects frequently (rotate behavior or setting angle every tick) is one that doesn't show up in that list, but it can really slow things down, especially if you are rotating large objects.

    This is interesting. I was under the impression that mobile GPUs would be pretty good at elemental operations like translation, scaling, rotation, etc. Did you experience this on CocoonJS as well? I'll have to test it.

  • Nesteris,

    Actually I wouldn't worry at all about most Every Tick events. The biggest source of slowdown on mobile is related to graphics, not logic. Unless you've got some hardcore physics calculations happening (EDIT: or insanity with loops, and other serious logic slowdown issues, anything way out of the ordinary), forget optimization and just make sure your code is organized and pleasing to the eye. Setting A equal to B every tick has practically zero impact on performance. Ashley has addressed this on his blog. If you haven't already, read it and feel relieved.

    https://www.scirra.com/blog/83/optimisa ... -your-time

    The best advice is to periodically export the game and check its performance on mobile. That way, if you made a change that breaks performance, you can re-evaluate your approach.

    Also, CocoonJS Canvas+ is the best export option when it comes to performance, there's no doubt about it. Because it's a "non-browser engine", Ashley doesn't like to promote it, otherwise users complain about Construct 2 being flawed when there are compatibility issues. The truth is that CocoonJS Canvas+ is WAY better performance-wise than Crosswalk, especially when it comes to twitch-based action games with lots of movement in them. So forget compatibility. If you are developing strictly for mobile, and CocoonJS Canvas+ works for you, then develop to export through it, and you'll get much higher quality results than Crosswalk.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Glad to know I was able to help! And yeah, new tips/tricks are always fun to learn. Programming on the whole is a vast frontier, with new things to discover around every corner. Good luck on your game!

  • I might have not understood properly, but I don't think you need an all-in-one sprite in the first place. It's less manageable, and no fun. I don't know what kinds of data you'd like to store, but in many cases, one array can hold the attributes for all your troops. For example, let's say you have Green, Yellow, and Red troops. Each troop has two attributes: Speed and Health.

    Define constants as follows:

    GREEN_INDEX = 0

    YELLOW_INDEX = 1

    RED_INDEX = 2

    ATTR_SPEED_INDEX = 0

    ATTR_HEALTH_INDEX = 1

    Now, make sure your array has a width of 3 (the number of troops), and a height of 2 (the number of attributes per troop). Now, you can set/store an attribute for a given troop by using the Array (Set at XY) command, where X is your troop index, Y is your attribute index, and Value is the value you'd like to set it to.

    For example, to set the Yellow troops health to 60, simply use Array (Set at XY): X = YELLOW_INDEX, Y = ATTR_HEALTH_INDEX, Value = 60.

    You can read these attributes in a similar way.

  • You can use one array and use one column for each unique troop. Or you can create a unique Array object for each troop.