Now that we have covered event functions, adding our own custom functions should be pretty easy. Any object, including ones you make during runtime using the curly braces, can have functions attached to them. Not only that, but a variable itself can be a function. You can create functions inside another function and even change what is in an existing function during runtime. Basically, functions are everywhere and they are very flexible. In order to properly make a game, you will need functions. Lots of functions.
So let's create our first function. We'll return to our project we have been using the past tutorials called
FirstProject and go into the
main code file. After the
Mob/Player and
Mob/Monster declarations, we will add some new lines.
Example codes will start to be more condensed in order to show only what is important for that particular example. By now you should be able to understand what you are reading and be able to add the code under the proper type. In this example below, just simply put the code after
Mob at the end of your
Mob chunk of code in the code file. Or you can just put the code how it is displayed in your project and it will work, it'll just be less organized. If this confuses you any, be sure you check the link at the bottom of this tutorial to see what the final source of this tutorial should look like.
Mob
function myFunction()
this.setLoc(1, 1)
We now have a function added to our code. All mobs will now have a function called
myFunction which they can call from any other function, including event functions. The code inside our new custom function should be familiar from the previous tutorial. This function with its code will sit in our source and can only be called if we manually call it, the engine will never automatically call it like it would with an event function.
So let's call this function. In order to call it, we are going to learn and use a new event function. All
Mob type diobs have the
onLogin and
onLogout event functions. The first is called when a client connects to a mob and the second is called when a client disconnects from a mob. We'll go into what a 'client' is in a later tutorial, but for now, let's add a login event function to our player mob type that calls our new function.
Mob
Player
onLogin()
this.myFunction()
Try to put the
onLogin event function under our already defined
Mob/Player code. Just below the
onNew event function would be ideal. You do not have to, though.
So what is happening here is, when a client connects to the mob Mob/Player it calls the
onLogin event function, which calls our newly added
myFunction function, which will set our player's location to 1,1 on the map. So build and run the code and see that we are at 1,1 at the start of the game instead of 5,5 or 10,10 like our other code. The reason we are at 1,1 instead of 10,10, which we set in
onNew is because
onNew is called before
onLogin, so the login event function has the final say on where we end up. All of this happens so fast that we never see the changes.
Now we know how to create our own function and how to call it, but we can also send values to the function and have the function return values. Change the new
myFunction to look like the code below.
Mob
function myFunction(pX, pY)
this.setLoc(pX, pY)
return 'It worked!'
And change the
Mob/Player onLogin code to look like the following.
Mob
Player
onLogin()
var mes = this.myFunction(2, 2)
alert(mes)
Let's pick apart what is going on here.
In the first example code we are adding new arguments to our function. These are values that can be passed into the function, in our case they are assumed to be our x and y values. These variables can be called anything you want, but our in case we name them
pX and
pY. The first thing we do in our function is pass our two argument variables into the
setLoc function. After that, we use something new called
return. What
return does is it tells the function to return to the function that called it. In this case we tell it not only to return, but to return with a value, which happens to be a string that reads 'It worked!' in our example. Functions may return one value or no value at all. Once the execution reaches the last line of the function it will return automatically, but if you want to include a value or tell it to return prematurely, then we need to include it. We'll see some other examples of
return later.
In the second example code we are calling the actual function. We pass two values into the function, which we saw earlier will be read as the x and y values and we store the value that our
myFunction function returns into a local variable called
mes. Then we call something new called
alert with our
mes variable passed into it. Basically what
alert does is pop up an alert window with a message in it.
Build and run and an alert saying 'It worked!' should appear on your screen then our player should now be at the location 2,2 once you close the alert.
Now that we know some basics about functions, let's take a look at some of the statements that can be used inside of a function. The most common is the
if statement and the other statements that go along with it such as
else and
else if. An
if statement is code that checks to see if something is true and then executes the code under it if that statement is infact true. If the statement is not true, then it will skip the code under the
if statement and either continue along or run code in an
else or
else if statement if one is there. An
else if statement will be called if the if statement(s) above it are false and an
else will be called if no other
if statements were true. An
else and
else if statement must always be attached to an
if statement.
Let's see these statements in action. Change our
myFunction code to look like the code below.
Mob
function myFunction(pX, pY)
if (pX === 2)
this.setLoc(pX, pY)
else if (pX === 3)
this.setLoc(3, 1)
else
this.setLoc(1, 1)
return 'It worked!'
There's a lot going on here, let's go through it line by line. First thing we do is check if
pX is equal to
2. The three equal signs there basically say compare the things to the left and right of me and if they are exactly equal to eachother, so if pX holds the number
2 in it, then the statement is
true, otherwise the statement is
false. You may also use only two equal signs, but three equals is a strict compare and it's good practice to use them. The difference between the two might be covered in a later tutorial.
So, in order for the code under this
if statement to be called, the
if statement must be
true, so this means the only time this
if statement's code will be executed is if
pX is equal to the number
2. If
pX is equal to the number
2 then after the code under the
if statement has been called, the execution will skip all the way down to the
return code, because there is no reason to call the
else codes. But if
pX is not equal to
2 then the execution will move to the next statement attached to the
if if there is one, and in this case there is. Now, the
else if is the same deal, but this time
pX must be equal to the number
3 in order for the code under it to be executed. If
pX does not equal the number
3 then we head to the
else which runs that code no matter what. Basically what the
else is saying is if the two above
if statements are not
true, do this, but don't do this if they are
true.
Now, because we pass
2 into our
myFunction function as the
pX value, our first
if statement should always execute, meaning our player's location will be set to
pX,
pY which is
2,
2 in our case. Go ahead and build and run to see that our player appears at
2,
2.
So how can we get our other statements to execute? Go to our
Mob/Player onLogin code and change the code where we call
myFunction to pass in the
3 and
3 values. So replace the
2s with
3s.
Build and run and our player should now appear at the
3,
1 location on the map instead of the
3,
3 location. This is because in our
myFunction code we have the
else if statement (which is called because
pX does not equal the number
2) that says if
pX is equal to the number
3 (which it is) then set our player's location to
3,
1. So basically we change the
y value from
3 to
1.
Try some values where the
x value is not equal to the numbers
2 or
3 and no matter what numbers you put, we should always appear at the location
1,
1 because our
else basically says that if
pX does not equal the number
3 or
2 then set the location to
1,
1.
Many things can be put inside of an if statement. So far we have seen how to compare two things to see if they are equal, but we can also check to see if one of the values is either greater than or less than. These checks can be done on numbers or strings. For strings it would be based on alphabeticalization.
Let's change our previous statements to make use of greater than and less than. Change the
myFunction function code to look something like the code below.
Mob
function myFunction(pX, pY)
if (pX > 3)
this.setLoc(pX, pY)
else if (pX <= 3)
this.setLoc(3, 1)
else
this.setLoc(1, 1)
return 'It worked!'
So now our code will first check if
pX is greater than the number
3. If this is false then we check to see if
pX is less than
or equal to the number
3, which obviously it is if it is a number, since it's not greater than 3, but we are learning here. Then the
else you would think would never run because the value has to be either greater than, less than, or equal to
3, but in the case that
pX is not even a number or string (assuming an error does not occur), then our
else will be executed.
Change the numbers in the
onLogin event function that we passed into the
myFunction to
4 and
5 and then build and run. Our player should appear at
4,
5 on the map because the first if statement is executed. Try the values
3 and
4 and our player should appear at
3,
1 because of our second if statement.
Now for
boolean variable values. A
boolean is either equal to
true or it is equal to
false. Booleans are good for making some type of switch that keeps track of if something is on or off. When you check the boolean in an if statement, it'll execute if the boolean is
true and not if it is
false. Booleans are pretty common in game development, so expect to be using them often. An example of one being used might be to track if a Mob is stunned or not. Either it is stunned or it is not, true or false.
Let's make use of a boolean and also nest some if statements to show it can be done. Pass a new parameter into the
myFunction call code called
false. Make your onLogin code look something like this.
Mob
Player
onLogin()
var mes = this.myFunction(4, 5, false)
alert(mes)
Then change your
myFunction function code to look something like this.
Mob
function myFunction(pX, pY, pBool)
if (pBool)
if (pX > 3)
this.setLoc(pX, pY)
else if (pX <= 3)
this.setLoc(3, 1)
else
this.setLoc(1, 1)
return 'It worked!'
else
return 'It did not work!'
Build and run and you should now get an alert that says 'It did not work!' because our
pBool value is false and our first if statement in our function checks to see if
pBool is true. You will also notice that we appear at the location
10,
10 because we no longer override our mob's
onNew code that sets our location. Go back to where we call
myFunction in
onLogin and change the
false to a
true. Build and run again and we should now have our old results back.
If statements can do more than only check if a
boolean is
true or
false, it can check if a variable has a value or not or if it is equal to zero. If a variable is equal to
null or
0 or the variable does not exist at all, an if statement will return false for it. In our above example, not only is our if statement checking to see if
pBool equals
true, it is also checking to see if it has a value at all and is not equal to
null or
0. To better understand this, here are a few examples of variables and what an if statement would read them as. Do not include them in your code.
var a = 0
if (a) //false
var b = 'a'
if (b) //true
var c = null
if (c) //false
var d = 45
if (d) //true
We can also negate things inside of the if statements. A negation is used with an exclamation mark and when you put it infront of something it basically says, whatever the if statement would read this value as, flip it. So a
true would be
false and a
false would be
true. Let's change our
myFunction function code to make use of this.
Mob
function myFunction(pX, pY, pBool)
if (!pBool)
if (pX !== 3)
this.setLoc(pX, pY)
else if (pX <= 3)
this.setLoc(3, 1)
else
this.setLoc(1, 1)
return 'It worked!'
else
return 'It did not work!'
So now our first if statement will only execute if
pBool is
false, because we negate whatever value it happens to have, so in order for us to get the
true we need to make the statement run,
pBool has to be
false. Then inside the first if statement you will notice we changed the first nested if statement to
if (pX !== 3). What this means is if
pX does
not equal the number
3 then execute the if statement. So with the function code we now have,
pBool needs to be
false and
pX has to equal something other than
3 in order for us to move to the location
pX,
pY which our first nested if statement does.
Finally, we will cover
and and
ors, which can be used inside of if statements to check multiple things at once. If we want to check if something is equal to something else
and another thing is equal to something, we would use the symbols
&& between each statement. If we wanted to check if something is equal to something else
or another thing is equal to something, we would use the symbols
|| between each statement.
Let's give it a try. Alter your
myFunction function code to look like the code below.
Mob
function myFunction(pX, pY, pBool)
if (!pBool || pX > 3)
if (pX !== 3 && pY !== 3)
this.setLoc(pX, pY)
else if (pX <= 3)
this.setLoc(3, 1)
else
this.setLoc(1, 1)
return 'It worked!'
else
return 'It did not work!'
The
myFunction function now calls the first if statement if either
pBool is
false OR if
pX is greater than the number
3. Then if that is
true, the next if statement executes if
pX does
not equal the number
3 AND the variable
pY does
not equal the number
3 as well. So if both variables are something other than
3, this statement should execute.
So we have now learned how to create our own functions, execute code inside of them, and use statements to check values of things and run different sections of code depending on the results. In the next tutorial we will learn about more statements and other code that we can use inside of functions.
If you followed everything in this tutorial, the source of your project should look something like this.
https://vylocity.com/ide/Vylocity/FirstProject3/
References