Tip: Using simple math for toggling (random) direction

Consider this scenario: you have an arrow sprite that can point left or right. You often need to switch it from left to right (e.g. after an object collides with it), so you give it a variable ‘direction’ which is either ‘left’ or ‘right’. Here’s what the switching code might look like:

Condition: Object collides with Arrow
Action:
  Condition: Variable 'direction' of Arrow is = 'left'
  Action: Do 'right' to variable 'direction' of Arrow
  Condition: Variable 'direction' of Arrow is = 'right'
  Action: Do 'left' to variable 'direction' of Arrow

You also want to give the arrow a random direction when it’s first created. Here’s how that might look:

Condition: At the beginning of the scene
Action: Do = Random(1) to scene variable initial_direction
  Condition: Scene variable 'initial_direction' is = 0
  Action: Do 'left' to variable 'direction' of Arrow
  Condition: Scene variable 'initial_direction' is = 1
  Action: Do 'right' to variable 'direction' of Arrow

Now that code (should) work, but it’s cumbersome and repetitive. Here’s what I believe is a simpler solution…

Use integers for left and right; -1 being left and 1 being right. When you want to switch direction, simply multiply the current direction by -1. Example: if the arrow is facing left (-1), when you multiply by -1 you get 1 (right). And if the arrow is facing right (1), when you multiply by -1 you get -1 (left). This also has the benefit of matching the x and y coordinate system GDevelop uses (so it’s easy to make objects move in the given direction just by multiplying the direction integer by an amount (negative amounts move left and positive amounts move right (the same can be used for up and down too!)))

As for choosing an initial direction randomly, you can’t just do RandomInRange(-1, 1) as 33.33% of the time you’ll get 0 (and then have to re-calculate the random value and that just adds more code). Instead, use (Random(1) * 2) - 1 That gives a random number (0 or 1, with a 50/50 chance of either), which you then multiply by 2 (so 0 stays 0 and 1 becomes 2), and then you subtract 1 (so 0 becomes -1 and 2 becomes 1).

Using these ideas, here’s how the above code can be simplified:

Condition: Object collides with Arrow
Action: Do *-1 to variable 'direction' of Arrow
Condition: At the beginning of the scene
Action: Do = (Random(1) * 2) - 1 to variable 'direction' of Arrow

I love finding elegant solutions to problems, so thought to share this in the hope that it helps someone else too :smiley:

1 Like

Nice, I love tricks!
Can you check if RandomWithSteps(-1, 1, 2) doesn’t give you - 1 or 1 too?
Another one is pow(-1, Random(1)), because -1^1 = -1 and -1^0 = 1 :slight_smile:
But no doubt that your way is the best, a similar calculation is used a lot in shaders programming to convert from a color range [0, 1] to vector range [-1, 1] :wink:

In a side note: wow, three nested parenthesis… like a math formula :smiley:

Happy to share :slight_smile:

I didn’t know about RandomWithStep(-1, 1, 2) but looked it up in the wiki (note that there’s no ‘s’ on the end), and that does certainly work! I think it might be better than mine; at least it looks simpler and easier to understand (especially considering it’s just using one documented function without other math involved).

pow(-1, Random(1)) also works, however I couldn’t find it documented anywhere… Speaking of which, is there a list somewhere of all functions available in GDevelop? Or is that a function from whatever language GDevelop uses under the hood (which is C++ or Javascript)?

I’ve attached an example that shows each method outputting -1 or 1 (use the debugger to see output).

Yes, I do love maths, and being a web developer/programmer I’m used to making sure all nested parentheses are properly closed :wink:
game.json.zip (1.43 KB)

Funny fact: I added all the random functions to GD except the basic Random one, but misspell the name, forget I wrote the wiki article too, and I’m asking an user to recheck its working properly instead doing it myself :smiley:

Are not in the list when you press the sigma (summation) button?
Press that button when writing an expression, there will be a search bar, search for “pow”, if nothing shows up then it’s missing :neutral_face:

No worries, I don’t mind learning :slight_smile:

Yes, pow() is in the sigma button list. I was referring however to some documentation like a wiki page, but that’s ok, I can search for future functions using that button.

Refer to the old wiki: http://wiki.compilgames.net/doku.php/gdevelop/documentation/manual/function_reference :slight_smile:

Thanks! I’d like to copy that to the GD5 wiki, but I can only edit pages, not create new ones. Can you create a new page for me, then I’ll copy that over?

If you visit a page on the wiki that doesn’t exist, the wiki offer you the option to create the page. Plus icon on the left.

Note that there’s an “Expressions” page that right now have the random functions only, you could (should?) add them there :slight_smile:

Thanks, done: wiki.compilgames.net/doku.php/gd … /functions
Not sure how to update the menu though…

In GD5 there is no native platform but HTML5 only, you may want to remove the expressions for the native features like 3d box…

Also I’m not sure if they should be on a page called functions since functions and expressions are not the same thing in GD functions are a type of event now :slight_smile: