nkholski

Generic platformer + ES6 / Webpack 4 boilerplate

Recommended Posts

This project started off as a Phaser 3 / ES6 / Webpack boilerplate for testing Phaser 3 in its early stages, but ended up with a quite ambitious demo attached to it. I kept updating it and now it has two purposes:

1. A Phaser 3 / ES6 / Webpack 4 boilerplate. Replace the src folder with your own game and you have a good foundation watching your scripts and a built-in server with live reload plus the possibility to deploy your code for production use.

2. A,  let's call it "generic platformer". Hack around in the source to see what's making the demo tick or alter it to build something of your own. The code isn't as tidy as it should be, and some parts are still left since the beta when I had to do hacks around the API to get things running but I'm making an effort now and then to improve it. Also, when I feel for it I add an extra feature. I prioritize features that force me to explore new parts of the API. I plan to continue to improve it (but not create a complete game because of obvious copyright reasons).

GitHub: https://github.com/nkholski/phaser3-es6-webpack

Questions, suggestions and contributions are all more than welcome.

smb-phaser3-short.gif.beb9ea7b7d6781bd72d6e55c76029139.gif

 

 

Share this post


Link to post
Share on other sites

I've added touch controls tonight to be able to check performance on mobiles. There is no lag at all on my Honor 8 from 2016 and I've done nothing to optimize the code. Phaser 3 is going to be great!

You can try it by the link provided above. Note that the touch controls are just a quick test to be able to move Mario at all, and not what touch controls could be in a real game.

Share this post


Link to post
Share on other sites

I'm happy to hear that. Please let me know if you think I should add something in particular. I'm thinking about title screen to demonstrate going between scenes and fireballs in a pool.

I would be a bit cautious learning webpack from the project though. Most of the time I have no clue what I'm doing and when I guessed something that works I stay with it. :-)

I updated the repository to Phaser 3.0.0 earlier today btw.

Share this post


Link to post
Share on other sites

I added a title screen running the game itself in a parallel scene in attract mode. The attract mode was made by recording my gameplay in a json and then repeat it. It's buggy and does weird things from time to time due to non-deterministic physics, but I think it looks kind of cool anyway.

I also updated the repository. What I really should have done was to clean up the code (and remove some pre-release solutions) but now I added more spaghetti code than ever when hacking in the attract mode.

5a89ecd18969c_Peek2018-02-1822-14.gif.45a56b3126ea6c070b175da3cb513deb.gif

 

 

Share this post


Link to post
Share on other sites

First of all, @nikbrg, thank you very much for the boilerplate, I've been using it as a starting point when I started to play with Phaser 3 this weekend.
I have a question tho: I've noticed in the main game scene you are calling this.mario.update() to call update logic of Mario sprite, and same for the enemy sprites. I'm not an expert in Phaser, was playing around with v2 a bit, but I remember in prev version it was possible to just write an update logic in Sprite and it was working (no need to call it explicitly in the main scene/state). I've tried myself to not call it explicitly, I've rechecked that my sprite was added to the scene in it's own constructor like that: 

config.scene.add.existing(this);

but indeed, it's not working.

I wonder, is there any way in Phaser 3 to not call update() of Sprite explicitly in the main scene and make update() logic constantly work anyway after object creation?

Share this post


Link to post
Share on other sites
20 hours ago, Vlas said:

First of all, @nikbrg, thank you very much for the boilerplate, I've been using it as a starting point when I started to play with Phaser 3 this weekend.
I have a question tho: I've noticed in the main game scene you are calling this.mario.update() to call update logic of Mario sprite, and same for the enemy sprites. I'm not an expert in Phaser, was playing around with v2 a bit, but I remember in prev version it was possible to just write an update logic in Sprite and it was working (no need to call it explicitly in the main scene/state). I've tried myself to not call it explicitly, I've rechecked that my sprite was added to the scene in it's own constructor like that: 


config.scene.add.existing(this);

but indeed, it's not working.

I wonder, is there any way in Phaser 3 to not call update() of Sprite explicitly in the main scene and make update() logic constantly work anyway after object creation?

Currently this isn't a supported feature in v3; however, there's an open PR with some discussion around this topic so we may see it shortly in an upcoming version.

Share this post


Link to post
Share on other sites

@Vlas @jorbascrumps I think it's a good decision not to call an update-method for all game objects (even if I was used to this from Phaser 2 and was quite confused why my code didn't work initially with Phaser 3). I hope we get a standard method to do this, like gameObject.runUpdate(true) to push it to an array of objects that get updated for each loop (and gameObject.runUpdate(false) to remove it again). However, doing it yourself as I do isn't that complicated either. It's probably a quite common bump on the road for those going from Phaser 2 to 3 though.

@msickle The code is in the source code. I planned to clean up the code but couldn't stop myself from doing this instead, thus with a messier source code. 

The attract mode is the actual game stage running in parallel of the title screen with muted music. If you study it you see that you can activate a function to record keystrokes and positions of the player. Arcade Physics isn't deterministic and this was a big challenge, that's why I need to copy the position and velocity and not only keystrokes. I played the game while recording the keystrokes to a global variable. When happy with the result I did JSON.stringify with the object and I copied the output to a JSON-file. When running in attract mode I keep track on time and simulate keystrokes from the imported JSON and I adjust the position and velocity of Mario too to adjust it to what it was when I played. You can try to comment out the adjustment of position and velocity if you want and you'll see how soon it'll freak out. The enemies aren't controlled by anything else than game logic which means that Mario could be killed or miss a jump (he almost always fail to jump on the second goomba in the pair just before the first hole, my JSON seems to adjust Mario just in time to miss the enemy each time but sometimes Mario manages to squash it). It's far from a perfect solution but it was fun to make and good enough to keep in the demo I think :-).

@Everybody: I'm super happy to see so many of you have used the repository. I mean 200+ stars is crazy! I didn't expect that. I've been busy with other things but hope to be able to return soon to update the code to Phaser 3, go through everything for readability and move misplaced code where it belongs. And of course, most probably get obsessed to add something new that makes everything into a mess again.

Share this post


Link to post
Share on other sites

Thanks, that's a great source of examples !

I'm curious about some of your choices on your Webpack config.

1. Is there any benefit from using BrowserSync instead of Webpack dev server ? Or this choice come from the others repos you refer to ?

2. In my project, I use both file-loader and a static folder for my assets. I don't know which way is the good way neither if one option is better than the other.

I see you serve your assets in a static folder. Is there a reason ?

3. I copied the following part from another repo and I see you have it too. But I don't know the purposes of theses lines. Can you explain ?

var definePlugin = new webpack.DefinePlugin({
    __DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')),
    WEBGL_RENDERER: true, // I did this to make webpack work, but I'm not really sure it should always be true
    CANVAS_RENDERER: true // I did this to make webpack work, but I'm not really sure it should always be true
})

 

Share this post


Link to post
Share on other sites

This entry in the changelog explains what the WEBGL_RENDERER and CANVAS_RENDERER flags are used for: https://github.com/photonstorm/phaser/blob/master/CHANGELOG.md#updates-2 (and that they've in fact changed with Phaser 3.7.1).

TL;DR When building Phaser yourself you can include/exclude the two renderers with those flags. So if your game only ever runs in Canvas mode, you can exclude the WebGL renderer to reduce your file size.

Share this post


Link to post
Share on other sites

@B.Guyl The webpack-stuff of repository a clone of a Phaser 2 boilerplate which I've managed to get to work with Phaser 3 through trial and error. I'm not a great source for webpack best practises. 🙂 (1) No idea. It's just kept as it was in the original repository. (2) I don't really understand the question. I prefer a source folder with content that should be transpiled, a static folder and a build folder that everything get copied to. I load the assets with the Phaser 3 file loader. (3) @snowbillr got you covered 🙂

Share this post


Link to post
Share on other sites

I've done some work on reorganizing and otherwise improve the code, but when the code got really messy (by the end of the  Game create method) I lost focus a bit and couldn't resist implementing fire Mario. If you're using this, what would you prefer: Improved code base or additional features?

The online demo was also updated:

 343520767_firemario.gif.e9441abcee78deac8262f33efa7c5735.gif

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.