Due to the rapid pace of change some links or details may no longer be correct.
New Clock class, Timers, Endless Tilemaps and State updates.
Someone asked me on Slack if I thought Phaser 3 was ready to be used to make a game with yet. This is a valid question as obviously significant areas of the API are still yet to be done (Mouse Input and Sound for example). But I took it as more of a challenge than a query and started working on a proper game with it.
It was an enlightening experience. Beyond sound, nearly everything I wanted to do in the game, I could. And what's more, it was genuinely a pleasure to do it. Small switches from things like long method signatures to config objects made the code easier to write and understand. Parallel States allowed me to craft a UI overlay, keeping my code much cleaner. And the performance was excellent.
It also highlighted a number of areas that needed either finishing or improving. In the schedule, these had been pencilled in for a couple of weeks time but I moved them forwards and spent last week on them. To that end, I'm afraid there isn't a whole lot of eye candy this issue but there are plenty of updates.
Phaser 2 had a Clock that was controlled by the core game loop and these 'disposable' clocks called Timers that you could create via it. Within those Timers you could create TimerEvents. They basically consisted of a duration and a callback. They are useful things to have but were a bit heavy-weight and prone to a few timing issues if you did things like constantly pause the game or lose focus. So I rebuilt them from scratch.
v3 now has a Clock class but it belongs exclusively to a State and every State has one. You can add events to this clock using a simple syntax:
After 2000 ms (2 seconds) the callback will be invoked and internally the event is recycled for later use.
If you are more familiar with the TweenMax / GSAP syntax then you can use that too. The following code does the exact same as the above:
Timed Events can be set to repeat a specific number of times, or loop forever (until you ultimately kill the event). You can also get the progress of an event, either of the current iteration if the event is set to repeat, or of the overall progress. You can see that in the example below - the yellow clock arrow is the current progress and the red one the overall progress. As usual, click the screen shots to open the example:
You don't have to even use a callback if you don't want to. You can simply monitor the progress of an event and base your own in-game actions on that. Here we can see a whole bunch of timers running, all with different (random) durations:
Timers can be paused and resumed directly via code and also automatically if the State is sent to sleep and woken up again. One final feature they have is the ability to scale time. Each Timer itself has a timeScale property which can be tweaked to change the time scaling for that one specific timer, or you can timeScale the whole Clock - this has the effect of scaling every timer currently running. In the following example you can see 3 timers running in parallel, all of them set for 5 seconds, only the first has a timeScale value of 0.5, so takes twice as long to complete, and the 3rd one has a value of 2, so completes in half the time:
They may not be very exciting, but they're bloody useful!
Last issue we demonstrated Dynamic Tilemaps and I said that one of the things they could be used for was an 'endless' world, where new map data is streamed in at runtime.
I wanted to prove that this was possible and not just an idle boast, so I created a small example to show it in action:
The concept is pretty simple: A map is created that is 51 x 37 tiles in size. With 16x16 tiles, as in this example, that gives us a map width of 816 pixels. Our game is 800 pixels wide. We then scroll the camera horizontally each frame and once it has moved 16 pixels we update the tilemap data so that all of the tiles shift across by 1 and a brand new set of tiles are created on the right-hand edge. Finally, the camera scroll is reset to zero. The end result is that as the map scrolls brand new data is generated dynamically on the right-hand edge and is scrolled into the screen, giving us a random endless map.
If you needed a hand-crafted map then you could of course feed in actual map data from a larger array instead. You could also make the map 52 tiles in width, enough to have tiles on both the left and right, so that the player could scroll in both directions. It all depends on what sort of game you're making but I just wanted to prove that technically v3 can handle it. The implementation details are down to you though :)
Using the exact same concept as the Endless Tilemap scroller above I created an example showing how to display a really long scrolling message. Bitmap Text was given a feature a while ago allowing you to scroll the contents of it, but it only impacts the text currently being displayed. If you scroll the text, then shift all the characters along one and replace that on the end, you can scroll for as long as you like:
Here's a simple example displaying the opening of William Gibson's classic book Neuromancer. You wouldn't want a BitmapText displaying such a massive amount of characters, as most of them would be off the edge of the screen - so instead we just cycle through the text string, actually only rendering 8 characters at once. As it doesn't use the camera to scroll but a native feature of BitmapText you can easily pass whatever content you like via this method.
Working on States
As well as getting the Clock class in and running I also spent a good chunk of last week on the State Manager. I am going to demonstrate this in more depth next issue because the demo I created is waiting for a fix to the Camera system from Felipe before I can release it! But I can talk a little about the new features that have been added.
First of all, Felipe added the ability for a Camera to have a background color and opacity level. This is really useful as it renders behind anything in the display list and can be any color you need. Using this I added the option for Cameras to be defined via the State Config object. You can set the width, height, position and color of a camera in there and it will create them all automatically for you. Click the following shot to see a typical config object (when it loads use the blue buttons at the top to run the example):
States also now have a set of new modes they can be in. They can be fully active, which means both their update and render methods are called. They can be paused, which means they still render but their update isn't processed (effectively pausing anything that was based on it, like timers or physics). They can be 'asleep' which means they neither update nor render, but have not shutdown and can be woken at any point, where they will just carry on as if nothing has happened. And finally they can be fully shut down, so they don't render or update and their systems and display lists have been cleared too.
With these new options it allows you to craft all manner of set-ups and I can't wait to demonstrate some of these in the coming weeks.
As always, thank you for your support. If you are a patron then I really do appreciate it. We're not doing any client work at all at the moment, so every penny we make is going right back in to Phaser 3 work and allowing us to work flat-out on it. The more I use v3 to make real games, the more I realise we've built something really quite special. And that's exciting as hell :)
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.