This is the 7th day of my participation in Gwen Challenge

preface

Phaser is an open source, free framework for H5 2D game development. It supports JS and TS, is based on the Pixi.js engine, and has built-in physical properties for game objects. It supports Canvas and WebGL rendering modes, and can be switched between browsers. Because Phaser is lightweight, easy to use and free to use, there are obvious advantages to using Phaser for small development. You can reference or install Phaser directly in the lowest Canvas supported browser for game development.

Display objects in the game

1. Image object Image

Image object has 5 properties phaser.game.add.image (x,y,key,frame, Group)

function preload(){
    game.load.image('bg'."./img/bg.png");
}

function create(){
    game.physics.startSystem(Phaser.Physics.ARCADE);
    // Start the physics engine
    var bgImage = game.add.image(0.0.'bg');
    // Create a picture object
    game.physics.arcade.enable(bgImage);
    // Enable the physics engine for this image
    bgImage.body.bounce.y = 0.2;
    // Elastic coefficient
    bgImage.body.gravity.y = 300;
    / / gravity
    bgImage.scale.setTo(0.5);
    / / zoom
    bgImage.inputEnabled = true;
    // Enable events
    bgImage.input.enableDrag();
    // Start object drag
}
Copy the code
2. Sprite objects
Phaser.game.add.sprite (x,y,key,frame,group)
function preload(){
    game.add.image('player'."./img/player.png");
}

function create(){
    game.physics.startSystem(Phaser.Physics.ARCADE);
    // Start the physics engine
    var player = game.add.sprite(0.0.'player');
    // Create a picture object
    game.physics.arcade.enable(player);
    // Start object physics engine
    player.body.bounce.y = 0.2;
    // Elastic coefficient
    player.body.gravity.y = 300;
    / / gravity
    player.scale.setTo(0.5);
    / / zoom
    player.inputEnabled = true;
    // Enable events
    player.input.enableDrag();
    // Start object drag
}
Copy the code
3. The use of Sprite charts

The utility and convenience of Sprite graphs without using HTTP2.0 is great, and the consistent usage here is to fetch and use them as frames.

// We will put many images of the same or similar characters in a Sprite map, and extract one of them when using
function preload(){
    game.load.spritesheet('player'.'./img/player.png'.32.32.16);
    // 32 32 refers to the Sprite frame width and height, starting from the upper left corner. The first frame is 32 bits wide and height
    // 16 is the frame length. 16 frames correspond to 0-15
}
function create(){
    var player = game.add.sprite(0.0.'player')}Copy the code
4. Button object

Button objects and many event methods, such as clicking, pressing, lifting, etc., can perform callbacks after these event actions.

function preload(){
    game.load.spritesheet('button'.'./img/button_sprite.png'.180.60);
}

function create(){
    this.button = game.add.button(0.0.'button', btnOnClick, this.2.1.0);
    this.button.onInputOver.add(function(){
        // after over to do ...
    }, this);

    this.button.onInputOut.add(function(){
        // after out to do ...
    }, this);

    this.button.onInputUp.add(function(){
        // after up to do ...
    }, this);
}

function btnOnClick(){
    // Click the callback function
    document.title = 'onDown';
}
Copy the code
5. The Bitmapdata object of the image object

1. Draw with Canvas method and use it as Sprite pattern.

/ / parameters have Phaser. Game. Add. BitmapData (width, height, key,)
function create(){
    var width = 100,height = 100;
    var bmd = game.add.bitmapData(width, height);
    bmd.ctx.benginPath();
    bmd.ctx.rect(0.0,width,height);
    bmd.ctx.strokeStyle = "# 000";
    bmd.ctx.strokeRect(0.0,width,height);
    bmd.ctx.fillStyle = "#FFF";
    bmd.ctx.fill();
    bmd.ctx.stroke();
    var block = game.add.sprite(0.0,bmd);
    block.inputEnabled = true;
    block.tint = 0xffffff;
}
Copy the code

2. Use methods provided by the Phaser framework

function create(){
    var ob = game.add.bitmapData(50.50);
    ob.circle(25.25.25."gray");
    ob = game.add.sprite(0.0,ob)
}
Copy the code

6. The Graphics object of the graphics object draws geometric shapes based on coordinates

function create(){
    circle = new Phaser.Circle(game.world.centerX, game.world.centerY, 500);
    var graphics = game.add.graphics(0.0);
    graphics.lineStyle(1.0xffffff.1);
    graphics.drawCircle(circle.x, circle.y, circle.diameter);
}
Copy the code

7. Text objects Text objects themselves can be styled.

// Phaser.Game.add.text(x, y, text, style, group);
function create(){
    var text = game.add.text(0.0."demo"[]); text.fill ="#FFF";
    text.font = Microsoft Yahei;
    text.fontSize = 16;
    text.fontWeight = "normal";
    text.style.backgroundColor = "#F00";
    text.worldWrap = true;
    // wrap
    text.worldWrapWidth = 150;
}
Copy the code

Atlas is able to put multiple images of different sizes and positions into a set map (commonly known as Sprite map, Sprite map), which can greatly reduce the image request.Atlas can also use Sprite animation, and prepare the map set file and its description JSON file.

function preload(){
    // For the NTH time, the server environment is required to load audio, video and JSON files
    game.load.atlas('demo'.'./assets/img/atlas.png'.'./assets/img/atlas.json')}function create(){
    demo = game.add.sprite(64.64.'atlas');
    demo.frameName = "demo_click.png";
    demo.inputEnabled = true;
    demo.events.onInputDown.add(function(){
        demo.frame+;
    },this)}Copy the code

Groups can be used for objects that are repetitive or have the same function, such as scene objects and NPCS.

// Create groups and add objects
var group;

function preload(){
    game.load.image("npc"."./assets/img/npc.png");
}
function create(){
    group = game.add.group();
    / / create a group
    group.create(game.world.randomX-100, game.world.randomY-100.'npc')
    // Create child elements within the group
    npc1 = game.add.image(0.0.'npc');
    // Create a Sprite
    npc2 = game.add.image(0.20.'npc',group);
    // Create Sprite 2 and add to the group
    npc3 = game.add.image(0.40.'npc',group);
    // Create Sprite 3 and add to the group
    group.add(npc1);
    // Add Sprite 1 to the group
    document.title = group.length;
    // The header shows the number of elements in the group
}
// Other methods of Group:
// group.setall (' properties ',' values ') sets the attributes of the child elements in the group
// group.callall (' method ') All group children call methods
// group. World. BringToTop (group
// group.remove(child element) Removes child element
Copy the code

Basic skills to build a game

10. Sprite animation is a frame-by-frame animation that uses a sequence of Sprite frames to play.

// 1. Create a Sprite object
var player;

function preload(){
    game.load.spritesheet('player'.'./assets/img/player.png'.32.32.16);
}
function create(){
    player = game.add.sprite(0.0.'player')

    // 2. Animate the Sprite
    player.animation.add('up'[0.1.2.3].10.true);
    player.animation.add('down'[12.13.14.15].10.true);
    player.animation.add('left'[4.5.6.7].10.true);
    player.animation.add('right'[8.9.10.11].10.true);

    player.animation.play('right'); 
    // Play the right animation, here just play the frame animation, the real movement must be added to the coordinate movement.
}
Copy the code

The earliest tween animation appeared in Flash. You can change the state A-B by setting pictures at several nodes within A period of time, such as adding character graphics at the beginning and end of 1 second, and then setting tween animation.

To put it simply, Tween animation is given two key frames before and after, and then processed by the system. It is also A process of changing from state A to state B, which is also called Tween. Here, only translation animation, transparency animation and rotation animation are discussed.

var player;

function preload(){
    game.load.spritesheet('player'.'./assets/img/player.png'.32.32.16);
}
function create(){
    player = game.add.sprite(0.0.'player');
    player.animations.add('right'[8.9.10.11].10.true);
    // Add animation
    player.animations.play('right');
    // Play the animation
    player.add.tween(this.player).to({x:game.width - this.player.width}, 500.'Linear'.true)
    // Tween animation is linear

    // Transparency animation
    game.add.tween(this.player).from({alpha:0}, 2000.'Linear'.true).repeat(10.1000);

    // Rotate the animation
    var tween = game.add.tween(this.player);
    tween.from({ angle:360 }, 2000, Phaser.Fasing.Bounce.Out, true.0, -1);
    // 0 delay, loop playback, slow animation
    tween.yoyo(true.3000);
    // Yoyo will start the new loop again with the animation property set to the value of the previous round, i.e., from 360 to 45 and from 45 to 360
}
Copy the code

13. Tile Sprite first saw this application in the Tower game, to achieve a tile Sprite graph loop scrolling.

var player;

function preload(){
    game.load.image('player'.'./assets/img/player.png');
}

function create(){
    player = game.add.tileSprite(0.0.32 * 4.32 * 4.'player');
    player.autoScroll(100.0);
}
// Scroll bars and subtitles can be applied here
Copy the code

14. Audio and video has been introduced before the loading of audio, no further details, today introduces the use of video loading.

// Load the video resource and loop it
function preload(){
    game.load.video('video'.'demo.webm');
}

function create(){
    var video = game.add.video('video');
    // Create a video
    video.play(true);
    // Loop
    video.addToWorld(400.300.0.5.0.5.2.2);
    // Add the coordinates xy anchor point to the game
}
Copy the code

Displays the current video playing progress (video.progress).

function preload(){
    game.load.video('video'.'demo.webm');
}

function create(){
    var video = game.add.video('video')
    video.play(video);
    video.addToWorld(400.300.0.5.0.5.2.2);
}

function update(){
    document.title = Math.round(video.progress * 100) + The '%';
    // Displays the current video playback progress
}

// If you want to replace the video, you can use video.changesource (' Video resource address ');
Copy the code

Sprite sharing video suitable for special effects.

var video;
var group;

function preload(){
    game.load.video('video'.'demo.webm');
}

function create(){
    group = game.add.group(); 
    // Create a video group
    video = game.add.video('video');
    for(var i = 3; i >= 0; i--){
        var sprite = group.create(game.world.randomX, game.world.randomY, video);
        sprite.width = 100;
        sprite.height = 100;
    }
    video.play(true);
}   
Copy the code

The camera in the game can not only follow the character, but also switch scenes based on different parameters. You need to set the scope of the game world before using the camera.

// The camera follows the target
var plane;
var dialog;

function preload(){
    game.load.image('bg'.'./assets/img/bg.png');
    game.load.image('plane'.'./assets/img/plane.png');
    game.load.image('dialog'.'./assets/img/dialog.png');
}
function create(){
    game.world.setBounds(0.0.2000.480);   // Set the scope of the game world
    game.add.image(0.0.'bg');

    plane = game.add.image(50.50.'plane');
    plane.angle = 90;   // The fighter rotates 90 degrees

    dialog = game.add.image(0.0.'dialog');
    dialog.y = game.height - this.dialog.height;
    dialog.width = game.width;
}
function update(){
    game.camera.follow(this.plane);
    plane.x++
}
// You can see that the camera is always positioned on the Player object and the dialog box is slowly disappearing.
// If you want the dialog box to be fixed at the bottom of the game, add dialog.fixedToCamera = true
Copy the code

If you want to keep the game stage still and move the camera, you can do this:

var plane;

function preload(){
    game.load.image('bg'.'./assets/img/bg.png');
    game.load.image('plane'.'./assets/img/plane.png');
}
function create(){
    game.world.setBounds(0.0.2000.1000); // Set the scope of the game world
    game.add.image(0.0.'bg');
    plane = game.add.image(50.50.'plane');
    plane.angle = 90;  // The fighter rotates 90 degrees

    // The camera focuses on the target object. Tapping the screen returns the camera to focus
    game.input.onDown.add(function(){
        game.camera.focusOn(plane)
    })
}
function update(){
    game.camera.x++;
    game.camera.y++;

    // The camera lens jitter, the smaller the number, the faster the frequency, the smaller the amplitude
    if(game.camera.x%5= =0 ){
        game.camera.x = this.x;
        game.camera.y = this.y; }}Copy the code

16. Particle Effects This is the most common effect in game scenes, such as cherry blossoms falling, shooting stars, flying bullets, NPCS flying, etc.

var emitter;

function preload(){
    game.load.image('bullet'.'./assets/img/bullet.png')}function create(){
    emitter = game.add.emitter(100.200);
    // Create a particle emitter with parameters: coordinates, maximum number of particles

    emitter.makeParticles('bullet');
    // Create a particle with parameters: resource name, frame number, quantity, whether particles collide with each other, and whether they collide with boundaries

    emitter.setXSpeed(500.1000);
    // Speed control defines horizontal speed X left + right + Y minus up + down

    // emitter.setScale(minX,maxX,minY,maxY,rate)
    // The zoom control sets the zoom rate transition time

    // emitter.setAlpha(min,max,rate,ease)
    // Transparency controls the minimum and maximum transparency transitions

    // emitter.setRotation(min,max)
    // Angle controls the rotation speed of the emitted particles

    emitter.start(false.3000.1000.50)

    / / emitter. Bounce. Y = 0.8
    // Elastic coefficient

    / / emitter flow (0100 0,1,100)
    // The particle emission life cycle is 0, then the number of particles emitted in the eternal emission time interval is total

    // Use frame as particle image, but need to be careful, at most 50 particles appear on the screen at one time, the more the more stuck, the fireworks effect caution
    var demo = game.add.emitter(game.width/2, game.height/2.10)
    demo.makeParticles('demo'[0.1.2.3.4.5.6.7]);  // Use the frame as the image of the particle
    demo.flow(3000.10.50, -1); // Life cycle, occurrence interval, emission number, particle total, direction
}
Copy the code

There are 4 kinds of scaling in the game: ScaleManager, EXACT_FIT, SHOW_ALL and USER_SCALE

  • Phaser. ScaleManager object

You can change the scaling mode using the ScaleMode property

  • EXACT_FIL Size of the parent element

game.scale.scaleMode = Phaser.ScaleManager.EXACT_FIT

  • SHOW_ALL keeps the aspect ratio scaled to the maximum available space

game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL

  • USER_SCALE Custom scale

Game. The scale. The scaleMode = Phaser. ScaleManager. USER_SCALE game. Scale. SetUserScale (0.5)

Game pager is not a client, and generally the window size is not set by the user. Canvas game interface is fixed under the belt, so there will be horizontal version and vertical version. At this time, it is necessary to judge the user’s device to adjust the playing direction of the playing browser.

// Check whether the device is a PC or mobile phone
if (game.device.desktop) {
    //code for desktop devices
} else {
    //code for mobile devices
}

// Determine whether the device is portrait or landscape
if(game.scale.isLandscape){
    game.scale.correct = true
    console.log('landscape')}else {
    game.scale.correct = false
    console.log('portrait')}Copy the code

Adaptation solution: Use ScaleManager to solve Phaser screen adaptation problems, mainly used to solve two major problems: no deformation but can fill the entire screen, let the browser landscape.

1. Problem # 1: The game doesn’t morph but fills the entire screen

The essence of the question is, is there a way to make two rectangles that don’t want to have equal aspect ratios overlap by scaling them equally? The answer is: no.

Solution: Dynamically set the game area, get the screen size and then scale it to a game area size.

The solution is to create some background in the.html so that the game will blend into the background instead of having black or white edges on both sides. ②. Fix the world size, and then the elements are positioned according to the world size.

2. Problem 2: Let the browser landscape

Because the browser is HTML’s environment, HTML has no right to change its external environment, so setting the browser landscape inside a Phaser doesn’t work. If the user’s phone or tablet does not have a forced portrait screen, the game still appears perfectly when the screen is turned sideways by rotating the world 90 degrees. After the world is rotated, the coordinates are adjusted as follows:

// Camera fixes were added when adjusting coordinates because the world size is larger than the game area
// camera is not necessarily at (0,0), so take it into account.
Phaser.World.prototype.displayObjectUpdateTransform = function() {
  if(! game.scale.correct) {this.x = game.camera.y + game.width;
    this.y = -game.camera.x;
    this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(90));
  } else {
    this.x = -game.camera.x;
    this.y = -game.camera.y;
    this.rotation = 0;
  }

  PIXI.DisplayObject.prototype.updateTransform.call(this);
}

// In addition, we need to change the width and height of the game in real time when the screen changes
game.scale.onOrientationChange.add(function() {
  if(game.scale.isLandscape) {
    game.scale.correct = true;
    game.scale.setGameSize(WIDTH, HEIGHT);
  } else {
    game.scale.correct = false; game.scale.setGameSize(HEIGHT, WIDTH); }},this)
Copy the code

Add this code to your game’s BootState, and the rest is the same as before. What are your previous game.width and game.height values? Not necessarily, so don’t use them when positioning elements. According to the recommendation of the official website, the game width and height are defined globally and all positioning is carried out according to the head office, so there is no error.

The official website adaptation solution address: www.phaser-china.com/tutorial-de…