why phaser game lagging in mobile devices - javascript

I am creating my first game using Phaser and it is running fine in desktop.
But it is lagging on android phones.
can anyone tell me what could be the reasons?
game is very small
smaller than 2mb.
Images used in game is also very tiny pngs.
is there anyway to find out any leaks in my code.
my main js file.
var buttetSpwanSpeed;
var bulletSpeed;
var enemySpwanSpeed;
var enemySpeed;
var golis;
var enemies;
var enemyLoop;
var scoreText;
var powers;
var bulletSize;
setStart();
//game phaser
var game=new Phaser.Game(window.innerWidth, window.innerHeight, Phaser.CANVAS,"gamearea");
var BootState={
//loding accets
preload: function(){
this.load.image('LodingScreen', 'assets/desimulga.png');
this.load.image('background', 'assets/blue.png');
},
create: function(){
game.state.start("LoadingState");
},
};
var LoadingState={
//loding acc
preload: function(){
bg=this.game.add.tileSprite(0,0,600,300,'background');
bg.height = game.height;
bg.width = game.width;
LodingScreen=this.game.add.sprite(this.game.world.centerX,this.game.world.centerY,'LodingScreen');
LodingScreen.anchor.setTo(0.5);
LodingScreen.scale.setTo(0.5,0.5);
this.load.image('spaceship', 'assets/player.png');
this.load.image('goli', 'assets/bullet.png');
//load ememies
this.load.image('enemy1', 'assets/enemies/enemy1.png');
this.load.image('enemy2', 'assets/enemies/enemy2.png');
this.load.image('enemy3', 'assets/enemies/enemy3.png');
this.load.image('enemy4', 'assets/enemies/enemy4.png');
this.load.image('enemy5', 'assets/enemies/enemy5.png');
this.load.spritesheet('power1', 'assets/power/bulletUp.png',34,33,4);
this.load.image('restart', 'assets/restart.png');
this.load.spritesheet('blast', 'assets/explosion.png',400,400,8);
game.load.audio('fire', 'assets/music/bullet.mp3');
game.load.audio('killed', 'assets/music/killed.mp3');
//game.load.audio('bg_music', 'assets/music/background.mp3');
game.load.audio('death_music', 'assets/music/death.mp3');
game.load.audio('start_music', 'assets/music/start.mp3');
},
create: function(){
game.time.events.add(Phaser.Timer.SECOND * 2, function(){
bg.kill();
LodingScreen.kill();
game.state.start("PreGameState");
},this);
},
};
var PreGameState={
//loding accets
create: function(){
game.scale.refresh();
bg=this.game.add.tileSprite(0,0,600,300,'background');
bg.height = game.height;
bg.width = game.width;
Startb=this.game.add.text(this.game.world.centerX,this.game.world.centerY, 'TAP TO START' , { fontSize: '32px', fill: 'yellow' });
Startb.anchor.setTo(0.5);
Startb.scale.setTo(0.5,0.5);
ship=this.game.add.sprite(this.game.world.centerX,this.game.world.height*0.4,'spaceship');
ship.scale.setTo(0.4);
ship.anchor.setTo(0.5);
game.physics.arcade.enable(ship);
bg.inputEnabled=true;
start_music = game.add.audio('start_music');
start_music.allowMultiple = true;
start_music.addMarker('start_music', 0, 30);
bg.events.onInputDown.add(function(){
bg.inputEnabled=false;
Startb.kill();
start_music.play("start_music");
// game.physics.arcade.moveToXY(ship, this.game.world.centerX, this.game.world.height*0.8, 300, 3000);
// game.add.tween(ship).to( { y: game.world.height*0.8 }, 3000, Phaser.Easing.Sinusoidal.InOut, true);
var tween = game.add.tween(ship).to({
x: [this.game.world.centerX, this.game.world.width*0, this.game.world.width, this.game.world.centerX],
y: [this.game.world.height*0.4, this.game.world.height*0.5, this.game.world.height*0.6, this.game.world.height*0.8],
}, 2000,Phaser.Easing.Quadratic.Out, true).interpolation(function(v, k){
return Phaser.Math.bezierInterpolation(v, k);
});
game.time.events.add(Phaser.Timer.SECOND * 2, function() {
bg.kill();
ship.kill();
game.state.start("GameState");
} ,this);
}, this);
},
};
var GameState={
//loding accets
preload: function(){
},
create: function(){
//background
this.background=this.game.add.tileSprite(0,0,600,300,'background');
this.background.height = game.height;
this.background.width = game.width;
this.background.inputEnabled=true;
this.background.input.enableDrag(true);
this.background.input.startDrag = function(pointer) {
pointer.shipStart = new Phaser.Point(GameState.ship.x, GameState.ship.y);
Phaser.InputHandler.prototype.startDrag.call(this, pointer);
};
this.background.input.updateDrag = function(pointer) {
GameState.ship.x = pointer.shipStart.x - pointer.positionDown.x + pointer.x;
GameState.ship.y = pointer.shipStart.y - pointer.positionDown.y + pointer.y;
GameState.background.x=0;
GameState.background.y=0;
};
//ship
this.ship=this.game.add.sprite(this.game.world.centerX,this.game.world.height*0.8,'spaceship');
this.ship.scale.setTo(0.4);
this.ship.anchor.setTo(0.5);
game.physics.arcade.enable(this.ship);
// this.ship.inputEnabled=true;
// this.ship.input.enableDrag(true);
//score
this.scoreText = this.game.add.text(16, 16, 'Kills: 0', { fontSize: '32px', fill: '#fff' });
//background Music
// music = game.add.audio('bg_music');
//music.play('', 0, 1, true);
//bullet sound
bullet_sound = game.add.audio('fire');
bullet_sound.allowMultiple = true;
bullet_sound.volume=0.5;
bullet_sound.addMarker('fire', 0, 0.5);
//Killed sound
killed_sound = game.add.audio('killed');
killed_sound.allowMultiple = true;
killed_sound.addMarker('killed', 0, 0.5);
//death music
death_music = game.add.audio('death_music');
death_music.allowMultiple = true;
death_music.addMarker('death_music', 0, 10);
//groups of bullets and enemies
golis=game.add.group();
enemies=game.add.group();
powers=game.add.group();
//fire bullet loop
fireLoop=game.time.events.loop(Phaser.Timer.SECOND*1/buttetSpwanSpeed, fireBullet, this);
//this.game.input.onTap.add(fireBullet, this);
//create ememy loop
enemyLoop=game.time.events.loop(Phaser.Timer.SECOND*1/enemySpwanSpeed, createEnemy, this);
//change ememy speed and enemy spwan speed loop
enemySpeedLoop=game.time.events.loop(Phaser.Timer.SECOND*1.5, changeEnemySpeed, this);
//give powerup
powerUp=game.time.events.loop(Phaser.Timer.SECOND*20, powerFun, this);
},
update: function(){
//scrolling background
this.background.tilePosition.y+=2;
//keybord control
if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
{
this.ship.y-=2;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
this.ship.y+=2;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
this.ship.x+=2;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
this.ship.x-=2;
}
//dont go out
if(this.ship.y<0+this.ship.height/2)
{
this.ship.y=0+this.ship.height/2;
}
if(this.ship.y>this.game.world.height-this.ship.height/2)
{
this.ship.y=this.game.world.height-this.ship.height/2;
}
if(this.ship.x<0+this.ship.width/2)
{
this.ship.x=0+this.ship.width/2;
}
if(this.ship.x>this.game.world.width-this.ship.width/2)
{
this.ship.x=this.game.world.width-this.ship.width/2;
}
//check for collisions
game.physics.arcade.overlap(golis,enemies,b_e_collide,null,this);
game.physics.arcade.overlap(this.ship,enemies,s_e_collide,null,this);
game.physics.arcade.overlap(this.ship,powers,s_power1_collide,null,this);
},
};
//setting start game conditions
function setStart(){
buttetSpwanSpeed=2;
bulletSpeed=2000;
enemySpwanSpeed=1;
enemySpeed=300;
score=0;
bulletSize=1.2
}
//fire bullet function
function fireBullet(){
goli=this.game.add.sprite(this.ship.x,this.ship.y-this.ship.height/2,'goli');
goli.anchor.setTo(0.5);
goli.scale.setTo(bulletSize,1);
goli.checkWorldBounds = true;
goli.outOfBoundsKill = true;
//adding to group
golis.add(goli);
game.world.moveDown(goli);
game.physics.arcade.enable(goli);
goli.body.collisonWorldBounds=true;
goli.body.velocity.y=-bulletSpeed;
bullet_sound.play("fire");
}
//create enemy function
function createEnemy(){
enemyNo=game.rnd.integerInRange(1, 5);
x1=game.rnd.integerInRange(0,this.game.world.width);
x2=game.rnd.integerInRange(0,this.game.world.width);
enemy=this.game.add.sprite(x1,10,'enemy'+enemyNo);
enemy.anchor.setTo(0.5);
enemy.scale.setTo(0.4);
enemy.checkWorldBounds = true;
enemies.add(enemy);
enemy.outOfBoundsKill = true;
game.physics.arcade.enable(enemy);
enemy.body.collisonWorldBounds=true;
enemy.angle=90;
enemy.no=enemyNo;
//moving enemy
angleRedian=game.physics.arcade.moveToXY(enemy, x2, this.game.world.height+enemy.height, enemySpeed,0);
angleDegree=angleRedian*57.2958;
enemy.angle=90+angleDegree;
}
//runs when bullet collide to enemy
function b_e_collide(goli,enemy){
//blast
blast=this.game.add.sprite(enemy.x,enemy.y,'blast');
blast.anchor.setTo(0.5);
blast.scale.setTo(0.5);
var explosion=blast.animations.add('explosion');
blast.animations.play('explosion',30,false,true);
//killing
goli.kill();
enemy.kill();
//update scores
if(enemy.no<4)
{
score+=1;
killed_sound.play('killed');
}
this.scoreText.text = 'Kills: ' + score;
}
//runs when ship collide to enemy
function s_e_collide(ship,enemy){
blast=this.game.add.sprite(enemy.x,enemy.y,'blast');
blast.anchor.setTo(0.5);
blast.scale.setTo(0.5);
var explosion=blast.animations.add('explosion');
blast.animations.play('explosion',10,false,true);
ship.kill();
enemy.kill();
//music.stop();
this.scoreText.kill();
death_music.play("death_music");
game.time.events.remove(fireLoop);
game.time.events.add(Phaser.Timer.SECOND * 2, function() {
fianlScore = this.game.add.text(this.game.world.centerX,this.game.world.centerY, 'KILL: '+score, { fontSize: '32px', fill: 'yellow' });
fianlScore.anchor.setTo(0.5);
gameOverText = this.game.add.text(this.game.world.centerX,this.game.world.centerY - fianlScore.height, 'GAME OVER', { fontSize: '32px', fill: 'red' });
gameOverText.anchor.setTo(0.5);
//restart button
restart=this.game.add.sprite(this.game.world.centerX,this.game.world.centerY + fianlScore.height+10,'restart');
restart.anchor.setTo(0.5);
restart.scale.setTo(0.05,0.05);
restart.inputEnabled = true;
restart.events.onInputDown.add(restartGame, this);
game.time.events.stop();
}, this);
}
//runs when ship collide power1
function s_power1_collide(ship,power){
power.kill();
game.time.events.remove(fireLoop);
fireLoop=game.time.events.loop(Phaser.Timer.SECOND*1/10, fireBullet, this);
game.time.events.add(Phaser.Timer.SECOND * 10, function(){
game.time.events.remove(fireLoop);
fireLoop=game.time.events.loop(Phaser.Timer.SECOND*1/buttetSpwanSpeed, fireBullet, this);
},this);
}
function changeEnemySpeed()
{
if(enemySpeed<=900)
{
enemySpeed+=5;
}
if(enemySpwanSpeed<=3)
{
enemySpwanSpeed+=0.025;
}
enemyLoop.delay=Phaser.Timer.SECOND*1/enemySpwanSpeed;
}
//send power up
function powerFun()
{
x1=game.rnd.integerInRange(0,this.game.world.width);
x2=game.rnd.integerInRange(0,this.game.world.width);
power=this.game.add.sprite(x1,10,'power1');
power.anchor.setTo(0.5);
var shine=power.animations.add('shine');
power.animations.play('shine',5,true,true);
power.checkWorldBounds = true;
power.outOfBoundsKill = true;
powers.add(power);
game.physics.arcade.enable(power);
power.body.collisonWorldBounds=true;
game.physics.arcade.moveToXY(power, x2, this.game.world.height+power.height, 400,0);
powerDelay=game.rnd.integerInRange(20,35);
powerUp.delay=Phaser.Timer.SECOND*powerDelay;
}
function restartGame(){
setStart();
game.time.events.start();
game.state.start("PreGameState");
}
game.state.add("GameState",GameState);
game.state.add("BootState",BootState);
game.state.add("LoadingState",LoadingState);
game.state.add("PreGameState",PreGameState);
game.state.start("BootState");
since the game is so small in size I think it should run smoothly on mobile devices.
it runs good on some high end mobile devices but gets slow as time progresses.
this is my first game so I am not very good with game designing concepts.

Hi I currently got this issue fixed myself for my games cross platform.
Things I did were
Load alll sprites right at my main screen/or loading screen
If you have reusable sprites use the command .kill() not .destory() which will take more memory to reload sprite unless the sprite is not coming back to screen then it’s ok to destroy.
Recycle everything let’s say you use a bullet asoon as it hits the wall boom kill and get it back.
And sad part in some cases even by doing sometimes it’ll still lag and have some glitches here and there you just have to see at what point is happening. Use break points to see exactly what sprites are causing it and consider also if the image doesn’t have transparency to use .jpeg
Good luck hope this helps

If it works fine on your desktop, most likely it's an issue with the asset sizes being too big. Reduce all of your assets 1/2 of the size. Phaser has to load all of the assets into cache, then it reduces the pixel size of those files in the engine.

In the mobile phone the processing capacity is lower than in the desktop.
Generally the architecture of a mobile Cpu is usually optimized to save energy. When you are on a desktop, the x86 or x64 architecture is optimized for processing of data.
Therefore it is very important to test the performance of the application on the target device.
You need to reduce creation of objects, loading images or objects when the game is playing. I have better experience with my game just hidging and showing the same objects (enemies), instead of destroying objects (Enemies or Visual elements) and creating again while play. Because when a game create a new instance, the CPU load the same again. This change no make diference in high CPU but is very better in low CPU. Maybe it help you.

Related

Phaser 3: Change "Hitbox"/Interactive area of sprite without physics

The game I'm creating doesn't require any physics, however you are able to interact when hovering over/clicking on the sprite by using sprite.setInteractive({cursor: "pointer"});, sprite.on('pointermove', function(activePointer) {...}); and similar. However I noticed two issues with that:
The sprite has some area which are transparent. The interactive functions will still trigger when clicking on those transparent areas, which is unideal.
When playing a sprite animation, the interactive area doesn't seem to entirely (at all?) change, thus if the sprite ends on a frame bigger than the previous, there end up being small areas I can't interact with.
One option I thought of was to create a polygon over my sprite, which covers the area I want to be interactive. However before I do that, I simply wanted to ask if there are simpler ways to fix these issues.
Was trying to find an answer for this myself just now..
Think Make Pixel Perfect is what you're looking for.
this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect());
https://newdocs.phaser.io/docs/3.54.0/focus/Phaser.Input.InputPlugin-makePixelPerfect
This might not be the best solution, but I would solve this problem like this. (If I don't want to use physics, and if it doesn't impact the performance too much)
I would check in the event-handler, if at the mouse-position the pixel is transparent or so, this is more exact and less work, than using bounding-boxes.
You would have to do some minor calculations, but it should work well.
btw.: if the origin is not 0, you would would have to compensate in the calculations for this. (in this example, the origin offset is implemented)
Here is a demo, for the click event:
let Scene = {
preload ()
{
this.load.spritesheet('brawler', 'https://labs.phaser.io/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
},
create ()
{
// Animation set
this.anims.create({
key: 'walk',
frames: this.anims.generateFrameNumbers('brawler', { frames: [ 0, 1, 2, 3 ] }),
frameRate: 8,
repeat: -1
});
// create sprite
const cody = this.add.sprite(200, 100).setOrigin(0);
cody.play('walk');
cody.setInteractive();
// just info text
this.mytext = this.add.text(10, 10, 'Click the Sprite, or close to it ...', { fontFamily: 'Arial' });
// event to watch
cody.on('pointerdown', function (pointer) {
// calculate x,y position of the sprite to check
let x = (pointer.x - cody.x) / (cody.displayWidth / cody.width)
let y = (pointer.y - cody.y) / (cody.displayHeight / cody.height);
// just checking if the properties are set
if(cody.anims && cody.anims.currentFrame){
let currentFrame = cody.anims.currentFrame;
let pixelColor = this.textures.getPixel(x, y, currentFrame.textureKey, currentFrame.textureFrame);
// alpha > 0 a visible pixel of the sprite, is clicked
if(pixelColor.a > 0) {
this.mytext.text = 'Hit';
} else {
this.mytext.text = 'No Hit';
}
// just reset the textmessage
setTimeout(_ => this.mytext.text = 'Click the Sprite, or close to it ...' , 1000);
}
}, this);
}
};
const config = {
type: Phaser.AUTO,
width: 400,
height: 200,
scene: Scene
};
const game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>

Phaser P2 Player kick ball and add Impulse on hit

I need help for a school project and want to code a game like Headsoccer in Phaser with P2 Physics, I already have two players, two goals and a ball that can collide with each other. Now I want to add a kick animation and a hitbox for the kick which when kicking the ball applies an impulse or some sort of force from the kick. How could I do that?
Thanks.
Here is some Code
Would be nice if you can give me some advice on how to structre my code better or if i can change something
function create() {
game.world.setBounds(0, 0, 800, 500);
game.physics.startSystem(Phaser.Physics.P2JS);
//game.physics.p2.enable([ player, player2, fussball, goal, latte ], true);
//game.physics.arcade.gravity.y = 200;
game.add.tileSprite(0, 0, 800, 600, 'Spielfeld');
game.physics.p2.gravity.y = 600;
goal = game.add.sprite(35, 428, 'goal');
game.physics.p2.enable(goal,true);
goal.body.static = true;
goal.physicsBodyType = Phaser.Physics.P2JS;
goal.body.data.shapes[0].sensor = true;
player = game.add.sprite(100, 500, 'player');
game.physics.p2.enable(player,true);
player.anchor.setTo(0.5, 0.5);
player.body.collideWorldBounds = true;
player.body.fixedRotation = true;
player.body.clearShapes();
player.body.loadPolygon('playerPhysics','player');
player2 = game.add.sprite(500, 500, 'player');
game.physics.p2.enable(player2);
player2.anchor.setTo(0.5, 0.5);
player2.body.collideWorldBounds = true;
player2.body.fixedRotation = true;
var shape = new p2.Circle();
ball = game.add.sprite( game.world.centerX, game.world.centerY, 'ball');
game.physics.p2.enable(ball);
ball.anchor.setTo(0.5, 0.5);
ball.body.collideWorldBounds = true;
ball.body.data.gravityScale = 1;
ball.body.clearShapes();
ball.body.addCircle(shape);
My game looks like this, and I showed the hitbox of Player 1 and Goal.
Since we don't have any code to work with, I'm assuming you have something like the official Impact Events example code in place.
In that case, you could play an animation when one of the players collides with the ball. In the example above, that would be changing this method to play the animation (instead of changing the sprite's alpha):
function hitPanda(body1, body2) {
body2.sprite.alpha -= 0.1; // Remove/replace this line.
// Add the playing of the kick animation.
body1.play('kick');
}
In this same area you could then apply a speed boost to the ball.

Phaser scrolling background

My goal is to make a sprite bigger than the screen and have the user scroll to see the different parts of it, so I wanted to ask if Phaser had any sprite eventListener-functions such as:
var canvas = window.document.getElementsByTagName('canvas')[0],
prevX = 0, prevY = 0, mouseDown = false;
where canvas can be used as
canvas.addEventListener('mousedown',function(e){
});
canvas.addEventListener('mousemove',function(e){
});
Here is how I did it.
In your update function:
if (this.game.input.activePointer.isDown) {
if (this.game.origDragPoint) {
// move the camera by the amount the mouse has moved since last update
this.game.camera.x += this.game.origDragPoint.x - this.game.input.activePointer.position.x;
this.game.camera.y += this.game.origDragPoint.y - this.game.input.activePointer.position.y;
}
// set new drag origin to current position
this.game.origDragPoint = this.game.input.activePointer.position.clone();
}
else {
this.game.origDragPoint = null;
}
If using the camera is OK for you, you can try this Phaser 2 plugin: https://jdnichollsc.github.io/Phaser-Kinetic-Scrolling-Plugin/
With this plugin you can enable vertical and horizontal scroll to simulate scrolling into the canvas element used by Phaser, also you can customize the movement before to initialize the plugin, example:
var game = new Phaser.Game(400, 400, Phaser.AUTO, '', {
init: function () {
//Load the plugin
this.game.kineticScrolling = this.game.plugins.add(Phaser.Plugin.KineticScrolling);
},
create: function () {
//Configure the plugin
this.game.kineticScrolling.configure({
kineticMovement: true,
timeConstantScroll: 325, //really mimic iOS
horizontalScroll: true,
verticalScroll: false,
horizontalWheel: true,
verticalWheel: false,
deltaWheel: 40
});
//Starts the plugin
this.game.kineticScrolling.start();
//Changing the world size
this.game.world.setBounds(0, 0, 800, 800);
},
stopScrolling: function () {
//Stop the plugin
this.game.kineticScrolling.stop();
}
});
Also there's a fork for Phaser 3, check the repo from GitHub.
Regards, Nicholls

Performance jQuery Ajax load game sources display as modal

I have a base website system which is using ajax load content without refreshing pages. I have a game page that load many html5 game links via ajax json and when I click on any games it will load the game source files which display as pop up. I am wonder while I'm playing then if I click the close button for stopping the game and then I remove the element of the source files game. Will it free up the memory? As I have noticed, it seems to getting slow the broswer. Anyone has experienced with that, please share with me.
Note: I need some suggestions in order to remove the elements and free up the memory.
eg:
<div id="pop-up">
<a id="close" href="#">Close Button</a>
<div id="inner-pop-up">
<script src="game sources" type="text/javascript"></script>
<script src="game sources" type="text/javascript"></script>
<script src="game sources" type="text/javascript"></script>
<div id="game">
<canvas></canvas>
</div>
</div>
</div>
$('#pop-up').modal('view', {
speed: 750,
close: '.close-favourite',
easing: 'easeOutBounce',
animation: 'top',
position: 'center',
overlayClose: true
});
$('#close').on('click', function() {
$('#inner-pop-up').children().remove();
});
The only real way to free up any resources used by script functions is to add a JavaScript file that basically calls delete window.myFunction for every possible object and function (functions are objects really) your specified script files may define. To me, for obvious reasons, this is a really bad idea.
Note that these objects would be script (window) objects so you cannot use .remove() to remove those.
I would also note that your should use $('#inner-pop-up').empty(); rather than your $('#inner-pop-up').children().remove(); since that would remove the text of the element if any, as well and specifically removes the data and event handlers from those elements prior to removal from the DOM.
You might have some very specific functions and objects from your scripts that you might want to remove here but only the contents of your scripts would tell that. If you create global window objects that gets really messy fast.
Note it is REALLY hard to determine what a script file creates and then remove it.
To prove a point open up your favorite browser console and execute $("script").remove(). stuff in that script still runs.
Eg: This is my game file which contained the object like that
FootballChallenge.Game = function (game) {
FootballChallenge._scoreText = null;
FootballChallenge._score = 0;
FootballChallenge.kickBoard;
this._preventClick = true;
FootballChallenge.kaboomGroup;
FootballChallenge.ball;
FootballChallenge.shoe;
FootballChallenge.self;
};
FootballChallenge.Game.prototype = {
create: function () {
FootballChallenge.self = this.game;
this.game.physics.startSystem(Phaser.Physics.ARCADE);
this.game.physics.arcade.checkCollision.up = false;
this.bg = this.game.add.image(this.game.world.centerX, this.game.world.centerY, 'field');
this.bg.anchor.setTo(0.5);
FootballChallenge.kickBoard = this.game.add.sprite(10, 20, 'kickBoard');
FootballChallenge._scoreText = this.game.add.bitmapText(0, FootballChallenge.kickBoard.height/2 + 20, 'white-font', ''+FootballChallenge._score+'', 32);
FootballChallenge._scoreText.align = 'center';
FootballChallenge._scoreText.x = (FootballChallenge.kickBoard.width-FootballChallenge._scoreText.width + 20)/2;
FootballChallenge.ball = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY - 100, 'ball');
this.game.physics.arcade.enable(FootballChallenge.ball);
FootballChallenge.ball.anchor.setTo(0.5);
FootballChallenge.ball.scale.setTo(0.5);
FootballChallenge.ball.body.collideWorldBounds = true;
FootballChallenge.ball.body.gravity.y = 0;
FootballChallenge.ball.body.bounce.setTo(1);
FootballChallenge.shoe = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY, 'shoe');
this.game.physics.arcade.enable(FootballChallenge.shoe);
FootballChallenge.shoe.anchor.setTo(0.5);
FootballChallenge.shoe.scale.setTo(0.5);
FootballChallenge.shoe.body.setSize(130,50,0,20);
FootballChallenge.shoe.body.collideWorldBounds = true;
FootballChallenge.kaboomGroup = this.game.add.group();
FootballChallenge.kaboomGroup.createMultiple(10, 'kaboom');
FootballChallenge.kaboomGroup.forEach(this.explosion, this);
this.play();
},
explosion: function(kick) {
kick.anchor.x = 0.7;
kick.anchor.y = 0.5;
kick.animations.add('kaboom');
},
play: function() {
this.bitmask = this.game.make.bitmapData(this.game.width, this.game.height);
this.bitmask.fill(50,50,50);
this.mask = this.game.add.sprite(0, 0, this.bitmask);
this.mask.tint = 0x000000;
this.mask.alpha = 0.6;
this.game.paused = true;
var pausedText = this.game.add.bitmapText(this.game.world.centerX, this.game.world.centerY - 200, 'white-font', 'click anywhere to begin!', 32);
pausedText.align = 'center';
pausedText.tint = 0xff0e25;
pausedText.anchor.setTo(0.5);
this.game.input.onDown.add(function(){
pausedText.destroy();
this.game.paused = false;
this.mask.alpha = 0;
FootballChallenge.ball.body.gravity.y = 1500;
this.game.canvas.style.cursor = "none";
}, this);
},
countScore: function(ball, shoe) {
ball.body.velocity.y = -1000;
ball.body.gravity.x = FootballChallenge.self.rnd.integerInRange(-80, 80);
FootballChallenge._scoreText.setText(FootballChallenge._score +=1);
FootballChallenge._scoreText.x = (FootballChallenge.kickBoard.width-FootballChallenge._scoreText.width + 20)/2;
var boom = FootballChallenge.kaboomGroup.getFirstExists(false);
boom.reset(shoe.x, shoe.y);
boom.play('kaboom', 40, false, true);
},
lose: function() {
this.game.state.start('EndGame');
},
update: function() {
if(FootballChallenge.ball.y >= this.game.height - 100) {
FootballChallenge.ball.body.gravity = false;
this.game.time.events.add(Phaser.Timer.SECOND * 0.2, this.lose, this);
}
this.game.physics.arcade.collide(FootballChallenge.ball, FootballChallenge.shoe, this.countScore);
this.game.physics.arcade.moveToPointer(FootballChallenge.shoe, 30, this.game.input.activePointer, 50);
}
};

Phaser loading screen animation

So I am working on a simple android app using Phaser. But I was looking if it is possible to create a loading screen that uses a spritesheet animation or programmatically do an animation other than just a simple crop how phaser does it?
this.preloadBar = this.add.sprite(50, 170, 'preloaderBar');
this.load.setPreloadSprite(this.preloadBar);
Thanks in advance :)
In order to achieve that, i have a boot state where i initialise various game related utilities and the sprite i want to have during the loading screen. Then i just load the preloader state where everything else is being loaded and i just put the previous sprite on the screen. When everything finishes, main game, or menu state starts.
Here is an example:
Test.Boot.prototype = {
init: function () {
//general game config like scaleManager
},
preload: function () {
this.game.stage.backgroundColor = '#000000';
// the sprite you want to show during loading
this.game.load.atlasJSONHash('logo', 'asset/images/hand.png', 'asset/images/hand.json');
},
create: function () {
this.state.start('Preloader');
}
};
// Preloader.js
Test.Preloader.prototype = {
preload: function() {
//add the animation
this.logo = this.add.sprite(this.world.width/2, this.world.height/2, 'logo');
this.logo.anchor.set(0.5, 0.5);
this.logo.animations.add('shake',[8,9,10,11,12,13,14,15,16,17,17,8,9,8]);
this.logo.animations.play('shake', 60, true);
//load all the other assets
this.game.load.image("hero", "asset/images/hero.png");
this.game.load.image("clouds", "asset/images/sky3.jpg");
//this.game.load.image("rope", "asset/images/rope.png");
this.game.load.atlasJSONHash('items', 'asset/images/items.png', 'asset/images/items.json');
this.game.load.physics('physicsData', 'asset/images/polygon.json');
},
create: function() {
this.game.stage.backgroundColor = '#1589FF';
//A simple fade out effect
this.game.time.events.add(Phaser.Timer.SECOND * 2.0, function() {
var tween = this.add.tween(this.logo)
.to({alpha: 0}, 750, Phaser.Easing.Linear.none);
tween.onComplete.add(function() {
this.logo.destroy();
this.startGame();
}, this);
tween.start();
}, this);
},
startGame: function() {
this.state.start('MainMenu');
},
};
There is a video tutorial with similar technique here if you want to know more.

Categories

Resources