Phaser World Issue 12
Phaser 3 is now called Lazer.
Follow development in the repo and Mailing List.
Here are some of the changes made this week:
The Loader has been overhauled
Complete rewrite of the Loader. The Files are now entirely independent of the Loader and don't hold any references to the Loader at all. They are fully Promise based. The BaseLoader no longer cares about what the File is or does, as long as it exposes the properties and methods it needs. The File is responsible for handling its own loading (be it XHR or Tag based) and simply returns a Promise to the Loader.
The Files are no longer Classes either, but pure JavaScript objects with a few helper functions.
Lots of new XHR level properties have been added to the files and the Loader. You can now set XHR login credentials (username, password), a file load timeout value, request headers and mime type overrides. These can all be set on a per-file basis, or globally in the Loader itself (file level properties override global ones always)
Image Files have a new crossOrigin property, as does the Loader. So files can have their own CORs settings, not just a Loader level one.
Files also now have a process callback, which is invoked after the default File Handler process function has run. The Loader now works differently to Phaser - before once the file was loaded it was instantly processed. For example if you loaded a huge JSON it would be parsed immediately on load, even while other files were loading. This is a performance issue, so the Loader now works in two stages: Loading of files and Processing of them. Only once all the files have loaded are they processed (i.e. JSON is parsed, XML is evaluated, etc).
A new Tests Runner
Created a transform/2d/basic folder and moved relevant files in there. This will help distinguish it from other more complex 2D Transforms (i.e. those with parenting support).
Updated BaseTransformComponent so it now uses local [0][1] properties (like the Vec2 class does) instead of the _v property data array. This means you can now pass any Transform component such as Position or Scale to any function that expects a Vec2 data type. This makes it extremely flexible.
Created BaseTransform class, which can be used by a Game Object as a base class to extend from. It hides away the Transform methods you don't want to inherit and adds in some useful property accessors.
Moved the setTransform method out into the SetTransformToContext
function. Also created SetTransformToCSS
along with a new test (06-css1.js) and it works great, happily rendering 50 <div> elements, rotating and translating them across a container 'game' div, all from the same base Transform class as used for Canvas (and soon WebGL).
Created new Transform sets: Minimal, Basic and Standard. These relate to the number of components they have enabled, and thus their complexity within their update functions. Minimal just has the Position and Scale components, nothing else, so is the quickest of them all. Basic has Rotation and RotationAnchor support added, so is the next most complex. Standard adds Pivot support onto this, which is really useful but adds another layer of complexity to the update logic. The final set to create will be ones allowing for child transforms. I'm likely going to create several of those - again ranging in complexity the more calculations are needed.
Have created lots of test cases showing the new Transforms in action, very happy with how quickly this is coming together. Will soon be able
Big update to the Lazer-Dev Test Runner. It now looks lovely and is much easier to use. It's based on the Phaser one I use locally and includes the ability to run tests in a div or iframe, screen grab and other things. It runs from php, just because, but should work fine on any set-up.
Time to start thinking about Texture support, starting with how Frames and FrameData will be represented internally. Made a start by creating the Frame function along with SetTrim. Also created a massive multipack + rotation texture atlas in the lazer-dev repo to test from. This is going to need a new way to handle things from Phaser. Probably Sprite.frameSet
, Sprite.frameName
(the name of the frame within the atlas) and Sprite.frame
(the number of the frame within the frameName, if a Sprite Sheet, or within frameSet).
Moving away from Classes
Thought: Binding a Shape to a Transform on a class level seems like a bad idea (or any object actually). Feels like it would make more sense to build a 'ShapeFactory' that combined a Shape with whatever type of Transform you needed, then you could use more simple or complex ones as required.
For a while now I have wanted to move away from using 'Class' pretty much anywhere in Lazer. I'm not such a religious zealot that I believe it's as bad as lots of JS devs make out, but I do firmly believe that Lazer should be about data structures, not class structures.
However until today I had never found a clean way to handle getters and setters on pure Objects. I want you all to be able to do scale.x++
and similar, and not have to break out into scale.setX(value)
or something equally nasty. But today I finally found a good clean compromise (that I should have tried weeks ago to be honest). Basically adding the getters and setters onto the returned Object. This way I can have factory functions that spit out well formed Objects that themselves carry the properties and methods needed to just work. This is fantastic on several fronts: it allows you to keep using scale.x
directly, it allows me to embed property update logic into those setters, and it means I can remove truckloads of 'class' instances from the code base. Win, win.
Phaser 3 is now called Lazer.
Follow development in the repo and Mailing List.
Here are some of the changes made this week:
The Loader has been overhauled
Complete rewrite of the Loader. The Files are now entirely independent of the Loader and don't hold any references to the Loader at all. They are fully Promise based. The BaseLoader no longer cares about what the File is or does, as long as it exposes the properties and methods it needs. The File is responsible for handling its own loading (be it XHR or Tag based) and simply returns a Promise to the Loader.
The Files are no longer Classes either, but pure JavaScript objects with a few helper functions.
Lots of new XHR level properties have been added to the files and the Loader. You can now set XHR login credentials (username, password), a file load timeout value, request headers and mime type overrides. These can all be set on a per-file basis, or globally in the Loader itself (file level properties override global ones always)
Image Files have a new crossOrigin property, as does the Loader. So files can have their own CORs settings, not just a Loader level one.
Files also now have a process callback, which is invoked after the default File Handler process function has run. The Loader now works differently to Phaser - before once the file was loaded it was instantly processed. For example if you loaded a huge JSON it would be parsed immediately on load, even while other files were loading. This is a performance issue, so the Loader now works in two stages: Loading of files and Processing of them. Only once all the files have loaded are they processed (i.e. JSON is parsed, XML is evaluated, etc).
A new Tests Runner
Created a transform/2d/basic folder and moved relevant files in there. This will help distinguish it from other more complex 2D Transforms (i.e. those with parenting support).
Updated BaseTransformComponent so it now uses local [0][1] properties (like the Vec2 class does) instead of the _v property data array. This means you can now pass any Transform component such as Position or Scale to any function that expects a Vec2 data type. This makes it extremely flexible.
Created BaseTransform class, which can be used by a Game Object as a base class to extend from. It hides away the Transform methods you don't want to inherit and adds in some useful property accessors.
Moved the setTransform method out into the SetTransformToContext
function. Also created SetTransformToCSS
along with a new test (06-css1.js) and it works great, happily rendering 50 <div> elements, rotating and translating them across a container 'game' div, all from the same base Transform class as used for Canvas (and soon WebGL).
Created new Transform sets: Minimal, Basic and Standard. These relate to the number of components they have enabled, and thus their complexity within their update functions. Minimal just has the Position and Scale components, nothing else, so is the quickest of them all. Basic has Rotation and RotationAnchor support added, so is the next most complex. Standard adds Pivot support onto this, which is really useful but adds another layer of complexity to the update logic. The final set to create will be ones allowing for child transforms. I'm likely going to create several of those - again ranging in complexity the more calculations are needed.
Have created lots of test cases showing the new Transforms in action, very happy with how quickly this is coming together. Will soon be able
Big update to the Lazer-Dev Test Runner. It now looks lovely and is much easier to use. It's based on the Phaser one I use locally and includes the ability to run tests in a div or iframe, screen grab and other things. It runs from php, just because, but should work fine on any set-up.
Time to start thinking about Texture support, starting with how Frames and FrameData will be represented internally. Made a start by creating the Frame function along with SetTrim. Also created a massive multipack + rotation texture atlas in the lazer-dev repo to test from. This is going to need a new way to handle things from Phaser. Probably Sprite.frameSet
, Sprite.frameName
(the name of the frame within the atlas) and Sprite.frame
(the number of the frame within the frameName, if a Sprite Sheet, or within frameSet).
Moving away from Classes
Thought: Binding a Shape to a Transform on a class level seems like a bad idea (or any object actually). Feels like it would make more sense to build a 'ShapeFactory' that combined a Shape with whatever type of Transform you needed, then you could use more simple or complex ones as required.
For a while now I have wanted to move away from using 'Class' pretty much anywhere in Lazer. I'm not such a religious zealot that I believe it's as bad as lots of JS devs make out, but I do firmly believe that Lazer should be about data structures, not class structures.
However until today I had never found a clean way to handle getters and setters on pure Objects. I want you all to be able to do scale.x++
and similar, and not have to break out into scale.setX(value)
or something equally nasty. But today I finally found a good clean compromise (that I should have tried weeks ago to be honest). Basically adding the getters and setters onto the returned Object. This way I can have factory functions that spit out well formed Objects that themselves carry the properties and methods needed to just work. This is fantastic on several fronts: it allows you to keep using scale.x
directly, it allows me to embed property update logic into those setters, and it means I can remove truckloads of 'class' instances from the code base. Win, win.