[TUTORIAL] OR'ing events

Post your own tutorials, guides and demos.

Post » Fri Jun 15, 2012 7:15 pm

Using 'OR' to combine conditions can cause problems. To avoid them, you need to find a way to compare logically without using 'OR'. There is a way, and it is the system object's evaluate condition.

Instead of one event with 3 conditions, like so:
+ System: Is global variable 'keyDown' Equal to 0
+ System: OR
+ System: Is global variable 'keyDown' Equal to 2

You'd use the evaluate condition, like so:
+ System: global('keyDown') = 0 Or global('keyDown') = 2

That looks great, and it works, too. But what to do, if you need to 'or' triggers? You can't access them in expressions. But you can do an intermediate step to convert a trigger to a variable.

+ System: Always (every tick)
-> System: Set global variable 'keyDown' to 0

+ MouseKeyboard: Key Right arrow is down
-> System: Set global variable 'keyDown' to 1

+ MouseKeyboard: Key Left arrow is down
-> System: Add 1 to global variable 'keyDown'

+ System: global('keyDown') = 0 Or global('keyDown') = 2
-> do something, when both or no keys are down

The logic behind this example is that on every tick 'keyDown' is first reset to 0, then set to 1, if the right arrow key is down. After that, 1 is added to 'keyDown', if the left arrow key is down. Here are the sequences of setting 'keyDown' before it is or'ed:

left and right both not down:
0, 0, 0 -> 'keyDown' = 0
left is down, right is not down:
0, 0, 0+1 -> 'keyDown' = 1
right is down, left is not down:
0, 1, 1 -> 'keyDown' = 1
right is down, left is down:
0, 1, 1+1 -> 'keyDown' = 2

The last step now compares if either one of 'keyDown' = 0 or 'keyDown' = 2 is true (which stands for either no key or both keys down) and gets executed only, if it evaluates to true.

You can do this or any similar way (you might prefer working with dedicated variables per trigger), wherever you need to 'or' conditions.



Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Fri Jun 15, 2012 7:26 pm

Thanks you for that. Is the "or" function in general a bit bugged, or only if you use it wrong?
B
24
S
9
G
2
Posts: 294
Reputation: 3,160

Post » Fri Jun 15, 2012 7:36 pm

Nice example.
For the mouse & keyboard object you could go without the variable if you use control states.
MouseKeyboard.ControlState("", 1)
That will return 1 or 0. Useful in this particular situation.
Quotes are the named control, and 1 is the player.

Image Image
B
161
S
48
G
89
Posts: 7,347
Reputation: 66,249

Post » Fri Jun 15, 2012 7:50 pm

[QUOTE=zyblade] Thanks you for that. Is the "or" function in general a bit bugged, or only if you use it wrong?[/QUOTE] Well, it does not work as it should, so I'd say in general.
Basically it is a time issue. Here is a description of how to get 'OR' working, or why it does not work correctly:

http://www.scirra.com/forum/why-using-or-seems-to-fail-often_topic40925.html
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Fri Jun 15, 2012 7:54 pm

Good, I will consider that in my current/future projects^^
B
24
S
9
G
2
Posts: 294
Reputation: 3,160

Post » Sat Jun 23, 2012 3:48 pm

I want to share some general thoughts about logical operations. In conjunction with the translation of triggers to variables, it can greatly add to your event sheets being well arranged while covering even difficult parts.

A logical or is not the same as in our language. If we say "red or blue" we really mean "either red or blue". But a logical or means "any of the conditions", even if both are true. This seems to not make a huge difference, but think about a real world example. Let's say, we want a shirt in "red or blue". We look around the shop and if a shirt is either red or blue, we try it. But with a logical or we would also look for a blue and red striped shirt.
Consequence: A logical or evaluates to false only if both conditions are false (if there are no red shirts, no blue shierts and no red and blue striped shirts, in the real world example)

There are situations, where you would need a logical or that behaves like "either a or b", to make it exclusive. That's called a logical exclusive or (XOR). Construct does not provide this, but you can do it with a combination of AND plus OR.

(global('a') = 1 AND global('b') = 0) OR (global('b') = 1 AND global('a') = 0)

it would exclusively be only true if either a = 1 or b = 1, but not when both = 1 or both = 0. Take care of the brackets, btw, they show Construct that you first want to logically operate both ANDs and then operate on those results.

This works because AND only results to true if both conditions are true. Let us have a look at how the cpu sees such an evaluation.

a = 0, b = 0 given:
(global('a') = 1 AND global('b') = 0) OR (global('b') = 1 AND global('a') = 0)
(FALSE AND TRUE) OR (FALSE AND TRUE) => FALSE OR FALSE => FALSE

a = 1, b = 0 given:
(global('a') = 1 AND global('b') = 0) OR (global('b') = 1 AND global('a') = 0)
(TRUE AND TRUE) OR (FALSE AND FALSE) => TRUE OR FALSE => TRUE

a = 1, b = 1 given:
(global('a') = 1 AND global('b') = 0) OR (global('b') = 1 AND global('a') = 0)
(TRUE AND FALSE) OR (TRUE AND FALSE) => FALSE OR FALSE => FALSE

a = 0, b = 1 given:
(global('a') = 1 AND global('b') = 0) OR (global('b') = 1 AND global('a') = 0)
(FALSE AND FALSE) OR (TRUE AND TRUE) => FALSE OR TRUE => TRUE

Another logical operation is NOT, which reverses to the opposite, so that TRUE Becomes FALSE and FALSE becmes TRUE. By decribing this, you may already notice that Construct does provide this only for complete conditions in the form of "invert condition". If you do this to the example above, it will exclusively become true if either both = 0, or both = 1.

[inverted](global('a') = 1 AND global('b') = 0) OR (global('b') = 1 AND global('a') = 0)

is the same as

(global('a') = 0 AND global('b') = 0) OR (global('b') = 1 AND global('a') = 1)

End of lesson ;)
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242


Return to Your tutorials & example files

Who is online

Users browsing this forum: No registered users and 0 guests