Why my score is not updating properly. It overwrites the last one but it does not update itself. I looked some of the tutorials at phaser.io and in the examples there, the score is updating itself the way I used scoreUpdateLink. Maybe the problem is somewhere else in the code and I cannot find it.
Here is my code:
var game = new Phaser.Game(1000, 800, Phaser.CANVAS, "game_div");
var spaceField,
backgroundSpeed,
player,
cursors,
bullets,
bulletsTime = 0,
fireButton,
bullet,
bulletSound,
engineDownSound,
enemies,
score = 0,
scoreText,
winText;
var mainState = {
preload: function () {
//id
game.load.image("starfield", "images/space.png");
game.load.image("player", "images/playerSmall.png");
game.load.image("bullet", "images/fire.png");
game.load.image("enemy", "images/enemyShips.png");
// audio
game.load.audio("engineDownSound", "sounds/engineDown.ogg");
game.load.audio("bulletSound", "sounds/blaster.mp3");
},
create: function () {
// Full screen when clicking with the mouse on the screen
game.scale.fullScreenScaleMode = Phaser.ScaleManager.EXACT_FIT;
game.input.onDown.add(goFull, this);
// background
spaceField = game.add.tileSprite(0, 0, 1000, 800, "starfield");
backgroundSpeed = 2;
game.physics.setBoundsToWorld();
// player spaceship + adding physics + player movement
player = game.add.sprite(game.world.centerX, game.world.centerY + 300, "player");
game.physics.enable(player, Phaser.Physics.ARCADE);
player.body.collideWorldBounds = true; // Player cannot leave the spacefield - must be added after physics
cursors = game.input.keyboard.createCursorKeys();
engineDownSound = game.add.audio("engineDownSound");
// Fire bullets
bullets = game.add.group();
bullets.enableBody = true;
bullets.physicsBodyType = Phaser.Physics.ARCADE; // Enabling physics for bullets
bullets.createMultiple(30, "bullet");
bullets.setAll("anchor.x", 0.5);
bullets.setAll("anchor.y", 1);
bullets.setAll("outOfBoundsKill", true); // Checks if the bullet is off screen so we can reuse it
bullets.setAll("checkWorldBounds", true);
fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
bulletSound = game.add.audio("bulletSound");
// Enemies
enemies = game.add.group();
enemies.enableBody = true;
enemies.physicsBodyType = Phaser.Physics.ARCADE;
createEnemies();
},
update: function () {
// Making scrolling background
spaceField.tilePosition.y += backgroundSpeed;
player.body.velocity.x = 0; // Everytime when key is not pressed the player does not move
player.body.velocity.y = 0;
// Checking which key is pressed
if (cursors.up.isDown) {
//player.checkWorldBounds = true;
//player.events.onOutOfBounds.add(playerOutOfBoundsTop, this);
player.body.velocity.y = -350;
}
if (cursors.down.isDown) {
player.checkWorldBounds = true;
// player.events.onOutOfBounds.add(playerOutOfBoundsBottom, this);
player.body.velocity.y = 350;
engineDownSound.play();
}
if (cursors.left.isDown) {
player.body.velocity.x = -350;
}
if (cursors.right.isDown) {
player.body.velocity.x = 350;
}
if (fireButton.isDown) {
fireBullet();
}
// Collision and enemy death
game.physics.arcade.overlap(bullets, enemies, collisionHandler, null, this);
// Score bar
scoreText = game.add.text(0, 750, "Score: 0", {font: "40px Phaser.RetroFont.TEXT_SET10", fill: "gold"});
winText = game.add.text(game.world.centerX - 200, game.world.centerY, "You saved the Galaxy!", {font: "60px Phaser.RetroFont.TEXT_SET10", fill: "gold"});
winText.visible = false;
// updating score on display
scoreText.text = "Score: " + score;
if(score === 4800) {
winText.visible = true;
//scoreText.visible = false;
}
}
};
function fireBullet() {
if (game.time.now > bulletsTime) {
bullet = bullets.getFirstExists(false);
if (bullet) {
bullet.reset(player.x + 28, player.y);
bullet.bulletAngleOffset = 90;
bullet.bulletAngleVariance = 30;
bullet.body.velocity.y = -400;
bulletsTime = game.time.now + 200;
bulletSound.play();
}
}
}
/*function playerOutOfBoundsTop(player) {
// Move the Spaceship to the top of the screen again
player.reset(player.x, 60);
}*/
function createEnemies() {
let x,
y,
enemy;
for (y = 0; y < 4; y += 1) {
for (x = 0; x < 12; x += 1) {
enemy = enemies.create(x * 48, y * 50, "enemy"); // Creates the enemies
enemy.anchor.setTo(0.5, 0.5);
}
}
enemies.x = 100;
enemies.y = 50;
// Tween is used to move enemies across the map
var tween = game.add.tween(enemies).to({
x: 200
}, 2000, Phaser.Easing.Linear.None, true, 0, 1000, true);
tween.onRepeat.add(descend, this);
}
function descend() {
enemies.y += 20;
}
function goFull() {
if (game.scale.isFullScreen) {
game.scale.stopFullScreen();
} else {
game.scale.startFullScreen(false);
}
}
function collisionHandler(bullet, enemy) {
bullet.kill();
enemy.kill();
// Updating score on hit
score += 100;
}
//id
game.state.add('mainState', mainState);
game.state.start("mainState");
I think you should move your scoreText in create function and when you change your score, just update the text :
function collisionHandler(bullet, enemy) {
bullet.kill();
enemy.kill();
// Updating score on hit
score += 100;
scoreText.text = "Score: " + score;
}
It has fairly simple solution.
var game = new Phaser.Game(1000, 800, Phaser.CANVAS, "game_div");
var spaceField,
backgroundSpeed,
player,
cursors,
bullets,
bulletsTime = 0,
fireButton,
bullet,
bulletSound,
engineDownSound,
enemies,
score = 0,
scoreText,
winText;
var mainState = {
preload: function () {
//id
game.load.image("starfield", "images/space.png");
game.load.image("player", "images/playerSmall.png");
game.load.image("bullet", "images/fire.png");
game.load.image("enemy", "images/enemyShips.png");
// audio
game.load.audio("engineDownSound", "sounds/engineDown.ogg");
game.load.audio("bulletSound", "sounds/blaster.mp3");
},
create: function () {
// Full screen when clicking with the mouse on the screen
game.scale.fullScreenScaleMode = Phaser.ScaleManager.EXACT_FIT;
game.input.onDown.add(goFull, this);
// background
spaceField = game.add.tileSprite(0, 0, 1000, 800, "starfield");
backgroundSpeed = 2;
game.physics.setBoundsToWorld();
// player spaceship + adding physics + player movement
player = game.add.sprite(game.world.centerX, game.world.centerY + 300, "player");
game.physics.enable(player, Phaser.Physics.ARCADE);
player.body.collideWorldBounds = true; // Player cannot leave the spacefield - must be added after physics
cursors = game.input.keyboard.createCursorKeys();
engineDownSound = game.add.audio("engineDownSound");
// Fire bullets
bullets = game.add.group();
bullets.enableBody = true;
bullets.physicsBodyType = Phaser.Physics.ARCADE; // Enabling physics for bullets
bullets.createMultiple(30, "bullet");
bullets.setAll("anchor.x", 0.5);
bullets.setAll("anchor.y", 1);
bullets.setAll("outOfBoundsKill", true); // Checks if the bullet is off screen so we can reuse it
bullets.setAll("checkWorldBounds", true);
fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
bulletSound = game.add.audio("bulletSound");
// Enemies
enemies = game.add.group();
enemies.enableBody = true;
enemies.physicsBodyType = Phaser.Physics.ARCADE;
createEnemies();
// Score bar
scoreText = game.add.text(0, 750, "Score: 0", {font: "40px Phaser.RetroFont.TEXT_SET10", fill: "gold"});
winText = game.add.text(game.world.centerX - 200, game.world.centerY, "You saved the Galaxy!", {font: "60px Phaser.RetroFont.TEXT_SET10", fill: "gold"});
winText.visible = false;
},
update: function () {
// Making scrolling background
spaceField.tilePosition.y += backgroundSpeed;
player.body.velocity.x = 0; // Everytime when key is not pressed the player does not move
player.body.velocity.y = 0;
// Checking which key is pressed
if (cursors.up.isDown) {
//player.checkWorldBounds = true;
//player.events.onOutOfBounds.add(playerOutOfBoundsTop, this);
player.body.velocity.y = -350;
}
if (cursors.down.isDown) {
player.checkWorldBounds = true;
// player.events.onOutOfBounds.add(playerOutOfBoundsBottom, this);
player.body.velocity.y = 350;
engineDownSound.play();
}
if (cursors.left.isDown) {
player.body.velocity.x = -350;
}
if (cursors.right.isDown) {
player.body.velocity.x = 350;
}
if (fireButton.isDown) {
fireBullet();
}
// Collision and enemy death
game.physics.arcade.overlap(bullets, enemies, collisionHandler, null, this);
// updating score on display
scoreText.text = "Score: " + score;
if(score === 4800) {
winText.visible = true;
//scoreText.visible = false;
}
}
};
function fireBullet() {
if (game.time.now > bulletsTime) {
bullet = bullets.getFirstExists(false);
if (bullet) {
bullet.reset(player.x + 28, player.y);
bullet.bulletAngleOffset = 90;
bullet.bulletAngleVariance = 30;
bullet.body.velocity.y = -400;
bulletsTime = game.time.now + 200;
bulletSound.play();
}
}
}
/*function playerOutOfBoundsTop(player) {
// Move the Spaceship to the top of the screen again
player.reset(player.x, 60);
}*/
function createEnemies() {
let x,
y,
enemy;
for (y = 0; y < 4; y += 1) {
for (x = 0; x < 12; x += 1) {
enemy = enemies.create(x * 48, y * 50, "enemy"); // Creates the enemies
enemy.anchor.setTo(0.5, 0.5);
}
}
enemies.x = 100;
enemies.y = 50;
// Tween is used to move enemies across the map
var tween = game.add.tween(enemies).to({
x: 200
}, 2000, Phaser.Easing.Linear.None, true, 0, 1000, true);
tween.onRepeat.add(descend, this);
}
function descend() {
enemies.y += 20;
}
function goFull() {
if (game.scale.isFullScreen) {
game.scale.stopFullScreen();
} else {
game.scale.startFullScreen(false);
}
}
function collisionHandler(bullet, enemy) {
bullet.kill();
enemy.kill();
// Updating score on hit
score += 100;
}
//id
game.state.add('mainState', mainState);
game.state.start("mainState");
Related
so I have a 2d platformer in the works, and I'd like to add walls and platforms to it, but when I try to make a platform, it doesn't stop the player in front of it if they just walk forward, and instead it makes it sort of like a step/stairs.
Here's what I have so far:
var ctx, controller, rectangle, loop;
ctx = document.querySelector("canvas").getContext("2d");
// Screen size
ctx.canvas.height = 200;
ctx.canvas.width = 400;
// Position of Player
rectangle = {
height: 25,
jumping: true,
width: 25,
x: 10,
x_velocity: 0,
y: 0,
y_velocity: 0
};
controller = {
left: false,
right: false,
up: false,
keyListener: function(event) {
var key_state = (event.type == "keydown") ? true : false;
switch (event.keyCode) {
case 37: // Left
controller.left = key_state;
break;
case 39: // Right
controller.right = key_state;
break;
case 38: // Up
controller.up = key_state;
break;
};
}
};
loop = function() {
if (controller.up && rectangle.jumping == false) {
rectangle.y_velocity -= 25;
rectangle.jumping = true;
};
if (controller.left) {
rectangle.x_velocity -= 0.75;
};
if (controller.right) {
rectangle.x_velocity += 0.75;
};
// Gravity
rectangle.y_velocity += 1.5;
rectangle.x += rectangle.x_velocity;
rectangle.y += rectangle.y_velocity;
// Friction
rectangle.x_velocity *= 0.75;
rectangle.y_velocity *= 0.75;
// Floor
if (rectangle.y > 150 - 25) {
rectangle.jumping = false;
rectangle.y = 150 - 25;
rectangle.y_velocity = 0;
};
// Platform
if (rectangle.y > 145 - 25 && rectangle.x > 150 - 25) {
rectangle.jumping = false;
rectangle.y = 145 - 25;
rectangle.y_velocity = 0;
};
// Background
var bg = new Image;
bg.src = "https://i.imgur.com/He3uld9.png";
bg.onload = function() {
ctx.drawImage(bg, 0, 0);
};
// Player
var ply = new Image;
ply.src = "https://i.imgur.com/G4UUkIl.png";
ply.onload = function() {
ctx.drawImage(ply, rectangle.x, rectangle.y);
};
// Floor
var fl = new Image;
fl.src = "https://i.imgur.com/OoKP4Mm.png";
fl.onload = function() {
ctx.drawImage(fl, 0, 150);
};
window.requestAnimationFrame(loop);
};
window.addEventListener("keydown", controller.keyListener);
window.addEventListener("keyup", controller.keyListener);
window.requestAnimationFrame(loop);
<canvas style="border: 1px solid black;"></canvas>
The commented part that says Platform under the JS section is where my code for the platform currently is. As of now, it doesn't have an image or object for you to see it, but if you play the game, it is an invisible platform right above the floor.
What if you try to maintain a blockedRight and a blockedLeft property on the rectangle according to the zone you're in ? For instance, I have implemented a blockedRight boolean in the below where for Platform region, I turn it to true and for a Valid Region , I turn it back to false. Also I add this condition check in controller.right check as well.
So for an obstacle region that comes , you can make a condition that if the person is blockedRight and it tries to jump, you will set the blockedRight again to false. I am assuming the obstacles will be always taken care by jumping unless you have those which are greater than your jump height where more checks come in place.
var ctx, controller, rectangle, loop;
ctx = document.querySelector("canvas").getContext("2d");
// Screen size
ctx.canvas.height = 200;
ctx.canvas.width = 400;
// Position of Player
rectangle = {
height: 25,
jumping: true,
width: 25,
x: 10,
x_velocity: 0,
y: 0,
y_velocity: 0,
blockedRight:false
};
controller = {
left: false,
right: false,
up: false,
keyListener: function(event) {
var key_state = (event.type == "keydown") ? true : false;
switch (event.keyCode) {
case 37: // Left
controller.left = key_state;
break;
case 39: // Right
controller.right = key_state;
break;
case 38: // Up
controller.up = key_state;
break;
};
}
};
loop = function() {
if (controller.up && rectangle.jumping == false) {
rectangle.y_velocity -= 25;
rectangle.jumping = true;
};
if (controller.left) {
rectangle.x_velocity -= 0.75;
};
if (controller.right && !rectangle.blockedRight) {
rectangle.x_velocity += 0.75;
};
// Gravity
rectangle.y_velocity += 1.5;
rectangle.x += rectangle.x_velocity;
rectangle.y += rectangle.y_velocity;
// Friction
rectangle.x_velocity *= 0.75;
rectangle.y_velocity *= 0.75;
// Floor
if (rectangle.y > 150 - 25) {
rectangle.jumping = false;
rectangle.y = 150 - 25;
rectangle.y_velocity = 0;
};
// Valid ground
if(rectangle.x <= 150 - 25){
rectangle.blockedRight = false;
}
// Platform
if (rectangle.y > 145 - 25 && rectangle.x > 150 - 25) {
rectangle.blockedRight = true;
rectangle.jumping = false;
rectangle.y = 145-25;
rectangle.y_velocity = 0;
};
// Background
var bg = new Image;
bg.src = "https://i.imgur.com/He3uld9.png";
bg.onload = function() {
ctx.drawImage(bg, 0, 0);
};
// Player
var ply = new Image;
ply.src = "https://i.imgur.com/G4UUkIl.png";
ply.onload = function() {
ctx.drawImage(ply, rectangle.x, rectangle.y);
};
// Floor
var fl = new Image;
fl.src = "https://i.imgur.com/OoKP4Mm.png";
fl.onload = function() {
ctx.drawImage(fl, 0, 150);
};
window.requestAnimationFrame(loop);
};
window.addEventListener("keydown", controller.keyListener);
window.addEventListener("keyup", controller.keyListener);
window.requestAnimationFrame(loop);
<canvas style="border: 1px solid black;"></canvas>
There are two tanks. One of them is controlled by arrows. I did everything that was necessary so that the tanks could collide, but this does not happen. Why? If this large code is not easy to read, please tell me where I could run the example. Below I commented on the place where the code does not work as it should.
UPDATE
I downloaded a working example here
enter link description here
export default function game() {
const game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser', { preload: preload, create: create, update: update, render: render });
let player;
let cursors;
let fireButton;
let weapon;
let weapon2;
let controls;
let enemy;
function preload() {
game.load.image('player', '../img/game/tank.png');
game.load.image('bullet', '../img/game/bullet.png');
}
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.world.setBounds(0, 0, 800, 600);
player = game.add.sprite(500, 300, 'player');
player.scale.setTo(.1, .1);
player.anchor.setTo(0.5, 0.5);
player.angle = 270;
player.enableBody = true;
cursors = game.input.keyboard.createCursorKeys();
fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
weapon = game.add.weapon(1, 'bullet');
weapon.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;
weapon.bulletAngleOffset = 90;
weapon.bulletSpeed = 400;
weapon.trackSprite(player, 0, 0, false);
weapon.fireAngle = player.angle + 90;
enemy = game.add.sprite(100, 100, 'player');
enemy.scale.setTo(.1, .1);
enemy.anchor.setTo(0.5, 0.5);
enemy.angle = 270;
enemy.enableBody = true;
weapon2 = game.add.weapon(1, 'bullet');
weapon2.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;
weapon2.bulletAngleOffset = 90;
weapon2.bulletSpeed = 1400;
weapon2.trackSprite(enemy, 0, 0, false);
weapon2.fireAngle = enemy.angle + 90;
controls = {
right : this.input.keyboard.addKey(Phaser.Keyboard.D),
left : this.input.keyboard.addKey(Phaser.Keyboard.A),
up : this.input.keyboard.addKey(Phaser.Keyboard.W),
down : this.input.keyboard.addKey(Phaser.Keyboard.S),
fire : this.input.keyboard.addKey(Phaser.Keyboard.Q),
};
game.physics.arcade.enable(player);
game.physics.arcade.enable(enemy);
player.body.immovable = true;
enemy.body.immovable = true;
}
function killThem(enemy, bullet) {
console.dir(weapon);
enemy.kill();
bullet.kill();
}
function update() {
game.physics.arcade.collide(weapon.bullets, enemy, killThem);
game.physics.arcade.collide(weapon2.bullets, player, killThem);
game.physics.arcade.collide(player, enemy); // THIS CODE DOESNT WORK
if (cursors.up.isDown) {
player.y -= 4;
player.angle = 180;
weapon.fireAngle = 270;
} else if (cursors.down.isDown) {
player.y += 4;
player.angle = 0;
weapon.fireAngle = 90;
} else if (cursors.left.isDown) {
player.x -= 4;
player.angle = 90;
weapon.fireAngle = 180;
} else if (cursors.right.isDown) {
player.x += 4;
player.angle = 270;
weapon.fireAngle = 360;
}
if (fireButton.isDown) {
weapon.fire()
}
if (controls.up.isDown) {
enemy.y -= 4;
enemy.angle = 180;
weapon2.fireAngle = 270;
} else if (controls.down.isDown) {
enemy.y += 4;
enemy.angle = 0;
weapon2.fireAngle = 90;
} else if (controls.left.isDown) {
enemy.x -= 4;
enemy.angle = 90;
weapon2.fireAngle = 180;
} else if (controls.right.isDown) {
enemy.x += 4;
enemy.angle = 270;
weapon2.fireAngle = 360;
}
if (controls.fire.isDown) {
weapon2.fire()
}
}
function render() {
weapon.debug()
}
}
const game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser', { preload: preload, create: create, update: update, render: render });
let player;
let enemy;
let cursors;
function preload() {
this.load.baseURL = 'https://raw.githubusercontent.com/nazimboudeffa/assets/master/';
this.load.crossOrigin = 'anonymous';
this.load.image('dude', 'sprites/phaser-dude.png');
this.load.image('alien', 'sprites/phaser-alien.png');
}
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.world.setBounds(0, 0, 800, 600);
player = game.add.sprite(100, 100, 'dude');
game.physics.arcade.enable(player);
player.body.enbable = true;
enemy = game.add.sprite(300, 100, 'alien');
game.physics.arcade.enable(enemy);
enemy.body.enbable = true;
enemy.body.immovable = true;
cursors = game.input.keyboard.createCursorKeys();
}
function update() {
game.physics.arcade.collide(player, enemy, ()=>{console.log("collision")});
if (cursors.up.isDown) {
player.y -= 4;
} else if (cursors.down.isDown) {
player.y += 4;
} else if (cursors.left.isDown) {
player.x -= 4;
} else if (cursors.right.isDown) {
player.x += 4;
}
}
function render() {
var debug = this.game.debug;
debug.phaser(10, 20);
}
<script src="//cdn.jsdelivr.net/npm/phaser-ce#2.13.2"></script>
The problem is simple - objects do not block each other when trying to crash. Whatever I do, the objects ignore each other and pass each other through.
I also noticed that if you change the position X & Y through velocity, then the objects begin to block each other. But this does not suit me, because the velocity increases gradually, and I need the tank to move at linear speed. And you also need to avoid a rebound in a collision. That is, I need the tanks to just stop moving when they crash.
I posted a working example
Click here
const game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser', { preload: preload, create: create, update: update, render: render });
let player;
let cursors;
let fireButton;
let weapon;
let weapon2;
let controls;
let enemy;
function preload() {
game.load.crossOrigin = "Anonymous";
game.load.image('player', 'https://steemitimages.com/640x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516330590/dln77v8bxlbzkrevng0x.png');
game.load.image('bullet', 'https://examples.phaser.io/assets/sprites/bullet.png');
}
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.world.setBounds(0, 0, 800, 600);
player = game.add.sprite(500, 300, 'player');
player.scale.setTo(.1, .1);
player.anchor.setTo(0.5, 0.5);
player.angle = 270;
player.enableBody = true;
cursors = game.input.keyboard.createCursorKeys();
fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
weapon = game.add.weapon(1, 'bullet');
weapon.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;
weapon.bulletAngleOffset = 90;
weapon.bulletSpeed = 400;
weapon.trackSprite(player, 0, 0, false);
weapon.fireAngle = player.angle + 90;
enemy = game.add.sprite(100, 100, 'player');
enemy.scale.setTo(.1, .1);
enemy.anchor.setTo(0.5, 0.5);
enemy.angle = 270;
enemy.enableBody = true;
weapon2 = game.add.weapon(1, 'bullet');
weapon2.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;
weapon2.bulletAngleOffset = 90;
weapon2.bulletSpeed = 1400;
weapon2.trackSprite(enemy, 0, 0, false);
weapon2.fireAngle = enemy.angle + 90;
controls = {
right : this.input.keyboard.addKey(Phaser.Keyboard.D),
left : this.input.keyboard.addKey(Phaser.Keyboard.A),
up : this.input.keyboard.addKey(Phaser.Keyboard.W),
down : this.input.keyboard.addKey(Phaser.Keyboard.S),
fire : this.input.keyboard.addKey(Phaser.Keyboard.Q),
};
game.physics.arcade.enable(player);
game.physics.arcade.enable(enemy);
player.body.immovable = true;
enemy.body.immovable = true;
}
function killThem(enemy, bullet) {
console.dir(weapon);
enemy.kill();
bullet.kill();
}
function update() {
game.physics.arcade.collide(weapon.bullets, enemy, killThem);
game.physics.arcade.collide(weapon2.bullets, player, killThem);
if (cursors.up.isDown) {
player.y -= 4;
player.angle = 180;
weapon.fireAngle = 270;
} else if (cursors.down.isDown) {
player.y += 4;
player.angle = 0;
weapon.fireAngle = 90;
} else if (cursors.left.isDown) {
player.x -= 4;
player.angle = 90;
weapon.fireAngle = 180;
} else if (cursors.right.isDown) {
player.x += 4;
player.angle = 270;
weapon.fireAngle = 360;
}
if (fireButton.isDown) {
weapon.fire()
}
if (controls.up.isDown) {
enemy.y -= 4;
enemy.angle = 180;
weapon2.fireAngle = 270;
} else if (controls.down.isDown) {
enemy.y += 4;
enemy.angle = 0;
weapon2.fireAngle = 90;
} else if (controls.left.isDown) {
enemy.x -= 4;
enemy.angle = 90;
weapon2.fireAngle = 180;
} else if (controls.right.isDown) {
enemy.x += 4;
enemy.angle = 270;
weapon2.fireAngle = 360;
}
if (controls.fire.isDown) {
weapon2.fire()
}
}
function render() {
weapon.debug()
}
The Problem
I am creating a game that involves dodging projectiles. The player is in control of an image of a ship and I dont want the ship to move exactly together as this looks very unrealistic.
The Question
Is there a way to control how fast the image moves, how can i slow the movemnt of the image down?
The Code
var game = create_game();
game.init();
//music
var snd = new Audio("Menu.mp3");
snd.loop = true;
snd.play();
document.getElementById('mute').addEventListener('click', function (evt) {
if ( snd.muted ) {
snd.muted = false
evt.target.innerHTML = 'mute'
}
else {
snd.muted = true
evt.target.innerHTML = 'unmute'
}
})
function create_game() {
debugger;
var level = 1;
var projectiles_per_level = 1;
var min_speed_per_level = 1;
var max_speed_per_level = 2;
var last_projectile_time = 0;
var next_projectile_time = 0;
var width = 600;
var height = 500;
var delay = 1000;
var item_width = 30;
var item_height = 30;
var total_projectiles = 0;
var projectile_img = new Image();
var projectile_w = 30;
var projectile_h = 30;
var player_img = new Image();
var c, ctx;
var projectiles = [];
var player = {
x: 200,
y: 400,
score: 0
};
function init() {
projectile_img.src = "projectile.png";
player_img.src = "player.png";
level = 1;
total_projectiles = 0;
projectiles = [];
c = document.getElementById("c");
ctx = c.getContext("2d");
ctx.fillStyle = "#ff6600";
ctx.fillRect(0, 0, 500, 600);
c.addEventListener("mousemove", function (e) {
//moving over the canvas.
var bounding_box = c.getBoundingClientRect();
player.x = (e.clientX - bounding_box.left) * (c.width / bounding_box.width) - player_img.width / 2;
}, false);
setupProjectiles();
requestAnimationFrame(tick);
}
function setupProjectiles() {
var max_projectiles = level * projectiles_per_level;
while (projectiles.length < max_projectiles) {
initProjectile(projectiles.length);
}
}
function initProjectile(index) {
var max_speed = max_speed_per_level * level;
var min_speed = min_speed_per_level * level;
projectiles[index] = {
x: Math.round(Math.random() * (width - 2 * projectile_w)) + projectile_w,
y: -projectile_h,
v: Math.round(Math.random() * (max_speed - min_speed)) + min_speed,
delay: Date.now() + Math.random() * delay
}
total_projectiles++;
}
function collision(projectile) {
if (projectile.y + projectile_img.height < player.y + 74) {
return false;
}
if (projectile.y > player.y + 74) {
return false;
}
if (projectile.x + projectile_img.width < player.x + 177) {
return false;
}
if (projectile.x > player.x + 177) {
return false;
}
return true;
}
function maybeIncreaseDifficulty() {
level = Math.max(1, Math.ceil(player.score / 10));
setupProjectiles();
}
function tick() {
var i;
var projectile;
var dateNow = Date.now();
c.width = c.width;
for (i = 0; i < projectiles.length; i++) {
projectile = projectiles[i];
if (dateNow > projectile.delay) {
projectile.y += projectile.v;
if (collision(projectile)) {
initProjectile(i);
player.score++;
} else if (projectile.y > height) {
initProjectile(i);
} else {
ctx.drawImage(projectile_img, projectile.x, projectile.y);
}
}
}
ctx.font = "bold 24px sans-serif";
ctx.fillStyle = "#ff6600";
ctx.fillText(player.score, c.width - 50, 50);
ctx.fillText("Level: " + level, 20, 50);
ctx.drawImage(player_img, player.x, player.y);
maybeIncreaseDifficulty();
requestAnimationFrame(tick);
}
return {
init: init
};
}
https://jsfiddle.net/a6nmy804/4/ (Broken)
Throttle the player's movement using a "timeout" countdown
Create a global var playerFreezeCountdown=0.
In mousemove change player.x only if playerFreezeCountdown<=0.
If playerFreezeCountdown>0 you don't change player.x.
If playerFreezeCountdown<=0 you both change player.x and also set playerFreezeCountdown to a desired "tick timeout" value: playerFreezeCountdown=5. This timeout will cause prevent the player from moving their ship until 5 ticks have passed.
In tick, always decrement playerFreezeCountdown--. This will indirectly allow a change to player.x after when playerFreezeCountdown is decremented to zero or below zero.
Im having the same problem again, i dont know how to fix this. Ive notced though the error pops up when the blue enemy reaches the bottom. Please help!
JSBin Format click edit on top right corner to edit code
Code:
var game = new Phaser.Game(500, 550, Phaser.CANVAS, 'gameDiv');
var CountDown = {
preload: function() {
},
update: function() {
},
render: function() {
}
}
var player;
var enemy;
var bullets;
var shields;
var enemies;
var greenEnemies
var explosions;
var score = 0;
var scoreText;
var bulletTimer = 0;
var blueEnemies;
var mainState = {
preload: function() {
game.load.image('background', 'http://s1.postimg.org/nqynk9tkv/starfield.png')
game.load.image('player', 'http://s28.postimg.org/9qdf4xrfx/145103252914234.gif')
game.load.image('bullet', 'http://s9.postimg.org/z2bptetxn/bullet.png');
game.load.image('green', 'http://s28.postimg.org/kpmq4byt5/enemy_green.png')
game.load.spritesheet('explosionAnim', 'https://raw.githubusercontent.com/jschomay/phaser-demo-game/master/assets/explode.png', 128, 128)
game.load.bitmapFont('spacefont', 'https://raw.githubusercontent.com/jschomay/phaser-demo-game/master/assets/spacefont/spacefont.png', 'https://rawgit.com/jschomay/phaser-demo-game/master/assets/spacefont/spacefont.xml');
game.load.image('blue', 'https://raw.githubusercontent.com/jschomay/phaser-demo-game/master/assets/enemy-blue.png')
},
create: function() {
this.backgroundImg = this.game.add.tileSprite(0, 0, 500, 550, 'background')
player = game.add.sprite(game.world.centerX, 500, 'player')
player.health = 100;
player.anchor.setTo(0.5)
player.scale.setTo(0.25)
game.physics.arcade.enable(player);
game.physics.enable(player, Phaser.Physics.ARCADE);
player.body.collideWorldBounds = true;
this.game.inputEnabled = true;
this.game.input.useHandCursor = true;
player.body.maxVelocity.setTo(400, 400)
player.body.drag.setTo(400, 400)
// The baddies!
greenEnemies = game.add.group();
greenEnemies.enableBody = true;
greenEnemies.physicsBodyType = Phaser.Physics.ARCADE;
greenEnemies.createMultiple(5, 'green');
greenEnemies.setAll('anchor.x', 0.5);
greenEnemies.setAll('anchor.y', 0.5);
greenEnemies.setAll('scale.x', 0.5);
greenEnemies.setAll('scale.y', 0.5);
greenEnemies.setAll('angle', 180);
greenEnemies.setAll('outOfBoundsKill', true);
greenEnemies.setAll('checkWorldBounds', true);
greenEnemies.forEach(function(enemy){
enemy.body.setSize(enemy.width * 3 / 4, enemy.height * 3 / 4);
enemy.damageAmount = 20;
})
blueEnemies = game.add.group();
blueEnemies.enableBody = true;
blueEnemies.physicsBodyType = Phaser.Physics.ARCADE;
blueEnemies.createMultiple(5, 'blue');
blueEnemies.setAll('anchor.x', 0.5);
blueEnemies.setAll('anchor.y', 0.5);
blueEnemies.setAll('scale.x', 0.5);
blueEnemies.setAll('scale.y', 0.5);
blueEnemies.setAll('angle', 180);
blueEnemies.setAll('outOfBoundsKill', true);
blueEnemies.setAll('checkWorldBounds', true);
blueEnemies.forEach(function(enemy){
enemy.body.setSize(enemy.width * 3 / 4, enemy.height * 3 / 4);
enemy.damageAmount = 40;
})
game.time.events.add(1000, this.launchBlueEnemy);
// Shields stat
shields = game.add.bitmapText(game.world.width - 250, 10, 'spacefont', '' + player.health +'%', 50);
shields.render = function () {
shields.text = 'Shields: ' + Math.max(player.health, 0) +'%';
};
shields.render();
// Score
scoreText = game.add.bitmapText(10, 10, 'spacefont', '', 50);
scoreText.render = function () {
scoreText.text = 'Score: ' + score;
};
scoreText.render();
this.launchGreenEnemy();
bullets = game.add.group();
bullets.enableBody = true;
bullets.physicsBodyType = Phaser.Physics.ARCADE;
bullets.createMultiple(30, 'bullet');
bullets.setAll('anchor.x', 0.5);
bullets.setAll('anchor.y', 1);
bullets.setAll('outOfBoundsKill', true);
bullets.setAll('checkWorldBounds', true);
explosions = game.add.group();
explosions.enableBody = true;
explosions.physicsBodyType = Phaser.Physics.ARCADE;
explosions.createMultiple(30, 'explosionAnim');
explosions.setAll('anchor.x', 0.5);
explosions.setAll('anchor.y', 0.5);
explosions.forEach( function(explosion) {
explosion.animations.add('explosionAnim');
});
this.cursors = game.input.keyboard.createCursorKeys();
this.fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR)
},
update: function() {
this.backgroundImg.tilePosition.y += 2;
player.body.acceleration.x = 0;
if (this.cursors.left.isDown) {
player.body.acceleration.x -= 600;
} else if (this.cursors.right.isDown) {
player.body.acceleration.x += 600;
}
game.physics.arcade.overlap(player, greenEnemies, this.shipCollide, null, this);
game.physics.arcade.overlap(greenEnemies, bullets, this.bulletCollide, null, this);
game.physics.arcade.overlap(player, blueEnemies, this.shipCollide, null, this);
game.physics.arcade.overlap(bullets, blueEnemies, this.hitEnemy, null, this);
if (player.alive && this.fireButton.isDown) {
//Grab first bullet from the pool
if (game.time.now > bulletTimer) {
var bullet = bullets.getFirstExists(false);
if (bullet) {
bullet.reset(player.x, player.y + 8);
//Getting it up
bullet.body.velocity.y = -400;
bulletTimer = game.time.now + 250;
}
}
}
if(!(player.alive)){
console.log("Game Over")
}
},
launchGreenEnemy: function(){
enemy = greenEnemies.getFirstExists(false);
if (enemy) {
enemy.reset(game.rnd.integerInRange(0, game.width), -20);
enemy.body.velocity.x = game.rnd.integerInRange(-300, 300);
enemy.body.velocity.y = 300;
enemy.body.drag.x = 100;
}
game.time.events.add(game.rnd.integerInRange(300, 3000), this.launchGreenEnemy);
},
shipCollide: function(player,enemy){
var explosion = explosions.getFirstExists(false);
explosion.reset(enemy.body.x + enemy.body.halfWidth, enemy.body.y + enemy.body.halfHeight);
explosion.body.velocity.y = enemy.body.velocity.y;
explosion.alpha = 0.7;
explosion.play('explosionAnim', 30, false, true);
enemy.kill();
player.damage(enemy.damageAmount);
shields.render();
},
bulletCollide: function(bullet,enemy){
var explosion = explosions.getFirstExists(false);
explosion.reset(bullet.body.x + bullet.body.halfWidth, bullet.body.y + bullet.body.halfHeight);
explosion.body.velocity.y = enemy.body.velocity.y;
explosion.alpha = 0.7;
explosion.play('explosionAnim', 30, false, true);
enemy.kill();
bullet.kill();
score += enemy.damageAmount * 10;
scoreText.render()
},
launchBlueEnemy:function(){
enemy = blueEnemies.getFirstExists(false);
if (enemy) {
enemy.reset(game.rnd.integerInRange(0, game.width), -20);
enemy.body.velocity.x = game.rnd.integerInRange(-300, 300);
enemy.body.velocity.y = 300;
enemy.body.drag.x = 100;
if (this.y > game.height + 200) {
this.kill();
this.y = -20;
}
}
game.time.events.add(game.rnd.integerInRange(300, 3000), this.launchBlueEnemy);
},
// Restart the game
platformsCreate: function() {
}
};
var Menu = {
preload: function() {
},
create: function() {
},
update: function() {
},
render: function() {
},
start: function() {
}
};
var Game_Over = {
preload: function() {
},
create: function() {
},
update: function() {
},
render: function() {
},
onDown: function() {
}
};
// Add and start the 'main' state to start the game
game.state.add('CountDown', CountDown)
game.state.add('main', mainState);
game.state.add('Menu', Menu);
game.state.add('Game_Over', Game_Over);
game.state.start('main');
A event without a callback or callbackContext is in the events Array.
args: Array[0]
callback: undefined
callbackContext: undefined
delay: 644
loop: false
pendingDelete: true
repeatCount: -1
tick: 1451125781936
I think this line is causing your problem:
game.time.events.add(1000, this.launchBlueEnemy);
When looking for examples on how go use events.add I found this:
http://phaser.io/examples/v2/time/basic-timed-event
// Here we'll create a basic timed event. This is a one-off event, it won't repeat or loop:
// The first parameter is how long to wait before the event fires. In this case 4 seconds (you could pass in 4000 as the value as well.)
// The next parameter is the function to call ('fadePicture') and finally the context under which that will happen.
game.time.events.add(Phaser.Timer.SECOND * 4, fadePicture, this);
This suggest you need to provide 'this' as the third parameter.
This is the source-code for events.add:
/**
* Adds a new Event to this Timer. The event will fire after the given amount of 'delay' in milliseconds has passed, once the Timer has started running.
* Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added.
* If the Timer is already running the delay will be calculated based on the timers current time.
*
* #method Phaser.Timer#add
* #param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
* #param {function} callback - The callback that will be called when the Timer event occurs.
* #param {object} callbackContext - The context in which the callback will be called.
* #param {...*} arguments - The values to be sent to your callback function when it is called.
* #return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
*/
add: function (delay, callback, callbackContext) {
return this.create(delay, false, 0, callback, callbackContext, Array.prototype.splice.call(arguments, 3));
},
GOT IT:
game.time.events.add(game.rnd.integerInRange(300, 3000), this.launchBlueEnemy);
this, does not refer the this of your application here. I think this is because you left out the context earlier.
The reason i got the anwser wrong was that i missed the 3rd parameter called this as #Norbet said. But i missed it in two places.
First one is at the end:
launchBlueEnemy:function(){
enemy = blueEnemies.getFirstExists(false);
if (enemy) {
enemy.reset(game.rnd.integerInRange(0, game.width), -20);
enemy.body.velocity.x = game.rnd.integerInRange(-300, 300);
enemy.body.velocity.y = 300;
enemy.body.drag.x = 100;
if (this.y > game.height + 200) {
this.kill();
this.y = -20;
}
}
game.time.events.add(game.rnd.integerInRange(300, 3000), this.launchBlueEnemy); <<-- Should have had this as the third parameter.
},
And second is:
launchGreenEnemy: function(){
enemy = greenEnemies.getFirstExists(false);
if (enemy) {
enemy.reset(game.rnd.integerInRange(0, game.width), -20);
enemy.body.velocity.x = game.rnd.integerInRange(-300, 300);
enemy.body.velocity.y = 300;
enemy.body.drag.x = 100;
}
game.time.events.add(game.rnd.integerInRange(300, 3000), this.launchGreenEnemy); <<-- Should have had this as the third parameter.
},
Hope this helped to the people who were struglling like me :-). And happy late christmass!