Newsletter
Published on 3rd December 2018
Welcome to Issue 133 of Phaser World
It's good to be back in the land of newsletters after a short break. There's quite a bit of development news to catch-up on, new games to play, new tutorials to read and the Phaser stickers have been flying out the door, so grab some while you still can! :)
This is a pretty long issue, as I had a lot to cover. If your mail client truncates it, please do so you don't miss anything!
Until the next issue keep on coding. Drop me a line if you've got any news you'd like featured by simply replying to this email, messaging me on Slack, Discord or Twitter.
Phaser Sticker Packs nearly sold out!
Over the past few weeks, I have been frantically shipping the Phaser sticker packs to everyone who pre-ordered them. There have been some great photos on Twitter of Phaser stickers stuck to laptops and such-like :)
I have around 50 packs left and then I'll be sold out. Anyone ordering during December will also get a free Phaser badge and a new pixel-art sticker too (those who pre-ordered got free Christmas cards and extra stickers thrown in their packs!)
Click here to order a sticker pack.
The Latest Games
Game of the Week
Take control of the two titular heroes as they venture into the Crystal Temple on a gem grabbing, puzzle infested quest.
Staff Pick
This is a traditional solitaire game where you must take apart the construction made of dice.
Just tap to keep your plane in the air, collect the stars and unlock the intro sequences.
The asteroid survival game! Can you take out the other players and the rocks in this space blasting IO game?
The hive is buzzing and the bees are working furiously as they try to complete their jobs by sundown!
What's New?
Retro Highscore Table Tutorial
A new multi-part tutorial on creating a retro styled high-score table in Phaser 3 with modern inputs.
Circle vs. Line Segment Tutorial
A short but useful tutorial on handling circle to line segment intersection in your games.
A set of powerful Phaser 3 plugins for creating UI components such as scroll bars, text buttons and more.
Facebook Instant Games Leaderboards Tutorial
Learn how to create and use Leaderboards with the Facebook Instant Games Plugin for Phaser 3.
Circular Endless Runner Tutorial
Learn how to create a circular endless runner in part one of this new tutorial series.
Down the Mountain Tutorial Part 2
In the second part of this series the prototype is updated so the jump is handled using cubic bezier curves.
Making Games in Phaser 3 - Part 2
A video overview of Scene's in Phaser 3 and what they can do.
Phaser 3 Game Development Course
A complete Phaser 3 and JavaScript Game Development package. 9 courses, 119 lessons and over 15 hours of video content. Learn to code and create a huge portfolio of cross platform games.
Back the Phaser project
Because Phaser is an open source project, we cannot charge for it in the same way as traditional retail software. What's more, we don't ever want to. After all, it's built on, and was born from, open web standards. It's part of our manifesto that the core framework will always be free, even if you use it commercially, as many of you do.
You may not realize it, but because of this, we rely 100% on community backing to fund development.
Those funds allow Phaser to improve, and when it improves, everyone involved benefits. Your support helps secure a constant cycle of updates, fixes, new features and planning for the future.
There are other benefits to backing Phaser, too:
Click to see the full list of backer perks
I use Patreon to manage the backing and you can support Phaser from $1 per month. The amount you pledge is entirely up to you and can be changed as often as you like.
Patreon renews monthly, just like Netflix. You can, of course, cancel at any point. Tears will be shed on this end, but that's not your concern.
All Amounts Matter
Traditionally, the Patreon platform promotes the concept of "the more you pledge, the more rewards you get". Their whole system is geared around this. I felt, though, that for something like open-source support it was time to level the playing field. This is why all rewards are available to everyone, regardless of how much they pledge. There are a couple of exceptions, which I outline on the backers page, yet to me, this felt like the fairest approach to take.
If you're able to be a higher tier backer, then I cannot stress enough how much I thank you for that. Please don't feel that your contribution is undermined in any way. At the end of the day, the money is being used to keep development of Phaser going, and that will never falter. This move is about making everyone feel equally rewarded, regardless of financial ability. Equally, if it's at all possible to slightly increase your pledge at some point, there are now lots of more minor-increase tiers you can explore.
Backer Perks
▪ Backers Newsletter (due early December)
▪ Exclusive Backers Examples (first batch are out now)
▪ Private Discord Channel
▪ One-on-One Technical Support (time restrictions apply, see page)
▪ Free copy of Interphase 1
▪ Early Access to new Tutorials
▪ Early Access to new Books and Plugins
▪ Forum Badge
▪ Phaser Laptop Stickers
▪ Roadmap Round Table
▪ Promotion and Advertising for your games or product
▪ Special Offers
Please help support Phaser on Patreon
Full details about the perks can be found on the Phaser backers page.
Thank you to these awesome Phaser Patrons who joined us recently:
Alex Otten
Braelyn Sullivan
Charles Torris
Code For All, Lda
Container7
Daniel Romero
Danny Ralde
Đạt Đặng Quốc
Dibas Baral
Eric Theofanis
Fabio Rogerio da Silva Jose
Feng Li
Gaku
George Butter
Ilya Tepeyolotich
Jack M
Jalmari Ikävalko
James Lenoble
James Pierce
Jerome van den Heuvel
Jf Fj
Just Cooking Show
Kate Kligman
Katherine Brennan
Kristian Dorland
Lars Mathiasen
Marcel Jolaoso
MegaApple_Pi
NecoDoS
Noel
Oszkar Biro
Pablo Martínez Merino
Paolo Di Stefano
Paul Roberts
Richard Searle
Richard Sopuch
Rudra Softtech LLP
Saul Ignacio Ibarra Arce
Saul Martínez
Sergio Lopez
Stephen Gose
SUNG UK JANG
Tamas Varga
Tristsoalaire
Vignesh S
Vladimír Novák
Yaroslav Mykhalchuk
Yutsi
Thank you to the following for increasing their pledges:
Scott McFarlane
James Skemp
Kristian Koivisto-Kokko
Also, thank you to Omer Gunduz and Satege s.r.o for the donations.
Dev Log #133
Welcome to the first Developer Log in a few weeks. I took some time away from the newsletter to catch-up with other tasks, do some learning of my own (I've been addicted to VueSchools videos!) and just have a bit of a break from the relentless news and editing cycle. But, that doesn't mean development of Phaser itself stopped. Far from it, in fact. There's quite a bit of ground to cover, so let's get stuck in!
Phaser 3 Doc Jam is over!
Thank you to everyone who took part in the Phaser Doc Jam! I've now finished importing the last batch of comments into the code and it has bought the total down from 3,452 items left to document, to under 800. Which is a fantastic achievement for a few months of community effort.
As promised, I picked 6 who contributed the most towards the documentation, to receive the Amazon gift vouchers. Those are as follows:
▪ @telinc1
▪ rootasjey
▪ ajmetal
▪ cyantree
▪ Elliott Wallace
▪ STuFF
Again, thank you to everyone who took part. You've helped make a real dent in the documentation and we're closer than ever to being fully complete.
Phaser 3.16 Development
One of the side effects of working on the new Scale Manager is that because it's such a massive system, it touches upon a lot of areas within Phaser. One of those is, of course, the Input system. After all, it's essential that input still works, no matter how the game is scaled. While working in the Input Manager I took the opportunity to improve a number of things.
Get to the Point
The first was that I wanted you to be able to detect when a pointer left the game canvas. This was previously half-implemented, but you had to listen to an event coming from the Game instance itself, and it only worked for the mouse. Responsibility for this has now moved away from the Visibility Handler to the Input Manager, as it should be. There are two new events: `gameover` and `gameout`, both of which come from the Input Plugin in a Scene, which means you can listen for them with this code:
This gives you a chance to react to the primary pointer leaving your game. What you then do with that information is up to you, of course. It's worth noting that the pointer doesn't have to have left the game canvas bounds, it just isn't directly over the canvas DOM element any more. This means that if you were to open-up a DOM based overlay for your game, like an advert or text input field, that it would still fire a `gameout` because the pointer ain't in cansas any more (as the focus has been taken by the new DOM element).
I also added two more events, which are related to this: `pointerupoutside` and `pointerdownoutside`. As you can infer from their names, they are dispatched if the pointer is released, or pressed down, while outside of the game canvas. Internally, a pointer will no longer think it is 'up' if you press it down on your game, then drag outside the canvas, and release it. Which I know had been a source of concern for some of you. I didn't want it to dispatch the usual `pointerup` event, though, because it's a much more specific action that has happened.
Hence the creation of the new events for dealing with pointers outside the canvas. To go with these events the Pointer class gained the following new properties: `downElement` and `upElement`. These hold a reference to the DOM element on which the pointer was pressed down, or released. In normal activity, i.e. someone playing your game, they will both just be references to your game canvas. However, if someone presses down while outside your game, you can now check these properties to see what it was they clicked on. This should come in handy if you want to create an external DOM driven UI layer, for example.
Pointer Gestures
While working on an example for the Phaser Backers on Patreon, I was asked if I could show how you 'throw' a Game Object, by swiping on it. I had wanted to add in Gestures to the Phaser Input system for a while, so I figured it would make sense to try and kill two birds with one stone. In theory, all it would require is for a Pointer to keep track of its velocity. From that, you can pretty much determine any gesture you like.
This should be trivial, I thought. After all, to calculate it all you need is the difference between the Pointers current and previous position, right? Indeed if you do any research on this matter online, that's exactly what all the implementations suggest you do. So I added a naive velocity property based exactly on this. Strangely enough, it utterly sucked. In order to 'throw' something you need to get the velocity at the point at which the mouse button (or finger) is released. As it's the release that indicates the user wishes to fling the object. The speed at which they were moving just prior to the release determines the velocity it gets thrown at.
The issues with using a velocity based on just the previous position were two-fold. First, the browser samples DOM input events at a pretty high rate. And by their very nature, they're noisy as hell, too. What this means is that the data you get from the pointer positions is often all over the place, as it's sampling at such a high rate. In testing I found that most of the time when I released the mouse to 'throw' my object, the pointer had a velocity of zero. This was because when you move your mouse, it moves pretty fast, but when you release a button your hand is in the act of releasing the button and is usually no longer moving the mouse any more at all. It might only be a split second this happens (that your mouse remains still as you release the button) but that's all it needs, as the input sampling is so high. As far as the Pointer was concerned, it had stopped, so it had no velocity at all. Which isn't much use for throwing things.
It was possible, with practise, for me to time the button release while still moving. But, it felt unnatural, and the results were inconsistent. A new approach was required. My immediate thought was to increase the sample rate. So, instead of basing velocity on just the previous frame, instead I'd record a short movement history and calculate it from that instead. This presented it's own problems, however. How long should the history be? If the sample rate was too large, it would take too long for the velocity to catch-up and would 'lag' behind the Pointers true speed. If it was too short, it suffered the exact same problem as before. Plus there was the issue of recording the history every movement, which required array manipulation that I really didn't want to be doing in a potentially hot area of code.
I spent quite a while working through different ways of handling this. Phaser 2 had used the history array approach, but I was determined there was a better solution. What's more, each solution I tried varied from platform to platform. Using a high precision Steel Series mouse on my main work PC gave very different results to using the trackpad on my Macbook, which in turn gave very different results to using an iPad. Our hands just work differently in different environments. Who'd have thought?! :)
Finally, I decided to flip the problem on its head. It was no longer about recording the history of the Pointer positions, but instead about using just the current position to influence a hidden vector that each Pointer maintained. Think of it as a 'ghost' trailing the Pointer. This ghost is constantly chasing the Pointer, seeking the Pointers last known position every frame until it finally gets there. It's never too far behind, but just enough that we're able to read the data we need from it to get the angle of movement, the speed and the distance travelled. All variables we need to calculate gestures and throwing motions. The ghosts path is also passed through a Smooth Step interpolation, to reduce the noise inherent in pointer motion.
You can now access all of the following values on any Pointer instance, from any input event:
▪ `Pointer.smoothFactor` is a float-value that allows you to automatically apply smoothing to the Pointer position as it moves. This is ideal when you want something smoothly tracking a pointer in a game, or are need a smooth drawing motion for an art package. The default value is zero, meaning disabled. Set to a small number, such as 0.2, to enable.
▪ `Config.inputSmoothFactor` is a new property that allows you to set the smoothing factor for all Pointers the game creators. The default value is zero, which is disabled. Set in the game config as `input: { smoothFactor: value }`.
▪ `Pointer.velocity` is a new Vector2 that contains the velocity of the Pointer, based on the current and previous positions. The velocity is smoothed out each frame, according to the `Pointer.motionFactor` property. This is done for more accurate gesture recognition. The velocity is updated based on Pointer movement, it doesn't require a button to be pressed first.
▪ `Pointer.angle` is a new property that contains the angle of the Pointer, in radians, based on the current and previous positions. The angle is smoothed out each frame, according to the `Pointer.motionFactor` property. This is done for more accurate gesture recognition. The angle is updated based on Pointer movement, it doesn't require a button to be pressed first.
▪ `Pointer.distance` is a new property that contains the distance of the Pointer, based on the current and previous positions. The distance is smoothed out each frame, according to the `Pointer.motionFactor` property. This is done for more accurate gesture recognition. The distance is updated based on Pointer movement, it doesn't require a button to be pressed first.
▪ `Pointer.motionFactor` is a new property that controls how much smoothing to apply to the Pointer positions each frame. This value is passed to the Smooth Step Interpolation that is used to calculate the velocity, angle and distance of the Pointer. It's applied every frame, until the midPoint reaches the current position of the Pointer. The default value is 0.2.
▪ `Pointer.time` is a new property that holds the time the Pointer was last updated by the Game step.
▪ `Pointer.getDistance` has been updated. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
▪ `Pointer.getDistanceX` is a new method that will return the horizontal distance between the Pointer's previous and current coordinates. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
▪ `Pointer.getDistanceY` is a new method that will return the horizontal distance between the Pointer's previous and current coordinates. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
▪ `Pointer.getDuration` is a new method that will return the duration the Pointer was held down for. If the Pointer has a button pressed down at the time this method is called, it will return the duration since the Pointer's was pressed down. If no button is held down, it will return the last recorded duration, based on the time the Pointer button was released.
▪ `Pointer.getAngle` is a new method that will return the angle between the Pointer coordinates. If the Pointer has a button pressed down at the time this method is called, it will return the angle between the Pointer's `downX` and `downY` values and the current position. If no button is held down, it will return the last recorded angle, based on where the Pointer was when the button was released.
Which is quite a lot! You have full control over this. If you don't want any smoothing at all, you can disable it from a single config property. If you find you want things smoother (perhaps you're making an art package and need smoother brush movement?) then you can increase it, too. I'm very happy that these new properties will allow you to make any type of gesture you need and be pretty creative when it comes to pointer input in your games.
Using the new features in 3.16 I created a Pointer Monitor class, which you can see below:
The idea is that you create a Pointer Monitor in your code and then it can listen for swipe events. Meaning you can do this:
And all of a sudden, you've things being swiped and thrown all over the place :) The full code for this specific example is available today for Phaser backers on Patreon and will be released into the public domain in a few months time.
3.16 has also gained a really neat new blend mode called 'ERASE', which I'll cover with full examples next issue. I'm still working on packaging up a final release, but there's still quite a bit to do before I'm happy with it. Part of me is tempted to release it 'as is' just to get it out into the wild, but I'll make a firmer decision on that towards the end of this week.
In the meantime you can find all the latest code in the master branch on GitHub. Every new feature being added and every bug being fixed, is of course free and public and you can test them all out right now if you don't want to wait for a final release :)
This 16x16 Top Down Dungeon Set by s4m_ur4i is just lovely and a complete steal at $1.50 for 180+ sprites!
How to make a Roguelike is a truly massive article on creating rogue-likes, best practices, and innovation in the field.
Moon footage, sped-up, with techno music. It goes extraordinarily well :)
Phaser Releases
Phaser 3.15.1 released October 16th 2018.
Phaser CE 2.11.1 released October 2nd 2018.
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.