Claimed?
Last time we created our board and we prepared a 2D list that will let us know which squares are claimed and which are not.
In this post we'll actually learn how to claim a square, how to handle the animations and how to let our opponent see what square we claimed.
Lets start with claiming a square.
But before that let's use a little bit of logic to figure out how things could be done (the major problem here is that we're applying my logic: You've been warned!).
What we need to do to claim a square? Well...we need to click it (dooh), then we should check if it's claimed or not, and if it's not we should claim it (meaning changing a value in our 2D list) and then change the animation of that square from the blue or red one to a green animation.
So this should be something like this:
if we pressed the mouse on a square
check to see if the value in the list is 0
and if value is 0
change that value to 1
change animation for that square to a green animation.
If you actually think that I'll be using the above "code"...You're Wrong Again! (I did warn you about the use of my own logic). I'll switch things up a little:
if we pressed the mouse on a square
if the animation for that square is not the green one
change the animation to the green one
//more to come after this part:
This will allow us to start simple and add more things as we move along, so here's how a When the mouse is pressed event would look after I previously created an actor attribute named squareActor (note that we're still working on the same PlayBehavior behavior we started in the last post):
The problems!
Since you must run your game twice to be able to test it, then you probably noticed that both players can claim a square when they press the mouse button, and they shouldn't be able to do that since they must take turns.
To fix that, the Nuggeta Extension offers 2 blocks. A boolean that is true when it's the current player's turn to play, and false when it's not the player's turn, and a block that ends the current players turn to play. Our pseudocode would be something like this with those blocks:
if we pressed the mouse on a square
if it's our turn to play
......
claim at will
......
change turn after that
Our event would look like this now:
Should you test the game now you'd see that Player1 is the first one able to click a square, and after he claims a square, his turn changes (we'll handle the visual aspect of that turn change later on) and then the second player can claim a square.
So far so good, but we still have problems:
Whenever a player claims a square, his opponent should actually see what square he claimed, so we need to figure out how we could change the animation of the claimed square for both our players.
The only way to do that would be to send a message to our opponent and based on that message he should change the animation accordingly.
The Nuggeta Extension allows us to send a "raw message" to all our opponents, which means we don't need to create an object inside the Game Definition tab in the Nuggeta website, and that's what we'll use because there's no need to complicate things.
So now that we know that we can send a message to our opponent, we have to figure out what we should send. When we click on a square we could get it's X and Y coordinate and send those, or we could get the X and Y coordinates of the mouse and send those, or we could get the row and column number in our 2D list and send those, or ... I bet you can figure out what else we could send to our opponent, and maybe it will be a better choice than the one I'll pick next.
Ini mini miny moe!
After careful consideration (ahem) I decided to use the first option and just send the X and Y coordinates of the square to our opponent, so I added the corresponding block to our event:
Cool. Now we can send a message, which means we need to see how we can make the other player receive our message.
To do that we need to check when a raw message is received, and we need to do that inside an Always event. And don't worry, since you're only receiving that message once your code will only execute once even if it's inside that event.
From now on our Click event will handle our own actions, and the Always event will handle what our opponent does, and since we want to show to the player what square his opponent claimed our Always event should contain this code:
To do that we need to check when a raw message is received, and we need to do that inside an Always event. And don't worry, since you're only receiving that message once your code will only execute once even if it's inside that event.
From now on our Click event will handle our own actions, and the Always event will handle what our opponent does, and since we want to show to the player what square his opponent claimed our Always event should contain this code:
If a Raw message was received
save the message inside a list
get the X coordinate from the first item in the list
get the Y coordinate from the second item in the list
find the square that has those coordinates
change the animation for that square to the green one
In case nobody noticed, we might have another problem! Notice the "change the animation for that square" part? We already did that in the click event, and now we need to do the same thing again :(
When ever such an issue occurs it's best to create a Custom Block so we'll do just that.
What will we do with that block? We'll send that block the X and Y coordinate of the square we clicked on, or from the message we receive, and change the animation for the actor that has those coordinates. That's it!
I'll name mine Claim actor at X: [] Y:[], and this is how the Create Custom Block window looks like on my end in Stencyl:
Now we can go back to our Click event and modify it to use our new custom block:
This is the code that goes inside the Custom Block we just created:
I hope things weren't confusing, because so far we only modified what was already working (but we got rid of our problems... ≧◠◡◠≦✌ ), and our initial goal was to allow the players to see the squares that are claimed by their opponents. For that we added an Always event and I posted what we will do inside it in the above pseudocode.
I created a list attribute named messageList (so you should too) that we will use to store the coordinates we receive, and we'll send those coordinates to our Claim actor at X: [] Y:[] custom block:
Now if you test the game you will finally see that whenever we claim a square, our opponent will see it !
The last thing that we'll do in this part of the tutorial is to actually keep the squares that are claimed in our 2D list.
In the last post we created a 2D list named gridList, and we filled it with 0 when we created our board, and now we need to replace the 0 from that list with 1 for the square that we claimed and for the square that our opponent claimed. We'll let each player keep track of their own squares and their opponents squares and each player will be responsible to check if they won or lost.
Rows vs. Columns
When we click on a square we can visually see that said square belongs to a certain row and a certain column, but now we need to transform what we see into code. Let me clarify what I see when I talk about a row or column:
Notice that we start counting from 0 and not from 1 as you might expect, because it will be easier to transform the X and Y coordinates to Row and Column coordinates that we need for our 2D List.
To be even clearer, the greater the X value of our square will be, the greater the Column number will be, and the greater the Y value will be, the greater the Row number will be.
I created 2 additional attributes to store our Column and Row numbers and I (again cleverly) named them rowNumber and colNumber and I added the following to our Click event:
You may notice the replace entry at column # block and that I used rowNumber where that block claims to need a column number. That may be a bug in either the 2D list extension or a bug in my own logic (highly probable), but after printing the rowNumber and colNumber and also our 2D list I had to reverse those 2 attributes inside that replace entry.. block just to trick me that my own logic still works.
Now when we click on a square our 2D list gets updated properly, but we need to update it when the opponent claims a square also. That can be accomplished in exactly the same way that we did in the click event, but this time we need to add it in the Always event:
That's all there was to it. In the next post we'll mark the danger squares.