Newsletter
Published on 19th June 2017
Welcome to Issue 85 of Phaser World
Wait, it's not Friday already is it? Afraid not. This issue of Phaser World is coming to you on Monday 19th June, and Monday is going to be its new release day from now on. You may remember a few weeks ago I was ill and couldn't publish on Friday like normal, so I published on Monday instead. In looking at the metrics I get from the newsletter host a number of clicks and general interaction with the issue released on Monday were higher than on a Friday.
I'm not too sure why. I suspect when the newsletter arrives quite late on a Friday that Eurozone based readers, and those further East, are already well into their weekend, and maybe it just gets lost in the weekend's worth of email and never read come Monday again. Clearly, a lot of you do read it on a Friday, but as it's more on a Monday I'm going to try publishing on a Monday instead for a while and see what happens.
So, until the next issue, keep on coding. Drop me a line if you've got any news you'd like featured (you can just reply to this email) or grab me on the Phaser Slack or Discord channels.
Games made with Phaser
Game of the Week
Can you survive a terrible day in the office? in this superb platform adventure game.
Staff Pick
The concept is beautifully simple: Just click 10 times, 1 second apart. Can you manage it?
A fun game of the classic Battleships, with nice animations and sounds.
An endless runner game based on the classic Snake where you have to survive a crazy food rush as long as possible.
Swat Kats the Radical Squadron
Rescue your beloved heroes from the evil Dark Kat who has trapped them in his Lava Fortress.
Phaser News & Tutorials
A tutorial on creating complex objects: the combination of varying parent and child elements.
A great tutorial on creating vehicles and a landscape to drive on in P2 Physics.
The tutorial continues, adding spikes, death and more features to the game.
In this new instalment, the game is made fairer, with better object placement and optimisations.
Creating Games with Phaser Part 5
In Part 5 of this new video based tutorial course learn about Tilemaps and Layers.
Patreon Updates
Welcome and a massive thank you to the new Phaser Patreon who joined us this week: Lisandro Lorea.
Patreon is a way to contribute towards the Phaser project on a monthly basis. This money is used entirely to fund development costs and is the only reason we're able to invest so much time into our work. You can also donate via PayPal.
Backers get forum badges, discounts on plugins and books, and are entitled to free monthly coding support via Slack or Skype.
Development Log
This week we're going to try something a little different. Because Felipe had the week off and I mostly spent it doing quite dull input manager planning I thought I would use this week's Dev Log to bring you a tutorial.
Snake Plissken
I thought it would be quite fun to create a version of the classic Nokia Snake game. It has minimal asset requirements, so it's easy to show the logic and concepts behind it without getting bogged down in the graphics. Plus it's also ripe for potential expansion.
Because embedding code into newsletters is really tricky I have split the tutorial up into 8 parts and you can view the source for each one on the Phaser Labs. The links below will take you to the online code editor, so just hit the 'Run' button to see it in action.
Part 1 - The Basics
To get started I created a basic State structure and game config. The game will be 640 x 480 in size, running under WebGL and has a nice Nokia green background color. I defined a few functions I knew we'd and preloaded the assets.
Part 2 - Enter the Snake
It's time to create the Snake and get it moving around. I create a new Snake class that will look after its own internal properties, such as its position, alive state, speed, direction and heading.
The Snake itself is managed using a single Layer. Layers in Phaser 3 are like Groups on Phaser 2, but they don't impact the display list. The Layer is created in the Snake constructor and one single Sprite is added to it, referenced as 'this.head'.
I added 4 functions to control changing the snakes' direction (turnLeft, turnRight, etc). These are then called from the State update as the cursor keys are pressed. The functions check if the movement is valid. For example, if the snake is travelling UP and you press the down key, the press should be ignored, because the only valid direction when moving up is left or right. The new direction is stored in a local property this.heading and when it comes time to update the snake position it uses this to do so.
If you run Part 2 you are able to move the snake around using the cursor keys and have it wrap off the sides of the screen. The movement is done with a Layer Action called ShiftPosition. This Action works by taking an array of Game Objects and then iterating through them, changing the position of the next in the sequence to be the position of the one that came before it. This means if you move the head Sprite, then call ShiftPosition, all the rest will follow. Click the screen shot below and move the mouse to see the 'raw' effect running:
Part 3 - Dinner Time
In a game of snake you need something to eat. The food image is already loaded so in Part 4 I created a new Food class to handle it. This class simply extends GameObjects.Image and will gain a few extra properties and methods as the game evolves. For now, the food is created and positioned on the screen. You can still move around but you cannot eat it yet.
Part 4 - Let's Grow
Now we've got food we need to be able to eat it. This is done by adding a 'collideWithFood' method to the Snake class. It takes a Food object as its one single argument and then simply compares the position of its head with the food and if they match it's been eaten.
When the food is eaten Snake.grow is called. This simply uses the Layer.create command to add a new Sprite onto the end of the snake's body, into the position that was previously occupied by its tail end. The snake expands by one segment and also Food.eat is called. In order to prove it works all this does is change the position of the Food to a random x/y coordinate within the game. Even at this rudimentary stage, you can see it all coming together and although you cannot collide with yourself, you've still got the formation of a proper game now.
Part 5 - Speed-Up
It would be nice to make the game get slightly harder as you play it. To achieve this when our snake collides with the food it will increase the speed of the snake slightly. This is done in the collidesWithFood method. It first checks the current speed and if there is still room for it to increase it then checks to see if the total amount of food eaten is a multiple of 5. If so the speed goes up. So for every 5 bits of food eaten, the snake gets quicker. It's a simple change but it will help keep things interesting for the player.
Part 6 - The Trouble with Random
Currently, when food is eaten it randomly repositions itself. The problem with this is that as the snake gets longer it's entirely possible the food will reposition itself directly on top of the snake, or even back where it was before. This is no good and would look strange, so I had to prevent it from happening.
The game is basically a 40 x 30 sized grid. The concept for the new method of repositioning the food is to create a temporary 40 x 30 grid, flagging each cell is un-filled. Then loop through each snake body piece and remove those cells from the grid, as they're occupied, so are not good locations for the new piece of food. At the end of this process, we have a grid with only valid positions left in it which we then pass to Phaser.Math.RND.pick() to select one cell from. That cell becomes the new home of the food.
You can see all the code for this in the 'repositionFood' function. It's not that elegant but it does work and prevents our game from breaking, which is the most important part.
Part 7 - No-Body to Love
The traditional way to die in the game of Snake is to eventually make a mistake that causes you to run into your own body. To complete our game we need to implement this and thankfully it's quite trivial to do.
In Phaser 3 there is an Action called 'GetFirst'. It takes an array of Game Objects along with a comparison object. The Action iterates through the array, checking the properties and values of the comparison object against each Game Object, and if it finds a full match it returns it. In code it looks like this:
In the code above all children of the Body Layer are checked. If one is found that has the 'x' coordinate 100, the 'y' coordinate 200 and an alpha value of 0.5 then it's returned. If nothing matches the conditions then you get null back. Although this example is a little convoluted it has many useful applications, such as in our snake body check. In the Part 7 code, we use it to check to see if any of the body elements have the same x and y coordinate of the head. If they do we know the snake ran into its body. The result of this is captured and the game ends accordingly.
With this final check in place, you can now play a complete game of Snake. Collecting food, growing, wrapping around the screen and dying when colliding with yourself as seen in the animated gif below:
Part 8 - Audio Effects
Phaser 3 doesn't yet have a fully Sound Manager (it's on the schedule, but isn't due for a few months). However, a while ago I did add in the ability to generate dynamic audio at run-time. So let's use that to add some effects into our Snake game.
In part 8 you'll see I created a Web Audio context and then in the Food class I define the dynamic audio settings and call it in the Eat method:
The same is done when you die as well, just with a different effect. Feel free to tweak the values to see what kinds of interesting audio you can create! But it definitely feels a lot more alive when playing it now.
Further Thoughts
I appreciate it's quite a simple game but I feel like it has shown off a number of Phaser 3 features clearly: Layer Actions, which you can easily create your own to extend in all kinds of directions. An easy to use Phaser Class construct and even Dynamic audio.
Because the Snake is a fully self-contained class there is nothing stopping you from taking the code and using it elsewhere or even making a version where you have to control multiple Snakes at once. You could add in objects to avoid, power-ups, flies or different kinds of food. There are a lot of ways it could be expanded.
I hope you enjoyed this little trip into the works of using Phaser 3 for an actual game. Next issue we'll resume with a normal Dev Log again, but if little tutorials like this prove to be popular then I'll gladly write more in the future.
Phaser 3 Labs
Visit the Phaser 3 Labs to view the new API structure in depth, read the FAQ, previous Developer Logs and contribution guides. You can also join the Phaser 3 Google Group. The group is for anyone who wishes to discuss what the Phaser 3 API will contain.
Geek Links
Caves of Qud is a science fantasy RPG & roguelike epic. It’s set in a far future that’s deeply simulated, richly cultured, and rife with sentient plants.
#RemakeJam is an interesting concept: Remake your very first game, using all the skills and knowledge you've learnt since, to showcase how you've evolved as a developer.
A tour of Mars assembled from NASA images reveals a wondrous but uninviting planet
Phaser Releases
The current version of Phaser CE is 2.8.0 released on May 30th 2017.
Phaser 3.0.0 is in active development in the GitHub v3 folder.
Please help support Phaser development
Have some news you'd like published? Email support@phaser.io or tweet us.
Missed an issue? Check out the Back Issues page.