# a Beginners "way to know where"

This forum is currently in read-only mode.
0 Favourites
• 11 posts
• This is the .cap we start off with.

Lets move the black square with the arrow keys, and keep it between the walls.

There is a very nice behavior to do this.

(I freely assume that you walked trough all this )

From out the layout editor, select the black square (Box), and it give the "8 direction" behavior.

You can keep the initial values in the behavior's properties for now.

Run all ..

and yes it moves, very nice even. But it will go trough the walls.

To keep the Box from intruding the walls, we must tell the physics system in the "8 direction" behavior that the walls are Solid objects.

Select any wall object (i did not give them names since we are not gonna use any event, sorry ?) .

So select any wall object,

uncollaps the "groups" properties,

uncollaps the "attributes' properties under "groups"

toggle the "solid" properties

Since all wall objects are an instance of the same object. They all will be set "solid"

Run all ..

Perfect. This runs very nice. Even when we make the "play field" a little more complicated.

Make the grid 40 by 40.

Toggle the grid to make it snap.

Copy one of the wall objects, and place a copy at

x = 120

y = 120

The Grid is a big help in doing this.

Place another copy at

x = 520

y = 120

Scale the Square to 40 by 40 in its common properties.

Run all

Perfect.

Even if we make the Box non-square, by scaling it to 20 by 40.

The behavior will behave perfect.

This is a very well made behavior.

Assuming that the box is really free to walk and go where it pleases to go.

There are many games though, like pac-man, where the moving sprite needs to be aligned on certain horizontal and vertical lines.

Our box just moves where ever it can move.

But that is for later.

• Here is the starting .cap

Lets forget the Square and bring in a real animated Sprite.

You can see this when u select the Car thingy, and bring up "Animator" in the right Organizer Pane.

There Is One animation. With 4 sub animations, for each 90� angle of the object 1 sub animation.

When the object rotates, it will automatically play the right animation corresponding with its angle.

So add a "8 direction" behavior to the car thingy.

The walls are set "solid" already.

Run all.

Looks nice, but there are some culprits.

The car will go stuck in the bottom corners, and sometimes stick to the top edge.

From the last post we know that the behavior goes very well with Box shaped sprites.

Even when they are not square like our little car is.

Must have to do with the the way our car is sensing the walls.

Select the car, and change its collision method properties from "per pixel" to "Bounding Box"

Per pixel = every outer pixel will sense if it collides with a solid.

Setting this Method on "Bounding box", will use the the pixels that make up the bounding box of the sprite to sense collision with solids.

The bounding box has also the simple straight forward shape of the Box we used in previous post.

To see the bounding box, select the car in the layout, and there will be drawn a square around the sprite. Thats the bounding box.

Now its works perfect again.

Although, the way the car moves when bounded by the upper wall is silly. The head of the beast should move a few pixels over the wall. To have at least a little 3d feeling.

To do this, we need to make the bounding box smaller then the Sprite. But at the moment that is impossible in Construct.

There is no option to add "collision masks" to a sprite yet also. (version .95.3)

What now ? Stop using construct and wait till those things will be added ?

Nopes, no way.

The solutions is quite simple, and you will use it a LOT. Personal, for me there is no need to add "collision masks" to the program.

Lets get it going.

• ## Try Construct 3

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

Construct 3 users don't see these ads
• Starting .cap is here.

The duck has a "8 direction" behaviour already.

Run all

Move the Duck with the Arrow Keys.

But, oh man, thats a totally drunk Duck.

Suppose we want its movement aligned with the grid for this maze ?

Huh ?

Lets move the paper roll aligned to the maze's grid in a quick event, to show you.

Give the Paper object a Bullet Behavior.

Be care full to not move the Paper,

if you accidental did, then move it back by giving it x = 480 and y = 400 in its common properties.

Notice the Green Box objects, named h1... h4.

They are placed strategical on points where the Paper will change direction.

There angles are according the direction the Paper will change to.

And look under the Group properties, and deeper the Families properties.

They have been given a family name Yellow.

You can give a group of objects a Family name, to call them by there family in the events.

Go to the Events Editor.

Add a system flow event "always"

Add a sub event to this ..

step1: object = Paper

step2: condition = Is overlapping another object

step3: parameters: Choose Yellow as object.

finish

Yellow is the family name we call all the h1 ...h4 objects with.

step1: self = Paper

Step2: action = set angle

Step3: parameters: Yellow.angle

finish

Run All

That paper has a nice move.

And our duck is still drunk.

This is then the limit of the "8 directions" ?

Ahhhhh, not yet. But yes almost.

Go back to the layout Editor.

Edit its grid to 80 by 80.

Click Toggle grid to make objects snap to the grid.

Select the most Bottom layer.

Add a box object. Name it Sensor

Give it height and a width of 80

place it somewhere on the grid, but not on a wall, and not in the middle.

The grid will snap it to a good place.

You can change its color and looks, but the initial values are ok for me

Delete the "8 directions" behavior on the Duck

Give Sensor an "8 directions" behavior.

Go to the Events Editor

Add a system "Always" flow condition.

Add a sub event with a system "always" condition.

Ad an action to this sub event.

Step1: self = duck

step2: action = set position to another object

step3: parameters : choose the object Sensor

finish

Run all.

Nice !

Although, The Duck is still drunk by 1 pixel.

And Because you see the Sensor, it is easy to move the duck, because your eye is using it as a guide.

Go to the layout editor.

Select the Sensor,

Try to find its "set invisible" properties.

Uhh, i dont know myself where it is. But

Go to the Events editor.

Make a new Event from the System "Start of layout" condition

Add a action to this sub event.

Step1: self = Sensor

Step2: Action = Set visible

Step3: parameter = Invisible

finish

Move the "Start of layout" events on top of the events sheet.

Run all

Move the duck Around a while, and notice that its a little more difficult to push it around the corners.

Also, and this is the end of the "8 directions" behavior.

What if i want the duck to move in the maze but only in one direction ? With no Returns?

What if i want the duck keep moving and let the player only alter its direction?

Its the limit of the "8 directions".

BUT it is the Born of the sensor principle. You just made your first Sensor.

And believe me, once its born, it sticks on you.

• There is also a General Lesson to learn out of this.

Collision detection or overlap detection by events is limited to the moment in time they "tick".

And, on top, they are limited to Pixel coordinates.

To refresh.

The game runs 1 tick if it completed the whole events sheet 1 time. The time it takes to run 1 tick is of course depending on the speed of your computer and graphics card. But it will never be zero.

Lets assume an event sheet that runs 3 times a minute on your computer. (the slowest computer ever made) Lets assume the events sheet has 5 events.

Then one event runs every 20 seconds. (it ticks every 20 seconds) And lets assume the actions take 2 seconds to do there thing.

If this event is made out of an Collision detection condition, then the detection will be done Every 20 seconds during 2 seconds.

In other words, there will be no detection for 18 seconds, the remaining time the other events are ticking.

<img src="http://usera.imagecave.com/j0h/tick/timeFrame.jpg">

Thats 1 grid the events run in. Yes it is a time grid. Detections only get made when the event "ticks".

The other grid events run in are the Pixels. They are always Round. Events dont know a X position of 200,457. Place an object at 200,457 in an event and it will be placed at 200.

And the dimensions of 1 pixel is not zero. There dimensions depend on how big your screen is.

If the resolution of your screen is 1440 by 900, and your screen is 40 cm, then one pixel is 40 cm / 1440 = 0,3 mm / or 0.0118110236 inch. And that is not zero.

So events are limited by a time grid and by a position grid.

Behaviors do not have this limits at all.

In other words, an object moved by a behaviour ...

Who's position has to be tracked by an event, ..

Will a lot of time not be on the time grid that the event is checking on ..

and also not on the pixel grid the event is checking on.

Behaviors and Events RUN OUT OF SYNC.

There is a speed where the events always will pick the object moved by a behaviour.

How faster OR slower then this speed the object moves, how less chance the events have to pick it up.

To see this in action.

Scale the h1 ... h4 objects to 1 or even 2 pixels.

Place them on the grid in the corners

and run all.

there, thats all for this second.

• Lets Give the way of using a sensor in my last post a name.

And lets call it The Zombie Sensor.

It works, but it is not really aware, and the AI is brought by the player hitting the arrow keys.

Its a zombie sensor.

The next sensor i bring to you i call The Ghost Sensor.

(Nope Ashley, you can not upload in a reply, and i seem to annoy people when starting new posts)

The base for the Ghost Sensor is no more then just a copy of how the behaviors keep objects from intruding solids. So basically we just code our own behavior. But since we will have more control, we are not limited to only "solids".

Behaviors do this:

They memorize the objects position,

then they move the object,

then they check if the moved object is overlapping a solid,

if thats not true, they keep the new position of the object,

If there is indeed an overlapping with a solid, they will move the object back to the memorized position.

And this way, whatever shape the sprite has, the object will never be able to intrude a solid sprite.

This we can do ourself in Events. And even very simple.

So take up the starting layout, available in download on top of this post.

Since we not gonna use a "8 directions", we will need the mouse&keyboard object to code our own key related movements.

Add a new object to the layout, choose the mouse&keyboard object to add.

Go to the Events Editor.

There is already a "Start layout" event, let it just be there.

step1: object = mousekeyboard

step2: condition = on key is down

step3: parameters = Up Arrow

finish

step1: self = Sensor

step2: action = Set value

step3: parameters: add a new private variable "sX" / set the value to 0 (zero)

finish

step1: self = Sensor

step2: action = Set value

step3: parameters: add a new private variable "sY" / set the value to -2 (negative one)

Copy the this whole event tree 3 times.

Change the key's to right arrow, down arrow and left arrow. Change the values in the actions to.

for right arrow

sX = 2

sY= 0

for down arrow

sX = 0

sY = 2

for left arrow

sX= -2

sY= 0

When done with that, add a new event from the system flow "always"

add a sub event to this from the system flow "always"

where u set the object Sensor to "its self position" + "the private variables sX and sY"

You should know how to do this by now.

You can run it at this moment, to check up.

Temporal "invert the condition" that hides the Sensor in the "start layout" event.

add a second sub event to the top "always" of this event tree.

Make a collision that detects overlapping between the object Wall and the object Sensor.

Add an action to this that positions the Sensor to the DVD

(oh i forgot to rename the wall object to Wall, well then you do that)

Copy that event. And invert the condition.

Change the action in the copy to position the DVD to the Sensor.

Run all.

Thats all for the Ghost Sensor.

Its difficult to move the DVD into the middle maze ? Ah yes to do that it needs little adjustments.

But this type of Sensor, we will mostly use for objects moved by the computer.

So yes, this is the base for the Ghost Sensor.

The Events sheet should look like this.

<img src="http://usera.imagecave.com/j0h/tick/99_result.jpg">

note for Ashley: as you can see in my uploads i had to start this .cap over.

Is there a bug in saving a .cap under another name ? Making them corrupt ?

• I introduced you to the Zombie sensor, to the Ghost sensor,

next is the Octopus sensor.

<img src="http://www.rijnvos.nl/foto/octopus.jpg">

It dont look scary ! at all. So relax. Its simple too.

An octopus will reach out its tentacles and sense its environment.

But we need a point to attach the different tentacles.

Thats why here a brief tutorial on how to make Image Points.

Its in this .cap. Just run it.

http://www.mediafire.com/?lutyjtg4jby

One day Ashley will give us the condition "on Collision on image point (x)",

till then we will go with attaching tentacle sensors to image points.

But thats is for next post.

• here is the .cap that i will use as starting layout in the next post.

First notice The DOUBLE grid in the maze.

The octopus object is 40 by 40.

And moving it around in the layout shows that the maze has a 40 grid.

But now.

Set the layouts grid on 32 by 32.

Click the "toggle grid" to make it objects snap.

And you notice that the objects that make up the grid are place on a 32 by 32 grid.

This makes the ghost that we gonna move over the grid also move by a 32 by 32 grid.

40 is bigger then 32. This on purpose. It will allow us to use Overlap detections,

This gives us more control, and closer to black and white decisions.

The sensors will never be on a place where 1 pixel can make the difference between the object being stuck or moving fine.

You should always use the Box object as sensor. Because it is a very fast detection object. But this will make the .cap in this *tutorial* less readable. This .cap dont need to be fast. It needs to be illustrative. Thats why there are 4 sprites U, R, D and L.

But that will be clear at the end of all this.

If i am able to finish this today.

• This is the second time that i write all this. Why ?

Well i did yesterday, but then, while writing, i asked myself,

can i do this without sensors in the form of objects.

And the answer is yes. We can. Realizing this i closed it all out without posting.

But then, i hate to leave unfinished things behind. Thats my dads fault. He taught me. Finish what you started.

Now i have to add a post explaining how to do this all without sensors in the form of objects.

But i better finish this first. Its more *visual* and easier to explain, and easier to make the bridge to not using objects anyway.

So here goes. Pick up the last cap that i posted as start layout.

I skinned this layout down from another project that i worked on. I noticed i forgot to clean up some things. Like the global variables. Bring up the global variables, and clean all the present variables. I am sorry ?

Now explore the layout that i left you. There is a maze, and i gave some little secrets about that maze in previous post. All Members of the maze are part of the Family "Blue". You can see that in the properties. Event can call Objects by there Family name. Very handy.

There is the Ghost01, which has already a few private variables added.

There is the Octopus that we will move. Add 2 Private variables to it.

Xstep, number, 0

Ystep, number, 0

There are 4 objects: U, R, D and L.

Scale them to 12 by 12.

Change there collision methods to bounding

Add 4 image points to the Octopus. Instructions how to in a previous post.

Name them U, R, D and L. Use respectively the 8, 6, 2 and 1 keys on your numeric to positions the points.

Go to the events editor. First we snap the sensors to the Octopus. Giving the beast tentacles.

Add a System: Start of layout condition to the empty sheet. Thats easier now then later.

For me the events sheet looks weird without one. It marks for me the start of a sheet.

Add a system : always condition.

Add a sub condition system: always.

(as i explained earlier, the first always we will replace with a flow condition, once we build this module in a complete game))

add 4 actions to this sub event

U Set position to object 0ctopus 0 (image point "U")

R Set position to object 0ctopus 0 (image point "R")

D Set position to object 0ctopus 0 (image point "D")

L Set position to object 0ctopus 0 (image point "L")

As you can see. Although we dont use the sprites of the objects in the game, they will go invisible,

good thumbnails extracted from those sprites make the events very readable.

You can run this to check if you snapped up to up, right to right and so on.

Next event will move the Octopus.

Add another "always" sub to an "always" event to the sheet.

add 2 actions to the sub "always"

0ctopus Set X to .X + 0ctopus.Value('Xstep')

0ctopus Set Y to .Y + 0ctopus.Value('Ystep')

It is not moving yet, but it will do so soon.

There will be no key inputs. The Ghost01 has to move all by itself.

First we do the Overlap detections, to sense if the Octopus can go in a certain direction ...

or that there is a wall sitting in the way.

We can call all the wall objects by the Family name "Blue"

We also need a way to memorize the results. In a next step we will partly randomly choose a direction, partly force a direction not blocked by a wall. I will use a String for that, and at same time introduce basic string operations.

Add a sub event containing an "always" to the last event.

First we will reset the string.

The action will be:

Ghost01 Set 'Possible_Ways' to ""

Possible_ways is a private variable carried by Ghost01. "" stands for an empty string.

Now lets find out all "Possible_ways" the Octopus can go.

If object U overlaps Blue, then that way (upwards) the Octopus can not go.

But we need the the directions that it CAN go. Just invert the Overlap Conditions.

Add a second sub event with the condition

U overlaps Blue (inverted)

Ghost01 Set 'Possible_Ways' to Ghost01.Value('Possible_Ways') + "U"

(set value)

Copy this sub tree for R, D and L. And change objects in the conditions, and the strings in the actions.

U: overlaps Blue (inverted)

Ghost01Set 'Possible_Ways' to Ghost01.Value('Possible_Ways') + "U"

R: overlaps Blue (inverted)

Ghost01Set 'Possible_Ways' to Ghost01.Value('Possible_Ways') + "R"

D: overlaps Blue (inverted)

Ghost01Set 'Possible_Ways' to Ghost01.Value('Possible_Ways') + "D"

L: overlaps Blue (inverted)

Ghost01Set 'Possible_Ways' to Ghost01.Value('Possible_Ways') + "L"

What is all this doing ?

It resets the variable Ghost01.Value('Possible_Ways')

then it will add the letter "U" to the variable, which stands for upwards, if that direction is free from walls.

Same for R, D and L.

In other words, if there are no walls in the Left and Right directions, the variable Ghost01.Value('Possible_Ways') will hold the value "RL"

Note that you can, due the way we build the events structure, easily collapse every starting "always". Or invert it to keep it from running for debugging purpose. There is a "toggle event" in the ribbon, but for me inverting an "always" is easier, because there as contextual menu.

Al we have to do now is to decide which of the two possible directions we will go.

We will do this in a few conditions. But first lest make a 2 Global flow variables to guide those conditions.

Skip, numeric, 0

So_Many, numeric, 0

Make a new "always" event.

Add a sub "always' to it. Add an action to it to reset the variable Skip.

System: Always

System Set global variable 'Skip' to 0

Add another action to set the variable So_Many to the length of the variable Ghost01.Value('Possible_Ways')

System: Always

System Set global variable 'Skip' to 0

System Set global variable 'So_Many' to len(Ghost01 0 .Value('Possible_Ways'))

The length of 'Possible_Ways' is holding important info for us.

When the length = 1, then there is only 1 way to go, thats the way we have to let it go.

When the length = 2, and the way we are already going is still a possible way, then we will prefer to keep going the way we was going already.

When the length > 2, we will choose randomly, but with preferring the way it was going already, if this way is still a possible way.

This means that we also have to store the direction that we are going, before choosing another direction, in a variable. But that we do a little later in the events. Yet we will use it now.

This variable will be Current_way as private variable present in the Ghost01 object.

OK lets start this.

add a second sub event. Compare a global variable. Compare skip if its zero.

Add a second condition to this. Compare if So_many = 1

We store the actual way that we go in Ghost01's private variable Way_to_go

so the first action to this will be setting Way_to_go to Possible_Ways

the second action will tell the other conditions that we found a solutions. Its like a "dont bother, we know already".

This whole sub event looks like:

System: Is global variable 'Skip' Equal to 0

System: Is global variable 'So_Many' Equal to 1

Ghost01 Set 'Way_to_go' to Ghost01.Value('Possible_Ways')

System Set global variable 'Skip' to 1

You can copy this sub event tree, and just lazy edit the condition.

The comparing 'Skip' stays the same.

Comparing 'So_Many' will be against 2.

Add another condition to find out if the direction we are already moving is still possible.

To do this we will use the system expression "Find in string" put into the first value of a system condition "Compare", and compared as greater then the value 0

The sub event will look like:

System: Is global variable 'Skip' Equal to 0

System: Is global variable 'So_Many' Equal to 2

System: find( Ghost01 0 .Value('Possible_Ways'), Ghost01 1 .Value('Current_way')) Greater than 0

Find(string, string to find) , returns the position of the string we are looking in the string that we are researching. It will return a value higher then zero, if the string is found.

In our case, when the direction that we are going (Current_way) is present in the open ways string ('Possible_Ways'), then thats still the direction to move.

So the action will be, set the Way_we_go to Current_way,

and set skip to 1 because this is what we decided to do under those conditions.

the total event tree looks like this.

System: Is global variable 'Skip' Equal to 0

System: Is global variable 'So_Many' Equal to 2

System: find( Ghost01.Value('Possible_Ways'), Ghost01.Value('Current_way')) Greater than 0

Ghost01,Set 'Way_to_go' to Ghost01 0 .Value('Current_way')

System Set global variable 'Skip' to 1

You can copy this tree to lazy edit it.

the Skip condition stays.

So_many we compare against > 2

The find condition stays.

the action will add Current_way to Possible ways. In other words. This directions will be twice in the whole string. So when we randomly choose from the available directions , this direction has more chance to be chosen. At same time we update So_many to the new lenght.

Skip will not be changed.

Whole tree looks like.

System: Is global variable 'Skip' Equal to 0

System: Is global variable 'So_Many' Greater than 2

System: find( Ghost01.Value('Possible_Ways'), Ghost01.Value('Current_way')) Greater than 0

Ghost01Set 'Possible_Ways' to Ghost01.Value('Possible_Ways') + Ghost01.Value('Current_way')

SystemSet global variable 'So_Many' to len(Ghost01 0 .Value('Possible_Ways'))

You can copy this tree to lazy edit.

But all we keep in the conditions is the skip condition.

meaning, if there is no solution yet, lets randomly choose.

We will use the system expression "get middle substring"

as mid(String, Start, Count)

string in this = Possible_ways

start = random (the length) + 1 .. because random in construct starts from zero

Count = 1

mid( Ghost01.Value('Possible_Ways'),

random(global('So_Many')) + 1

,1)

this tree looks like:

System: Is global variable 'Skip' Equal to 0

Ghost01Set 'Way_to_go' to mid(Ghost01.Value('Possible_Ways'), random(global('So_Many')) + 1 ,1)

This is the final decision, so we will also set Current_Way to the same direction. Add a sub "always"

System: Always

Ghost01Set 'Current_way' to Ghost01 0 .Value('Way_to_go')

Now we covered all possible Direction changes. Our little Ghost starts to look smart.

Now all we have to do is translate U, R, D and L in to X and Y values.

Add a totally new "Always" event.

Add a sub event to this, compare the "Way_to_go" to the "U", and set the Xstep and Ystep variables according.

Add 3 sub events for the other directions.

This tree looks like:

System: Always

Ghost01: 24 Value 'Way_to_go' Equal to "U"

0ctopusSet 'Xstep' to 0

0ctopusSet 'Ystep' to -2

Ghost01: 24 Value 'Way_to_go' Equal to "R"

0ctopusSet 'Xstep' to 2

0ctopusSet 'Ystep' to 0

Ghost01: 24 Value 'Way_to_go' Equal to "D"

0ctopusSet 'Xstep' to 0

0ctopusSet 'Ystep' to 2

Ghost01: 24 Value 'Way_to_go' Equal to "L"

0ctopusSet 'Xstep' to -2

0ctopusSet 'Ystep' to 0

Now all we have to do is limit the Direction changes to the grid.

Locate the base "always" of the event that changes the directions. (should be line 12)

and change the always to a condition that checks if Octopus X is on the grid.

add a condition that checks if Octopus Y is on the grid.

Event will look like this:

System: 0ctopus 0 .X Equal to (round(0ctopus 1 .X /32)) * 32

System: 0ctopus 0 .Y Equal to (round(0ctopus 1 .Y /32)) * 32

The grid it has to move on is 32.

Round will round a number to the nearest integer, like 2,2 will be 2 and 2,7 will be 3

All points on the grid you can divide by 32 and the result will be an interger.

Now set the position of Gost01 to Octopus, up to you to choose where in the events.

The Whole events sheet looks Very simple when collapsed. Add some comments, and its very readable. Very Clean and logic too.

<img src="http://usera.imagecave.com/j0h/octupus/01limit.jpg">

Uncollapsed it looks.

<img src="http://usera.imagecave.com/j0h/octupus/02limit.jpg">

<img src="http://usera.imagecave.com/j0h/octupus/03limit.jpg">

<img src="http://usera.imagecave.com/j0h/octupus/04limit.jpg">

This method is very visual, very friendly to debug.

But i am sure not the most CPU friendly aproach.

Of course you will set the sensors invisible, and also mister Octopus.

But still.

Next post a small adjustment to do it without actual objects as sensors.

• Now look back at the events 8, 9, 10 and 11. Where we sense by overlap conditions.

Lets change those. First browser a second in the system objects conditions.

And notice the "Object overlaps point" condition. This is what we gonna use.

No more setting image points too. But its good that you know how to set those. And how to use those. So do not forget that.

ok .. double click the U overlaps Blue condition to change it.

Click back till you are in step1 of the wizard.

Step1: base object = system object.

Step2: condition = "Object overlaps point"

Step3: parameters : the object = Blue (the family we call the walls with)

now X will be an expression. We will point to the x where we positioned the Sensors in last post.

But Where is the X coordinate of the sensor ? without using the sensor ?

Well, the maze is a 40 by 40 grid. Our octopus is in the middle of that grid. So the distance from a maze edge to the Octopus middle point (its X and Y point) is half the 40. Simply 20.

Lets Add 2 pixels to have a save and never failing Overlap Detection.

So X for the up "sensor" = Octopus.X

and Y is Octopus.Y - 22

there ! The sensor objects are eliminated by this. But you need more imagination to see whats happening, and even more to debug if you run into problems.

But, its certainly faster and more CPU friendly.

so ...

point x gets the value Octopus.X

point y gets the value Octopus.Y -22

click finish.

do the same for R overlaps blue.

Xpoint in the parameters is now Octopus.X + 22

Ypoint = Octopus.Y

For D this will be

Xpoint = Octopus.X

Ypoint = Octopus.Y + 22

For L this will be

Xpoint = Octopus.X - 22

Ypoint = Octopus.Y

Now go to the layout editor.

Delete the objects U, R D and L

they will be deleted from the events sheet too

meaning, you will have a few empty always events.

You can delete those.

And run all.

NEVER DELETE OBJECTS BEFORE YOU CHANGED THE EVENTS !!

(hope daddy smiles after this post)

• To align the animation of the Ghost with the direction its moving.

Just add an action that sets the animation to the variable 'way_to_go'.

And just between the lines, notice that you can move every tree of events, well those that start with a "always" base, on any place in the events sheet.

It should not matter.

• tags: sensors c0nstuct

(just for me to find my *tuts* back)