How do I get enemies to change direction when hitting walls?

Just started using Construct 2? Post your questions here

Post » Wed Feb 10, 2016 6:18 pm

Message: Frisk can only post plain text URLS until they have 500 rep. 1 URLS modified. Why?
Or more clearly - "why doesn't what I'm doing work properly?" I have no idea how I'm screwing up possibly the simplest thing you can do.

https://drive.google.com/file

/d/0Bz6k_T7ICBNmdjU5b0xNTnZ1bVU

/view?usp=sharing

(Edited to split this up because it doesn't work otherwise..)

In the .capx linked are sprite enemies with a platform behaviour and a "Direction" instance variable, and a sprite called 'block' with a solid behaviour. Depending on the "Direction" of the enemy, it'll either simulate the platform behaviour to move left or right. In the events, if the enemy collides with the block and has the direction "Right", it'll set the instance variable to "Left" and simulate that movement. An identical event is there for the opposite direction. You probably worked all that out instantly just by looking at the 4 events.

Real simple stuff, right? But when the enemy collides with the block whilst moving left, it'll refuse to set itself to right. It doesn't do anything, just sits attempting to move into the block. In the debug, the "Direction" variable doesn't change at all.

I have no idea why it won't work. Everything is spelt correctly, the collision hitboxes are both just squares covering the entire sprite, and it works fine when hitting the block whilst moving right. It's like, the most basic thing in a platformer to get working, and it's seriously annoying me. I can't believe I'm making a thread here for something so simple.

If anyone could spend just 30 seconds to find the problem and tell me why I'm stupid, that'd be great!
B
7
S
1
G
1
Posts: 11
Reputation: 527

Post » Wed Feb 10, 2016 7:11 pm

I believe it's because the instant you change it from going left to right, the next event in line triggers.. While still colliding with the Brick, so it simply moves left again. (following the Event sheet top to bottom). If you flip the Direction changing events around, you'll see what I mean.

EDIT: A quick dirty fix:

Image

What I changed is fairly simple, we just need something to tell us that we've already changed direction so the next conditional event in line does not trigger.
B
5
S
1
Posts: 43
Reputation: 461

Post » Wed Feb 10, 2016 7:21 pm

There it is thats why you need triggers in construct 2 or an "or" function! :)
B
7
S
2
Posts: 56
Reputation: 583

Post » Wed Feb 10, 2016 7:24 pm

dsminor wrote:There it is thats why you need triggers in construct 2 or an "or" function! :)

I don't see how or is applicable here, since that'd still execute the same events. An ELSE function that works with any and all conditions and triggers would be nice though, and definitely useful in this case.

(Also, there is an OR block, if you have multiple conditions you can turn your block into one.)
B
5
S
1
Posts: 43
Reputation: 461

Post » Wed Feb 10, 2016 7:27 pm

or because you just want one condition triggered not both after each other.
it is like
main
sub
sub

but it should be like:
main
sub1 sub2

Anyway the variable works just fine.

(I just call it or i dont mean the construct 2 or function)

Maybe your right its more like an else chain:

if a is true than "do something" else check if b is true than "do something" else check if c is true and so on...

however its a bit offtopic here :)
B
7
S
2
Posts: 56
Reputation: 583

Post » Wed Feb 10, 2016 8:05 pm

Gumball wrote:I believe it's because the instant you change it from going left to right, the next event in line triggers.. While still colliding with the Brick, so it simply moves left again. (following the Event sheet top to bottom). If you flip the Direction changing events around, you'll see what I mean.


I understand this now, and you're correct, flipping them does have the exact same effect on the opposite direction.

A problem, though, with this:

Gumball wrote:A quick dirty fix:

Image

What I changed is fairly simple, we just need something to tell us that we've already changed direction so the next conditional event in line does not trigger.


Reading this through I'm not so sure I understand how that works.. after the "Shifted" number gets set to 1, wouldn't the events now never run because they don't meet the conditions? And if the number is also updated at the exact same time, how would this fix that original issue.

Edit: I've just copied that identically and it plays out in the exact same way.
B
7
S
1
G
1
Posts: 11
Reputation: 527

Post » Wed Feb 10, 2016 8:35 pm

Make sure it is a local variable, basically despite the fact that this is not code we're dealing with Object Oriented behaviour and scopes.

The -> Enemy On Collision with Brick event opens a new scope for the objects in question. (Thus, our current instances of Enemy and Brick) as triggers do. As long as you stay in this event (as my sub-events did) when you address the objects you're ONLY changing the ones within that scope. In code it'd more or less look as follows:

Code: Select all
internal static void OnCollision(Enemy instEnemy, Brick instBrick) {
    var Shifted = 0;
    if (instEnemy.Direction == "right" && Shifted == 0) {
        instEnemy.Direction = "left";
        Shifted = 1;
    }
    if (instEnemy.Direction == "left" && Shifted == 0) {
        instEnemy.Direction = "right";
        Shifted = 1;
    }
}


Although that might not mean much to you, I suppose. We are still staying within a scope. :) (e.g. anything surrounded by { } is a scope, and variables initialized within one are usable inside said scope and any scopes created within said scopes but not outside of the scope they were created in. When a new scope begins, new variables are initialized and the old ones are NOT re-used.) If you want to know more about how Object Oriented languages deal with scopes, I would advice you to search around a bit on google. It might be helpful.

But I digress, technical mumbo-jumbo. Basically, because I turned the conditions and variable into children of the collision trigger they only count for anything in that little block. The variable is not accessible globally, but only in that block and the conditions and actions trigger only on the items relevant to the trigger.

But instead of trying to explain scopes and programming logic (at which I stink, I can write it just fine but explaining things without writing an essay full of examples and pictures won't be easy. :P) here's the *.capx where I fixed it for you to play around with: https://www.dropbox.com/s/crrauxq4wt0bn ... .capx?dl=1

Just remember that positioning of variables, triggers, conditions and actions can be VERY important to the flow of your game.

EDIT: Come to think of it, how did you copy it? With the indentation or without it? (I'll be heading off to bed in a moment, but I imagine other folks around could help you if you get stuck on this as well. :))

(Of course you could be more efficient in code, and write something as follows:

Code: Select all
internal static void OnCollision(Enemy instEnemy, Brick instBrick) {
    instEnemy.Direction = instEnemy.Direction == "right" ? "left" : "right";
}

But unfortunately we don't have the luxury of such operators in Construct. :()
Last edited by Gumball on Wed Feb 10, 2016 8:45 pm, edited 1 time in total.
B
5
S
1
Posts: 43
Reputation: 461

Post » Wed Feb 10, 2016 8:44 pm

What he wants to say is local variables are only used in their event (and subevents below it) and reset them self every tick.
So no it will not stay at 1 and cause the event to never run again. :)
B
7
S
2
Posts: 56
Reputation: 583

Post » Wed Feb 10, 2016 8:46 pm

dsminor wrote:What he wants to say is local variables are only used in their event (and subevents below it) and reset them self every tick.
So no it will not stay at 1 and cause the event to never run again. :)

Not entirely correct, as it is not on every tick.. (Scopes! A very important concept in OO behaviour!) but that is the general idea.

And yes, I understand I turned this into a complex story right away.. But once you get what a scope does it'll make your life so much easier. (Alternatively, you could take my *.capx I posted and accept it works, and come back to the subject at a later day. I won't judge.. At least not harshly. :mrgreen: )
B
5
S
1
Posts: 43
Reputation: 461

Post » Wed Feb 10, 2016 9:26 pm

Hmm no its not on every tick ?
Isent the event triggerd ones per tick and the variable therefore reset every tick?
I cant see why and how the scope of the variable should change this.
(Maybe we have a different understanding of "scope")
B
7
S
2
Posts: 56
Reputation: 583

Next

Return to Beginner's Questions

Who is online

Users browsing this forum: No registered users and 0 guests