tanoshimi's Forum Posts

  • And the game is.... where, exactly?

  • Hi R0j0jound,

    "With a 2d array push() only sets Array.At(Array.Width-1, 0)"

    • Thanks for confirming that, which was the behaviour I was experiencing, although wasn't sure if it was something I was doing wrong! I couldn't find that limitation documented anywhere - it would be nice if the push() method documentation included the fact it only works with 1D. (Who do I suggest documentation edits to?)

    "You have to set the values at Array.At(Array.Width-1, 1), Array.At(Array.Width-1, 2), etc... manually."

    • Thanks. So, combining this with an Array -> Set size to (Array.Width+1, Array.Height, Array.Depth) action, I can simulate a push() onto 2d arrays.

    "All that's left is to implement a way to sort it"

    • Ah, I had glanced through the Array documentation and seen the Sort method, assuming this would already do what I wanted. Reading more closely, and experimenting a bit, I see that it doesn't! (i.e. there's no inbuilt method to sort an array by a key contained in an arbitrary X/Y row/column). Ok, well, my array is not too long, so even if I implement a naive sorting algorithm in O(n2) time, that should do fine.

    Thanks again for your help.

  • Hi,

    (I'm really sorry to have ask another question about arrays - I promise I have searched the forums and read the many, many existing threads!)

    I'm maintaining a structure similar to a local high score table but, rather than ranking the player's performance between successive games, I'm ranking the performance of the computer-controlled enemies within the current game. As the game progresses, new enemy instances are created based on the properties of the previously highest-performing instances. It's a kind of simple genetic evolutionary progression, in that I hope the "fittest" (i.e. best performing) enemies in each level pass on their behaviours to create more successful future generations of enemies.

    Let's say for the sake of argument that my enemies have two properties - their movement speed and their rate of fire. And, when each enemy is destroyed I assign a "fitness" score that determines how successful they were (based, say, on how many ticks they stayed alive for).

    So, a snapshot of my data might have the following information about enemies that have died so far:

    Movement_Speed | Rate_Of_Fire | Stayed_alive_for

    30             |     2        |    10

    20             |     1        |     8

    5              |     8        |    30

    1              |     6        |    25

    ...

    As enemies are destroyed, a new row is added to the table. Each level has a fixed number of enemies, so the maximum number of rows is known.

    However, the number of columns may vary in the future (let's say I also decide to record the "Armour" property of each enemy in another column).

    I need to be able to sort the data but only based on one key (how long they stayed alive for), in order to be able to select the best-performing parents from which to derive better enemies in the next generation. In fact, I'd quite like the table be maintained as a sorted list so that I could pick off the highest scoring enemy to date as at any time.

    So, my question is, how would you best achieve this using the structures available in C2? I've considered various combinations of multiple 1d arrays - one for each property (but I couldn't work out how to sort them all based on the keys in one array?), a 2d array containing only the fitness score and an ID that points to a dictionary entry maintaining the other properties (but I couldn't work out how to push() onto a 2d array).... and I've rewritten my code so many times that it's got scraps of different ideas all over the place now.

    Hoping that some of you brainy and helpful let might save me from this dirge of code spaghetti! Thanks in advance.

  • Thanks all for the feedback.

    newt - I think I had originally planned to make it possible to flock with instances of other types of object but, as you point out, it probably makes more sense to just flock all instances of the same type of object on which the behaviour is added.

  • (Disclaimer - I've only been working with Construct2 since Monday, so I have no idea if this follows best practices or not, but it seems to work for my purposes so I thought I'd share it here!)

    This adds a new movement behaviour based on the "Boids" flocking model first described by Craig Reynolds at cs.toronto.edu/~dt/siggraph97-course/cwr87

    When flocking, a character's movement is based not only on its desire to reach a target, but upon the relative position and speed of other members of its flock. There are four factors that influence the direction of movement - the desire to:

    • Head towards a target position
    • Avoid collisions with immediate neighbours
    • Head in the same direction as the rest of the flock
    • Stay close to the centre of the flock

    I had tried originally to implement this behaviour using the "Custom Movement" behaviour, but it seemed to involve a lot of hacking on the event sheet (explored by R0j0hound in scirra.com/forum/boids-tests_topic59833.html), so wrapping it in a new behaviour seemed more appropriate.

    Using the attached "boids" behaviour, you can set the target X,Y and also specify an object type to which an instance will flock together. The relative influence of each factor on the final direction of movement is governed by the targetPriority, seperationPriority, alignmentPriority, and cohesivePriority parameters. The seperationDistance parameter controls the optimum distance which each boid tries to maintain from others in the flock.

    <img src="http://i50.tinypic.com/102t56d.jpg" border="0" />

    Behaviour is a3uk.com/boids/boids_behaviour.zip, and example CAPX is a3uk.com/boids/Boids.capx. The example (which obviously requires the behaviour to be installed) shows 10 bat sprites that will follow the mouse cursor around the screen. You should notice that the movement of each individual bat is affected by the behaviour of other bats in the flock and, while they aim towards the cursor, they should also steer to avoid collisions (seperation), and try to remain together (cohesion).

    <img src="http://i49.tinypic.com/5bpikj.jpg" border="0" />

    Comments/suggestions welcome.

    [p.s. I must congratulate the Construct2 designers for creating such an elegant plugin system - it was refreshingly simple to use!]

  • R0j0hound - thanks so much for pointing that link out - I completely missed that post when I first scanned through the forums. In fact, your series of three BOIDs examples nicely exemplifies many of Kyatric's suggested workarounds (and the reason why I'd rather work with vector math, as I'm sure you did!)

    I think I've decided to go the custom behaviour plugin route - having had a quick look at the example behaviours it seems (relatively) straightforward to write a plugin, and a whole lot easier on the eye by encapsulating the logic in a separate code file (where I'm free to do vector math - mwa ha ha!) rather than on the event sheet.

    My intention is to try to encapsulate several of Reynolds' steering behaviours - not just flocking as shown by the BOIDs example here, but seeking/fleeing/arrival/leader-following/queueing, for example.

    If I get it to work, I'll let you know. Thanks!

  • (Ack! Wrote a long reply to this and then lost it. Edited version follows)

    Thanks very much for the reply, and the link to the article.

    Can the Function() object send back arrays/dictionaries as return values? I couldn't see how to do that, and if it can only return a single value I'm not sure if it will help other than to tidy up the event sheet slightly.

    I'm not sure I agree with Ashley completely in that article. Seperating out the X and Y components in anything other than a trivial vector calculation generates a lot of extra work that probably more than offsets any gain from reducing object creation (IMHO). And performance isn't everything - I'd rather my code be understandable and use established vector computations rather than using an arcane method just to squeeze a little but more performance out of it!

    Anyway, having established I'm not missing some "Add Vector2D plugin", I'm going to try different approaches to solving the problem and will post back here if I find anything useful to share. Thanks again.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Hi, Construct2 noob here (only been playing with it a week but very impressed by the possibilites, so thanks!)

    I'm trying to implement sprite movement that involves resolving various forces that are represented as 2d vectors. As an example, think of the classic BOIDs flocking example (http://www.red3d.com/cwr/boids/), in which the movement of each object is influenced by combining forces reflecting desire for alignment, cohesion, and separation.

    To do this, I'd like to be able to assign arbitrary vector variables to an instance and then perform standard functions on those vectors (addition, multiplication, normalisation, dot and cross products etc.) in order to calculate the appropriate acceleration to apply. However, it doesn't seem possible to assign or manipulate vectors - the only types of instance variables available are Boolean, Text, and Number (and I really don't want to have to separate out my vectors into separate X and Y components...)

    I see that the Custom Movement behaviour exposes properties such as dx/dy, acceleration, and Angle etc., which means I guess that Construct 2 must already have a 2d vector library internally that has all these functions, but am I correct in saying that it's not exposed anywhere else?

    What would be the best way to implement this? A plugin? (has anybody already done one?)

    Any advice would be gratefully received!