Yup, i was right.
A private variable is in base no more then an object properties.
All properties will return to there initial state, including the private variables,
when calling/ recalling a layout.
This means when u have to choose to use a private or a global variable,
and the value stored in the variable has to survive layout changes ...
then you can only use a global variable.
For the rest you are free, just keep in mind if you destroy an object,
you also destroy its private variables.
Me, myself, i will only use global variables when then they represent a value used
in flow condition, or indeed when they have to survive layout changes.
Concrete: If you want the score to be "global" over all layouts, you have to use a global variable.
But lets concentrate now on the private variables.
The real actor in this is "The Value".
Examples of values are: the score, lives, level, health, damage ..... etc.
The value can be a number or a text.
In order to store and retrieve those values, we need a special place that remembers them,
and a way to address them.
When we store the values in a variable belonging to an object. We call it a "private variable"
Private Variables in Construct get addressed by there object and there name.
First we need to create this special place, and that can be done in 2 ways.
Bring up the .cap with the darts i provided, or download it again from previous post.
bring yourself to the layout editor.
Select any of the darts ...
locate "Private variables" in the properties pane. Uncollapse it.
Click add to add a new one.
A window "manage private variables" will pop up.
click on the green + to add one.
name it Xstep
keep the type op op number
and let it keep the value zero.
Check on errors before you click "done"
And thats it.
Select the other darts .. and notice that they now all have this private variable added.
They are instances of the same object. If you add/delete a variable in 1 instance ...
it will be added/deleted in all instances. Handy though.
So that was the first way.
Go to the Events Editor.
Click on the "New action"
The wizard shows up.
Step1: self object = dart
Step2: action = set value (yes the actor in this is a value)
Step3: the parameters ... under "private variable" you will find a drop down menu.
Notice that Xstep is allready present.
There is also <..add new..>
just select "add new" and you get the same "manage variables" window.
make one with the name "Ystep"
and value = zero
click done and finish.
That was the second way.
Construct will not let you unneeded run from layout editor to events editor and back and forth.
For the same reason, the properties plane is visible in both editors.
Handy though ?
Ok now the dart object has 2 private variables. Xstep and Ystep
We can store a different values in each instance.
As i said before this will give a instance an identity too.
You can store by events, and you can store in the layout editor.
Go to the layout editor.
Give Ystep of the second dart in the upper row the value -1 (negative one) by changing it in the properties plane.
Give Ystep of the third dart on the bottom row the value 1 (just one)
Now lets isolate those 2 based on there private variables and do an action on them
Go to the events editor.
Delete all events in there, and all actions. There is at least the action from making the Ystep.
And maybe you have auto save on and there will be the events from last session.
Add a system flow condition "always"
Add a sub event
step1: self object = dart
step2: action = compare a private variable
step3: parameters .. Ystep as variable .. greater then as comparison .. 0 as value
we just retrieved a private variable btw
Add an action to this condition that rotates the dart by .angle + 1
(re-read previous post if you forgot how to)
Now lets save us a lot typing. And do what computers are made for. Copy and paste.
Select the sub event. (click the E-spot, member ?) The whole tree of the sub event will be selected.
Press CTRL+c, Press CTRL+v.
A copy of the sub event will appear.
And more important: Its all ready a sub event on the right place.
And on top, the action followed in the copy.
Handy no ?
Now double click the compare condition (C-spot, member ?) ..
The wizard will come up to allow you to edit the condition.
Just change the "greater then" to "less then" .. and finish.
Change the .angle + 1 in the action to .angle -1
As you see, construct has some great edit functions, but you do have to find them.
Run all, and see that we picked instances based on there private variables.
You dont feel the love for construct yet ?
OK, its time to take a dive into "expressions".
Expressions are no more then variables used in math. Like.
X + 6
Y * x
Where x and y stand for variables. Private or global. But also object properties and behavior properties.
Ashley made a document about expressions here:
But lets access expressions, and show you the ease of use.
Bring up again the .cap with the darts. Clean it from all events and actions.
Lets give the darts numbers.
Dart 1 is the top left dart. 2 is second in the same row .. 3 is next in same row .. 4 is last in same row .. 5 is first on the bottom row .. 6 is next in bottom row . and so on ..
Give the private variables Xstep and Ystep for each numbered dart the follow values.
Xstep = -1
Xstep = 0
Ystep = -1
Xstep = 1
Ystep = 0
Ystep = 1
Ah yes, it also an exercise in selecting, locating, getting along with the properties pane. Sorry ?
Select any dart, so its properties plane is displayed.
Now go to the events editor.
Make sure its empty.
Add a sub event "always"
add an action to the sub event ..
Step1: dart = the self object
Step2: as action choose "set X"
Step3: take a look at the parameter window ..
And especially the lower part, where the objects are listed again.
Click in the X field (thats where we want the expression to appear)
Double click dart in that list and a whole new world of expressions will open itself to you.
Full with properties and variables that you can access and use.
look for the "private variable" entry.
double click "get private variable", the expressions guide will disappear ...
and in the parameters (the step3 in the action wizard) will come back.
This time filled in with the expression.
dart.Value('Variable name') ???
Yes thats the call to a private variable. As i said, private variables get called with there object and name.
the name you can still find on the left plane.
I asked u to select any dart before opening the events editor.
every little help is welcom.
So fill in its name .. and leave the ''s
( "uhhh"= a string, 'uhhh'= a variable)
so yo get
Construct will not allow you to make an error here, if you just give good names, it should be easy.
Now copy the action by CTRL dragging it under itself. A black line will mark its future position.
Double click the copied action.
The action wizard will come up allowing you to change the action.
As you see, we always land in step3 of the wizard, the window with the arguments.
But, we want to keep the arguments, partly, but change the action to "set Y" instead of "set X".
Just click "back"
Now we are in step 2 ...
As action choose "set Y"
click next ..
The expression will be still there.
Another perfect editing option offered by construct.
Just change the Xstep to Ystep in the expression .. and click finish.
Run all ...
And look what we did with just 2 actions using an expression.
Nice eh ?
And here i sneaked in another basic movement.
Animate X and Y values of an object over time by setting them in events : )
next post is briefly about Global variables ... and then we will make a simple game to bring in practice what we learned so far.
Global variables are pretty the same as private variables.
Only they are carried by the system object.
In base they are just a private variable of the system object.
Create a place to store global variables can also be done in two ways.
Make a new Direct X game. We do not need any objects to show global variables.
And the system object is added moment you create a new direct X game.
Click on project in the top menu.
The ribbon will change to project related buttons.
Click on the big button labeled "manage variables" ..
And from there its the same as "private variables"
Add a system flow condition.
step1: base object = system
step2: condition = compare global variable
step3: the parameters = pretty the same as private variables
a global variable is the same as doing so with a private variable.
The only difference is that you start any action or event with the system object.
Since the system object is holding the Global variables.
Sprites that i will use in the next post.
I will not finish this today, its almost bed time.
But lets give it a start.
Making a game starts with planning it. We gonna make a simple Snake game.
Make a new direct X game.
Goto to events editor.
1/ Add a system flow event "start of layout"
2/ right click on an empty space, and add "insert comment" from the contextual menu.
type "keyboard input" in the comment
3/ Add a system flow event "always"
4/ Add a comment "move head"
5/ CTRL drag the first always to copy it at the end of the events. Be carefully to not make it a sub event of the comment !
5/ Add a comment "move body"
6/ copy an always
7/ add a comment "eat"
8/ copy an always
9/ add a comment "grow body"
10/ copy an always
11/ add a comment "dead"
12/ copy an always
13/ add a comment "restart"
14/ copy an always
It should look like this.
I strongly advise you to plan every project this way.
Some of the events we planned here will meld together ..
others will split.
We dont know that yet. We will see where the process of constructing brings us.
But let me ask you again. Write what you have in your head regarding the game down.
And make a planning like i just did. It will save you a lot of time.
Save this, i will continue tomorrow.
But maybe, after i slept and worked my job, you have done the game already all by yourself.
There will be only 1 new pick condition that we did not use so far.
Have a nice day
Most people start out constructing with
setting up the unmovable part of the environment of the game
that interacts with "the player", in the layout editor.
Say that again ?
The environment that interacts with the player, as there are ...
a maze (like in pac-man)
a platform (like in Donkey Kong)
grass, buildings, rivers (like in rts games)
Then they start exploring and coding the sensors/dedectors.
Those are like the eyes of the player object to sense the environment.
Then they attach the player object to the sensors.
Then they explore/code the other objects that move, like monsters, enemys, moving deadtraps ....
Artificial intelligence ...
Then they do things as score, layout changes, level changes, dead situations .....
Thats a very rough description, every game is different.
Our game is simple.
Its environment is no more then 1 sprite. And none of the moving objects will interact with it. Its just a visual grid, that helps the player to orientate.
So, or do the things explained in the previous post, or if you did this already and saved it ...
bring it up in construct.
Add a sprite, and choose "raster.png" from the sprites that i provided.
Name it, and for once you are free in what name you use.
Position it at exact x = 320 and y= 240.
Give it an opacity of 5%
And that is all that we will do with this object.
So lets lock it away, so we can not accidental move it, not even select it, thats annoying anyway.
To do this ..
Select it, right click and choose under hide/lock .. "lock selection".
You can try to select it now, and you cant no more.
Also, we will not use this object in events, and not in actions. So lets hide it for the wizards.
This keeps the list of objects small in the wizards. And thats a real time boost in developing a game.
To do this,
untoggle "show in editors" under the common properties.
Thats our environment. I said it would be a simple game.
We do not need sensors for this game. I will explain sensors in depth later. Thats a promiss.
blahhhhhhhhhhh .. it logged me out before post was done .. got to type it all over
** growwwling at myself for not copying the text before posting as i always do ***
Lets add the main actor. The snakes Head. But before we do that,
there is a question to answer.
What Z-order will the snakes head flow trough the game ?
Z-order is no more then then this :
When 2 object overlap ? which object will show in front of the other?
The object that shows in front has the highest Z-order.
Thats all !
We want the Head to move in front of almost every other object.
This can be simple accomplished by using Layers.
I introduced u already to the left properties plane. Now let me introduce you to the right organize plane. The right plane is to organize things.
This if you still have construct in the original interface layouts.
On the right you find TABS for:
Project: to organize the layouts and there event sheets.
Animator: to organize sprites into animations.
Resources: to organize application specific resources.
Layers: to organize .. well .. layers and there objects ... and easy Z-orders.
If one of those is not showing, then simply activate by clicking Home in the top menu, and the button on the ribbon for the missing organizer.
Note: layers have an internal Z-order too, but i am not gonna go there at this moment.
Click the Tab "layers".
The layer pane has 3 parts. On top the layers and there commands. On bottom a list of the objects.
And in the middle a filter to show certain objects in function to the selected layer.
We have only one layer so far. And on that layer *lays* the grid object.
Lets add another layer. Click the green up arrow on top.
The up arrow adds a layer a layer on top of all the existing layers. Easy as that.
The Z-order of the layers is "top - down". The higher positioned layer will be in front of all underlaying layers.
Select the top layer.
Add the sprite "dot.png" to the layout. It will be automatically placed on the selected layer.
In this case the top layer. So it will always display on top of other objects.
TIP: If you plan to make hundreds of objects in a big project with many many layers. Then immediately add a private variable to every object you bring into a layer. Name it like "Z-order" and give it as initial value the number of the layer. Now we do not have to remember what layer the object is when we spawn it in events. And it will be such a big help when we copy/past events to "lazy edit" them as base for the next event. : )
OK, back to the head. Name it Head. Always name your objects.
Place it in the middle of the layout.
Then edit the X and Y in the properties, so they end on a 5.
Thats in the middle of our 10 based grid.
X = 325 will do, Y = 235 will do.
The head will move according keys pressed by the player.
On arrow up key pressed the Head needs to move up. Same for left, right and down keys pressed.
To use the keyboard this way, we need an additional object.
Double click an empty place to add an object, and choose "mouse & keyboard" from the "new objects" wizard. A flashing message will confirm that it is added.
Dont look for it in the layout. It is a faceless object. Its has no sprite attached, just like the system object. You can see it in the layers pane on the right though.
I just could tell you what to do without trial and error.
But, ahhhh thats boring. So lets error and distillate little lessons out the errors.
Time to dive in the events editor. You should have the structure with comments and "always" events.
If not, then go back and do it. Takes one minute.
Now double click the "always" condition (C-spot) under the "keyboard" comment.
The events wizard shows up.
Click back to the first step of the wizard. This is what i call "lazy editing".
Step1: object = mouse & keyboard
Step2: condition = on key pressed
step3: parameters: click under "key" to access the drop down menu with keys. Choose "right arrow"
Add an action to this.
Step1: self object = Head
Step2: action = Set X
Step3: parameters = .x + 10 (respect the spaces, and do not forget the dot)
set x position of self + 10 pixels, every time the player will press the right arrow key
Run it, and try it out.
Yes that movement is right. But. Hmmm.
A snake in a snake game keeps moving, and will change direction according the pressed key.
This snake will stop moving when no arrow key is pressed.
Well then we are taking the wrong approach. No disaster.
Lets rethink this.
This means we need 2 events.
One to keep moving the Head.
One to catch Keys pressed and feed the changes to the directions of the head.
To do this we will need to store the keystrokes in a variable.
Or, we feed the X and Y of the head from a variable, changed according the directions by the keystrokes.
Lets choose for the last option.
But ? what kind of variable .. private ? or Global. And if private, which object its gonna hold it ?
Answers and theory in next post.
Carefully choose how to store your variables is half way the game.
So lets point a few things out.
The snake will have only 1 head. We do not have to deal with instance having each a different X and Y. So we could use a global variable.
Global variables do not reset when recalling the layout. And we will offer the player when he dies, to replay the game. And thats no more then recalling the layout.
I do not want to worry about resetting those variables. So Private it will be.
Now is the Question, which object is gonna hold this private variable ?
The snakes head? The sprite for the snakes head is a black dot. The body sprites will have the same sprite.
A small version of the sprites, thumbnails, will be present in the events. Adding to readability.
But if every call to a variable will be presented with a black dot. Thats too much of the same,
and certainly not adding to the readability of the event sheet.
In fact this is true for every game/project. I like my events to read nice. There for i will bring in different objects just to group, organize and store certain private variables. Those objects will have eye catching sprites, just to improve readability of the events.
There is a perfect sprite for that purpose in here
download, decompress somewhere handy.
Many times people told me, thats a wasted object.
An object that brings law and order is never a wasted object.
Add the sprite "info" from the last posted file.
Place it outside the canvas of the layout.
Name it "Vault". Size it if you feel its to big.
add 2 private variables to it
X_head, number, 0
Y_head, number, 0
Now we are set to take a new start.
back to the events editor.
Double click the action. Click back till we are in the first wizard step. (lazy editing )
step1: self object = Vault
step2: action = set value
step3:parameters .. private variable = X_head .. value = 10
You see the eye catching thumbnail ? Much better then a black dot.
now we "lazy edit" some more
CTRL + drag the action under itself to copy it. I do advice to not use copy / paste short keys in present version of construct when dealing with actions. Sometimes the copy shows up on a random place in the events. If you have all events but the one you work on collapsed, then suddenly your
game is messed up, and u dont know why. Using CTRL dragging to copy actions.
double click the copy.
we land allready in step3.
change X_head to Y_head
change value 10 to 0
Lazy but fast. And more of this.
Select the on key event. (line 2 in the sheet). The event, not the condition. (E-spot)
They whole tree will go selected.
press CTRL+c, press CTRL+v
Now we have a copy of the event, including the actions.
Double click the condition in the copied event. Automatically we land in step3 in the wizard.
Change the right arrow to left arrow.
Change the X_head value directly in the action line, by clicking the value 10.
Change it to - 10
The value stored in Y-head stays the same 0.
Do the same for up and down arrow keys. (copy event, change condition, change values)
the values for the up arrow will be
the values for the down arrow will be
Do you see how fast you can code ? make events ? edit events in construct ?
This is another reason why i like it so much.
Now we translated directions, given by a key, directly to X and Y changes.
All we have to do know is move the head's position + the changes
right click the always event under the "move head" comment.
Add an "always" sub event.
give the sub event an action.
step1: self object = head
step2: action = set X
step3: parameters ... click the vault object in the expressions guide .. click the expression "get private variable" ... change the 'Variable name' to 'X_head' ..
so its Vault.Value('X_head')
add .X + in front of that .. so it is
.X + Vault.Value('X_head')
note to ashley : it would be nice if the wizard preselects the Variable name, would be very nice.
Copy the action.
Double click the copy
Click back to step 2 of the wizard. Select "Set Y" as action.
Click next. The expression is still there, just change X_head to Y_head and .X to .Y
And we can run and test.
Hey that works. But OMG, that snake is fast.
Lets slow it down.
Double Click the TOP "always" condition in the event that moves the Head.
it brings up the events wizard.
click back to step 2 of it.
step2: Choose "every X milliseconds as" condition
step3: change the default value 1000 to 100 (hundred)
DO you Understand NOW why i want you to open each tree of events with a "always" condition ?
Its easier to edit, organize 1 condition, then to add a level of events to a tree.
And the structure stays correct.
run all .. and ..
is this better ?
there is something else to solve though.
Yes there is something to solve, but we do that after we made a body for the snake.
But before we go there, i have something so say.
About the key input events, or and mouse input events.
We have them now nicely added, visible, and easy accessible on top of the events sheet.
Thats a good practice.
Do not attach conditions to user inputs. How faster the game reacts on user input, how faster it feels.
Do not not bury the user inputs deep in a event tree. For the same reason, and also for another reason.
If you share .caps in here. Then remind that there are left handed and right handed people.
Usually you do not share complete games here. Including options for changing keys.
Mostly they lack instructions on how to play the game, which keys to use.
Most left handed people i see use the AQSD keys in stead of the arrow keys. Its handier for them.
Do not act as u are alone on the world. Make the user inputs clear and visible, readable and editable.
So anyone you share .caps with in here, can easy read what keys are used for, and edit them according there needs.
there ! .. now lets give the head a body. But that is for tomorrow.
Its a simple game. We will use the same sprite for the body as we use for the head.
But while the head gets straight directions from the players input, the body get its directions from the head. It will just follow the head.
There for we need a totally new object for the body.
The most simple way to do this would be cloning the head. But in the current construct release, when u copy an object and past it back as clone, the copy will like random jump allover the layout.
Like everywhere except on the place you told it to be. Even far outside the canvas.
At least, thats what it does on my computer, and i think it will also do so on yours.
The clone command is a little obsolete anyway, less you have no access to the original sprite.
Because, bringing the sprite again into the layout as a new object is exactly the same as cloning it.
Besides ofcourse, when you want to change the sprites, you will have to in both objects.
Well lets do this.
Add a new sprite to the layout from the "dot.png" that i provided.
Give it the name "body".
position it at exact x = 325 / y = 225. (again positioned according the grid of our little world)
Lets start out with 3 body parts.
So copy body twice, to make 3 instances in total.
Position instance 2 at x= 325 / y = 215
Position instance 3 at x= 325 / y = 205
Now we have a vertical row of dots. The bottom dot is the Head. The other 3 are instances of the body.
To translate the movement of the body in events, we do need to understand the movement.
Let me try to visualize the movement inside 1 tick for you and for myself.
1 tick is the execution of 1 complete events sheet, remember ?
Lets also forget the Y movement for a minute to simplify.
The *rest situation" we start from.
The head will move to the left.
Leaving an open spot. We want the body part to jump to that position, where the Head was.
In other words, we need to store the position of the head in a variable BEFORE it jumps to its new position. So we can Jump the body to the stored variable.
Lets call that variable X_to. Since its the place the body will Jump_to.
Now the next body will jump to the place where this body was just a moment ago. So we also need to store the place the first body is coming from in a variable.
Lets call it X_from. Standing in the shoes of the first body, its X_from.
Standing in the shoes of the next body its X_to.
We will need to make a loop that runs trough all instances of the body. When the loop starts with the second body part, we will have to store the X_from into the X_to. = Change point of view from the first body to the next body.
i have to post this, to check it what i wrote with the pictures. And to use it myself as guide for coding the events.
Develop games in your browser. Powerful, performant & highly capable.
LOL .. i hit the windows shortcut for page back in IE explorer at almost the end of my next post. LOL .. all gone .. LOL .. *hits head* I need to start writing this outside IE. But all my other spell checkers are DUTCH talking !!!! LOL.
Oh btw this IE plug in containing this spell checker is just plain awesome.
Google for IEpro.
I actual love this plug in.
Well, i got to start over. First will be dinner.