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>
Related
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()
}
I'm trying to create a 2D platformer in JavaScript, I'm getting no errors, but it's not working properly. Pressing the left arrow or the up arrow key does nothing, pressing the right arrow key causes the X-Pos to start incrementing by 1 pixel per tick. I realize this code is long and my 'physics' logic is completely twisted and backwards, but I can't understand anyone's guides on how to add phsyics and velocity and acceleration and gravity and I'm just super confused. I started using JavaScript a week ago and I really have no idea what I'm doing, so any recommendations about any of my code, even things that aren't technically 'problems' would be most appreciated. Thanks guys, you're dope <3
<!DOCTYPE html>
<html>
<meta charset="utf-8"/>
<head>
<title>For The Intended</title>
</head>
<body>
<canvas id="canvas" width="1200" height="800"></canvas>
<!-- <script src="platform.js"></script> -->
<script>
//
//notes
//
//Block collision should come when velocity tries to move, and the x-y position should be player.x + player.velocity to check exactly where the collision will be
//
//
//
//
//
//
//Canvas Settings
var cvs = document.getElementById("canvas");
var ctx = cvs.getContext('2d');
cvs.style = "position:absolute; left: 60%; width: 1200; margin-left: -800px";
//Variables
var platforms = [];
var imgCount = 0
var totalImgCount = 3
var lastUpdate = Date.now();
var keys = {};
//Controls
//Images
var platformImage = new Image();
var playerImage = new Image();
var bgImage = new Image();
platformImage.src = "images/platform.png";
playerImage.src = "images/forward1.png";
playerImage.src = "images/backward1.png";
bgImage.src = "images/bg.png";
platformImage.onload = function() {
imgCount += 1
}
playerImage.onload = function() {
imgCount += 1
}
bgImage.onload = function() {
imgCount += 1
}
//Objects
//Platforms
function Platform(x, y, length, height) {
this.x = x;
this.y = y;
this.length = length;
this.height = height;
platforms.push(this)
}
platform = new Platform(30,30,30,30)
platform = new Platform(40,40,40,40)
//Player
function Player(x, y, gravity, velocityX, velocityY, acceleration, isJumping, direction){
this.x = x
this.y = y
this.gravity = gravity
this.velocityX = velocityX
this.velocityY = velocityY
this.acceleration = acceleration
this.isJumping = isJumping
this.direction = direction
}
player = new Player(200, 600, 0.7, 1, 1, false, "forward")
function jump() {
if (player.isJumping == false) {
player.velocityY = -15;
player.isJumping = true;
}
}
function jumpingHandler() {
if (player.isJumping) {
player.velocityY += player.gravity;
player.y += player.velocityY;
draw();
if (player.y > 600) {
player.y = 600;
player.velocityY = 0;
player.isJumping = false;
}
}
}
*function move(e) {
if(keys[e.keyCode]) {
if(keys[38]) {
jump();
}
if(keys[37]) {
if (player.x > 150){
if (player.acceleration > -5){
player.acceleration = Math.floor(player.acceleration);
player.acceleratoion -= 1
player.acceleration = Math.floor(player.acceleration);
}
player.direction = "backward"
playerImage.src = "images/backward1.png";
}
}
if(keys[39]) {
if (player.x < 1050){
console.log("hey")
if (player.acceleration < 5){
console.log("hey2")
player.acceleration = Math.floor(player.acceleration);
player.acceleration += 1
player.acceleration = Math.floor(player.acceleration);
}
player.direction = "forward"
playerImage.src = "images/forward1.png";
}
}
}
}*
//Game Requirements
function draw() {
if (imgCount == 3) {
for (var i = 0; i < platforms.length; i++) {
ctx.drawImage(platformImage, platforms[i].x, platforms[i].y)
//Do something
}
ctx.drawImage(playerImage, player.x, player.y)
}
}
setInterval(update, 33);
function updateKeys() {
window.onkeyup = function(e) { keys[e.keyCode] = false; move(e)}
window.onkeydown = function(e) { keys[e.keyCode] = true; move(e)}
}
function update() {
if (player.acceleration > 1) {player.acceleration -= 0.2}
if (player.acceleration < 1) {player.acceleration += 0.2}
player.acceleration = Math.floor(player.acceleration);
player.velocityX = player.acceleration
player.x += (player.velocityX)
console.log("Velocity" + player.velocityX)
console.log("Acceleration" + player.acceleration)
console.log("X-Pos" + player.x)
jumpingHandler()
updateKeys()
draw()
}
</script>
</body>
</html>
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");
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.
I'm working on a canvas game that's using a sprite sheet for the character.
The dimensions of character is 64px wide and 128px high with 10 frames per animation.
So the total width of a single animation is 640px wide and 128px high.
However when I use the following code, The animation is offset by 1px, Sometimes flashing when I hold down a movement key.
player.width = 64;
player.height = 128;
player.x = canvas.width / 2;
player.y = canvas.height / 2;
ctx.drawImage(
LoadedImages.player_sprite,
64, // This is offset by 1px when moving. 63px fixes it.
128,
player.width,
player.height,
player.x,
player.y,
player.width,
player.height
);
Here's a picture of what happens:
Changing the width to 63 seems to fix the problem, But it doesn't explain why it's doing it in the first place.
The full code is available on Codepen
http://codepen.io/Codewoofy/pen/QNGLNj
Sprite Sheet:
Full Code:
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
// jQuery Objects
var $canvas = $("#canvas");
var $debug = $("#debug");
var KEY = {
W: 1,
UP: 38,
LEFT: 39,
RIGHT: 37,
SPACE: 32,
SHIFT: 16
};
var COLOR = {
DARKRED: "#9C1E33",
WHITE: "#FFFFFF"
}
var MESSAGE = {
UNDEFINED: "",
PRELOAD_ATTEMPT: "Attempting to preload: ",
ERROR_IMAGE_PRELOAD: "Unable to preload images.",
SUCCESS_IMAGE_PRELOAD: "Images successfully preloaded."
}
// Images
var Images = {
player_sprite: "http://h.dropcanvas.com/30npe/Talia-Sheet-Fix.png",
main_background: "http://h.dropcanvas.com/9kgs1/background_main.png"
}
var LoadedImages = {};
// Dictionaries.
var game = {};
game.enviroment = {};
game.canvas = $canvas[0];
game.canvas.height = 500;
game.canvas.width = 700;
var ctx = game.canvas.getContext('2d');
var player = {};
// Debug
game.debug = function(msg) {
if (msg == "") msg = MESSAGE.UNDEFINED;
$debug.prepend(msg + "<br />");
}
// Preloader.
game.loadImages = function() {
LoadedImages = {};
Object.keys(Images).forEach(function(path) {
game.debug(MESSAGE.PRELOAD_ATTEMPT + path);
var img = new Image;
img.onload = function() {
LoadedImages[path] = img;
if (Object.keys(LoadedImages).length == Object.keys(Images).length) {
game.onImagesLoaded();
}
}
img.onerror = function() {
game.onFailedPreload();
}
img.src = Images[path];
});
}
game.onFailedPreload = function() {
game.debug(MESSAGE.ERROR_IMAGE_PRELOAD);
}
game.onImagesLoaded = function() {
game.debug(MESSAGE.SUCCESS_IMAGE_PRELOAD);
game.game_update();
}
game.onLoad = function() {
// Game settings
game.keys = [];
game.running = false;
game.lastUpdate = 0;
// Enviroment
game.enviroment.gravity = 0.5;
game.enviroment.friction = 0.9;
// Player settings
player.name = "Talia";
player.color = COLOR.DARKRED;
player.direction = 'L';
player.width = 64;
player.height = 128;
player.speed = 4;
player.walkspeed = 4;
player.sprintspeed = 10;
player.jumping = false;
player.animation_frame = 0;
player.velX = 0;
player.velY = 0;
player.x = 0;
player.y = 0;
// Player Stats
player.health = 100;
player.mana = 100;
player.maxhealth = 100;
player.maxmana = 100;
game.loadImages();
}
/* Update the game every frame */
game.game_update = function() {
// Sprint
if (game.keys[KEY.SHIFT]) {
console.log(LoadedImages);
player.speed = player.sprintspeed;
} else {
player.speed = player.walkspeed;
}
// Jump
if (game.keys[KEY.UP] || game.keys[KEY.SPACE]) {
if (!player.jumping) {
player.jumping = true;
player.velY = -player.walkspeed * 2;
}
}
// Left
if (game.keys[KEY.LEFT]) {
player.direction = "L";
if (player.velX < player.speed) {
player.velX++;
}
}
// Right
if (game.keys[KEY.RIGHT]) {
player.direction = "R";
if (player.velX > -player.speed) {
player.velX--;
}
}
// Gravity and Friction
player.velX *= game.enviroment.friction;
player.velY += game.enviroment.gravity;
player.x += player.velX;
player.y += player.velY;
// Collisions
// LEFT RIGHT
if (player.x >= game.canvas.width - player.width) { // Check Right Collision
player.x = game.canvas.width - player.width;
} else if (player.x <= 0) { // Check Left Collision
player.x = 0;
}
// UP DOWN
if (player.y >= game.canvas.height - player.height) {
player.y = game.canvas.height - player.height;
player.jumping = false;
}
// Draw Objects
game.draw_background();
game.draw_player();
// Request next animation frame
requestAnimationFrame(game.game_update);
}
game.draw_player = function() {
ctx.beginPath();
ctx.drawImage(LoadedImages.player_sprite, 64, 128, player.width, player.height, player.x, player.y, player.width, player.height);
/*
if (player.direction == "R") {
ctx.drawImage(LoadedImages.player_sprite, 65, 128, player.width, player.height, player.x, player.y, player.width, player.height);
} else if (player.direction == "L") {
ctx.drawImage(LoadedImages.player_sprite, 63, 0, player.width, player.height, player.x, player.y, player.width, player.height);
}
*/
ctx.closePath();
}
game.draw_background = function() {
ctx.beginPath();
ctx.clearRect(0, 0, game.canvas.width, game.canvas.height);
ctx.closePath();
}
game.draw_UI = function() {
ctx.beginPath();
ctx.closePath();
}
/* Listeners */
document.body.addEventListener("keydown", function(e) {
game.keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function(e) {
game.keys[e.keyCode] = false;
});
/* Load Game */
window.addEventListener("load", function() {
game.onLoad();
});
body,
html {
position: relative;
}
canvas {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="700" height="500"></canvas>Use Arrow keys to move.
<p id="debug"><p>
The issue seems to be that your player.x is a float. That way is hard to account for pixel perfect paints.
Round player.x on the drawImage() or when you update the value with velocity.
Using a bitwise operator, you could simply do:
player.x += player.velX | 0;