This article is from netease Cloud community

Author: Wang Ge


Do not know whether you still remember in those days fashionable 2048 this game, a simple and not simple game, always let you play in idle time for a while.


In this article, we’ll use Phaser, the open source H5 framework, to recreate the game. Here you can learn about in-game state management, Sprite component objects, and how to use Preload, Create, and more.

Why choose H5 with so many game frameworks?

Due to the popularity of H5 in recent years, H5 game frameworks have sprung up all over the place, and there are even many frameworks that fall into this category that are not designed for game development. So why Phaser? Here’s why I chose it:

  • Native JS is supported.

  • You can easily switch between Canvas and WebGL.

  • Clearly positioned and focused on H5 game development.

  • Complete documentation and examples.

  • Phaser 3 is currently under development.





The final rendering of the game looks like this


The development of preparation

Visit the Phaser website at http://www.phaser.io, download the JavaScript version of Phaser, and structure your project

The project file structure is as follows:

Introduce the related JS file in index.html and define a div as the parent container of the Phaser generated canvas

<! DOCTYPE html> <head> <meta charset="UTF-8" />
   <title>2048</title>
    <script src="js/phaser.min.js"></script>
    <script src="js/Menu.js"></script>
    <script src="js/Game.js"></script>
    <script src="js/index.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
      }
      canvas {
        margin: 0 auto;
      }
      .game {
        position: absolute;
        width: 100%;
        height: 100%;
      }
    </style>
</head>
<body>
  <div id="game" >"game"></div>
</body>Copy the code

How does the game work

We have introduced the Phaser library in the HTML file, which gives us a global object called Phaser, through which we can access the methods and functions in the Phaser library used to build the game.

Now we’ll create a game instance using a Phaser object that represents the entire game, and we’ll add different states to it.

Index.js, where you can create a game instance, register each game state, and launch the game.

Window. game = new Phaser.Game(240, 400, Phaser.CANVAS,'game'); // Add state (); // Add state ();'Menu', Menu);
game.state.add('Game', Game); // State switch to start the game game.state.start('Menu');Copy the code

The “state” management in Phaser makes it very easy to switch scenes in the game, which can be interpreted as different game interfaces. 2048 is a simple game, requiring only two interfaces: the home page and the in-game interface.

  • The home page state, processed by menu.js, is used to load game resources and display the game start interface. Click the Start button to switch to the game state and start the game.

  • The game state, handled by game.js, is used to display the game interface, control the game logic, and display the score panel after the game is over

Next initialize the Menu state object (Menu), define a new object Menu in menu.js and add functions to it. When the state is started, the preload function within the object is first called, which is usually used to load the resources needed for the game. After loading, call the create function to initialize the game interface, logical objects, and so on.

var Menu = {
    preload: function() {// Load the image with the Key used to create the symbol and the file path game.load.image('background'.'assets/bg.png');
        game.load.image('btnStart'.'assets/btn-start.png');
        game.load.image('btnRestart'.'assets/btn-restart.png');
        game.load.image('logo'.'assets/logo.png');
        game.load.image('btnTryagain'.'assets/btn-tryagain.png');
    },
    create: functionTileSprite (0, 0, game.width, game.height,'background'); Var logo = game.add.image(0, 0,'logo'); logo.reset((game.width - logo.width) / 2, (game.height - logo.height) / 2 - 50); Var startBtn = game.add.sprite(0, 0,'btnStart'); startBtn.reset((game.width - startBtn.width) / 2, (game.height - startBtn.height) / 2 + 100); // Enable component click listening and add the listening event startBtn.inputEnabled =true;
        startBtn.events.onInputDown.add(this.startGame);
    },
    startGame: function() {// Switch state to game interface game.state.start()'Game'); }};Copy the code


At this point, the launch screen is complete. After starting the local Web server, open index.html in your browser and you can see the launch screen of the game.



I then start working on the interface and logic of the Game in game.js

var Game = {
    create: function() {// add background game.add.tilesprite (0, 0, game.width, game.height,'background'); // This. Score = 0; this.best = 0; Var titleStyle = {font:"bold 12px Arial", fill: "#4DB3B3", boundsAlignH: "center" };
        var scoreStyle = { font: "bold 20px Arial", fill: "#FFFFFF", boundsAlignH: "center"}; var scoreSprite = game.add.sprite(10, 10); Var scoreGraphics = game.add.graphics(0, 0); scoreGraphics.lineStyle(5, 0xA1C5C5); scoreGraphics.beginFill(0x308C8C); / / draw a rectangle with rounded corners. ScoreGraphics drawRoundedRect (0, 0, 70, 50, 10); scoreGraphics.endFill(); Scoresprite.addchild (scoreGraphics); // Add graphics to the parent container for overall repositioning. Var scoreTitle = game.add.text(0, 5,"SCORE", titleStyle); scoreTitle.setTextBounds(0, 0, 70, 50); Scoresprite.addchild (scoreTitle); this.scoreText = game.add.text(0, 20, this.score, scoreStyle); this.scoreText.setTextBounds(0, 0, 70, 50); scoreSprite.addChild(this.scoreText); . / / to add keyboard direction a listen and listen for an event var up = this. Game. Input. The rid_device_info_keyboard. AddKey (Phaser. The rid_device_info_keyboard. Up); up.onDown.add(function() {... }); var down = this.game.input.keyboard.addKey(Phaser.Keyboard.DOWN); down.onDown.add(function() {... }); var left = this.game.input.keyboard.addKey(Phaser.Keyboard.LEFT); left.onDown.add(function() {... }); var right = this.game.input.keyboard.addKey(Phaser.Keyboard.RIGHT); right.onDown.add(function() {... }); . / / get gestures sliding Y and X axis difference difference sliding direction is used to calculate the var deltaX = this. Game. Input. ActivePointer. Position. The X-ray this.game.input.activePointer.positionDown.x; var deltaY = this.game.input.activePointer.position.y - this.game.input.activePointer.positionDown.y; .Copy the code

2048 the rules of the game is very simple, the development of ideas is also very clear, maintain a 4*4 array, every time trigger mobile events traversed the number group, the direction of the superposition judgment, and then look for space in the array, random generation of new numbers, if not the end of the game. Some of the relevant development ideas and algorithm optimization is not detailed here, we can refer to it.


Information recommendation

While the game is very simple, there are many aspects of Phaser that can be learned through this project. If you are interested in this, you can further explore the following information:

  • Phaser official documentation

  • Phaser online editor

  • Phaer game examples show


Netease Cloud Free experience pavilion, 0 cost experience 20+ cloud products!

For more information about NETEASE’s r&d, product and operation experience, please visit netease Cloud Community.


Relevant article: “recommended” Question | mobile terminal registration of virtual machine and other cheating way of cracking 【 recommend 】 【 you one step away from the valley 】 netease hot collection of China entrepreneur competition projects