I have the following code in phaser, and I want to use a sprite animation instead of a static image, how can I pull that off? Using group to create new bullets.
I am creating a new object and with that creating new bullets to get fired by the player. And I want the bullet to rotate with an animated spritshit. How can I do that?
this.bullets = this.physics.add.group({
classType: Bullet,
maxSize: 10,
runChildUpdate: true,
});
The class i am using to create new bullets
var Bullet = new Phaser.Class({
Extends: Phaser.GameObjects.Image,
initialize:
function Bullet (scene)
{
Phaser.GameObjects.Sprite.call(this, scene, 0, 0, "bullet");
this.speed = Phaser.Math.GetSpeed(250, 1);
},
fire: function (x, y, direcao)
{
this.direcao = direcao;
if(direcao == 1){
//Cima
// console.log("Tiro Acima");
this.setPosition(x, y - 10);
this.setActive(true);
this.setVisible(true);
}else if(direcao == 2){
// Baixo
// console.log("Tiro Abaixo");
this.setPosition(x, y + 10);
this.setActive(true);
this.setVisible(true);
}else if(direcao == 3){
//Direita
//console.log("Tiro a direita");
this.setPosition(x + 10, y);
this.setActive(true);
this.setVisible(true);
}else if(direcao == 4){
//Esquerda
//console.log("Tiro a esquerda");
this.setPosition(x - 10, y );
this.setActive(true);
this.setVisible(true);
} else {
//Debug
console.log("Não disparou");
}
},
update: function (time, delta)
{
if(this.direcao == 1){
//Cima
// console.log("Tiro Acima");
this.y -= this.speed * delta;
}else if(this.direcao == 2){
//Baixo
// console.log("Tiro Abaixo");
this.y += this.speed * delta;
}else if(this.direcao == 3){
//Direita
// console.log("Tiro a direita");
this.x += this.speed * delta;
}else if(this.direcao == 4){
//Esquerda
// console.log("Tiro a esquerda");
this.x -= this.speed * delta;
}else{
//Debug
// console.log("Não disparou");
}
if (this.y < 0)
{
this.setActive(false);
this.setVisible(false);
}
if (this.y > 480)
{
this.setActive(false);
this.setVisible(false);
}
if (this.x < 0)
{
this.setActive(false);
this.setVisible(false);
}
if (this.x > 960)
{
this.setActive(false);
this.setVisible(false);
}
}
});
First you could extend from Phaser.GameObjects.Sprite rather than from Phaser.GameObjects.Image, then create an animation, with this.anims.create (link to documentation), and start the animation in the fire method , with the method play and stop the animation, when the bullet leaves the display (or so), in the update method.
Here a small working Demo (with pulsating bullet):
document.body.style = 'margin:0;';
var Bullet = new Phaser.Class({
Extends: Phaser.GameObjects.Sprite,
initialize: function Bullet (scene, x, y) {
Phaser.GameObjects.Sprite.call(this, scene, x, y, 'dynamicFrames');
},
fire: function (x, y) {
this.x = x;
this.y = y;
this.play('pulse');
this.setActive(true);
this.setVisible(true);
},
update: function (time, delta) {
let speed = .15;
this.x += speed * delta;
if (this.x > config.width) {
this.setActive(false);
this.setVisible(false);
this.stop();
}
}
});
class Example extends Phaser.Scene
{
constructor () {
super();
}
preload () {
/** CREATE SPRITE FRAME FOR ONLY DEMO --- START */
const canvasFrame = this.textures
.createCanvas('dynamicFrames', 32, 16);
let ctx = canvasFrame.context;
ctx.fillStyle = '#ffff00';
ctx.beginPath();
ctx.arc(8, 8, 8, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.arc(16 + 8, 8, 6, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
canvasFrame.add(1, 0, 0, 0, 16, 16);
canvasFrame.add(2, 0, 16, 0, 16, 16);
canvasFrame.refresh();
/** CREATE SPRITE FRAME FOR ONLY DEMO --- END*/
this.anims.create({
key: 'pulse',
frames: this.anims.generateFrameNumbers('dynamicFrames', { start: 1, end: 2 }),
frameRate: 8,
repeat: -1
});
}
create(){
this.add.circle(60, 100, 20, 0xffffff);
this.add.rectangle(55, 100, 45, 10, 0xffffff)
.setOrigin(0, .5);
let bullets = this.physics.add.group({
classType: Bullet,
maxSize: 10,
runChildUpdate: true,
});
this.time.addEvent({
delay: 1000,
startAt: 0,
loop: true,
callback: _ => {
bullets
.get(100, 100)
.fire(110, 100);
}
});
}
}
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: { default: 'arcade' },
scene: [ Example ],
banner: false
};
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
For future references, here is the solution using #winner solution.
var Bullet = new Phaser.Class({
Extends: Phaser.GameObjects.Sprite,
initialize:
function Bullet (scene)
{
Phaser.GameObjects.Sprite.call(this, scene, 0, 0, "bullet");
this.speed = Phaser.Math.GetSpeed(250, 1);
},
fire: function (x, y, direcao)
{
//Animação Bala
this.anims.create({
key: 'bulletAnimation',
frames: this.anims.generateFrameNumbers('bullet', {frames: [0, 1, 3, 4, 6, 7, 9, 10]}),
frameRate: 10,
repeat: -1,
});
this.anims.play('bulletAnimation', true);
this.direcao = direcao;
if(direcao == 1){
//Cima
// console.log("Tiro Acima");
this.setPosition(x, y - 10);
this.setActive(true);
this.setVisible(true);
}else if(direcao == 2){
//Baixo
// console.log("Tiro Abaixo");
this.setPosition(x, y + 10);
this.setActive(true);
this.setVisible(true);
}else if(direcao == 3){
//Direita
// console.log("Tiro a direita");
this.setPosition(x + 10, y);
this.setActive(true);
this.setVisible(true);
}else if(direcao == 4){
//Esquerda
// console.log("Tiro a esquerda");
this.setPosition(x - 10, y );
this.setActive(true);
this.setVisible(true);
}else{
//Debug
console.log("Não disparou");
}
},
update: function (time, delta)
{
if(this.direcao == 1){
//Cima
// console.log("Tiro Acima");
this.y -= this.speed * delta;
}else if(this.direcao == 2){
//Baixo
// console.log("Tiro Abaixo");
this.y += this.speed * delta;
}else if(this.direcao == 3){
//Direita
// console.log("Tiro a direita");
this.x += this.speed * delta;
}else if(this.direcao == 4){
//Esquerda
// console.log("Tiro a esquerda");
this.x -= this.speed * delta;
}else{
//Debug
// console.log("Não disparou");
}
if (this.y < 0)
{
this.setActive(false);
this.setVisible(false);
}
if (this.y > 480)
{
this.setActive(false);
this.setVisible(false);
}
if (this.x < 0)
{
this.setActive(false);
this.setVisible(false);
}
if (this.x > 960)
{
this.setActive(false);
this.setVisible(false);
}
}
});
Related
I've been making a simple game just with the HTML5 canvas and plain JavaScript. Most recently I tried adding a feature to shoot bullets which would then destroy obstacles but I've come upon a problem. Whenever you shoot a bullet it doesn't move until another is shot. Even when it starts moving and collides with one of the obstacles nothing happens. I've done some troubleshooting and I can't seem to get to the bottom of it. Any help and/or suggestions would be greatly appreciated.
Collision handling code:
for(var i = 0; i < this.bullets.length - 1; i++) { // -1 is present because whenever I remove it I get an error. I have a feeling this may be related to the order of how everything updates, will be fixed
this.bullets[i].x += this.bullets[i].speed;
if(this.bullets[i].x > cvs.width) {
this.bullets.splice(i, 1);
}
for(var j = 0; j < obstacles.length - 1; j++) { // Same here
if(rectanglesColliding(this.bullets[i], obstacles[j])) {
console.log("Collision");
}
}
}
Full player object:
var player = {
score: 0,
x: 50,
y: 150,
radius: 10,
jumping: false,
bullets: [],
velocityX: 0,
velocityY: 1,
angle: 90,
update: function() {
this.draw();
this.score++;
if(this.y + this.radius + 2 > cvs.height - 50 && this.jumping === false || this.y - this.radius + 2 < 0 + 50 && this.jumping === true) {
this.velocityY = 0;
} else if(this.jumping === false){
this.velocityY = 4;
} else {
this.velocityY = -4;
}
obstacles.forEach((obstacle) => {
if(colliding(this, obstacle)) {
gameEnded = true;
}
});
this.x += this.velocityX;
this.y += this.velocityY;
for(var i = 0; i < this.bullets.length - 1; i++) { // -1 is present because whenever I remove it I get an error. I have a feeling this may be related to the order of how everything updates, will be fixed
this.bullets[i].x += this.bullets[i].speed;
if(this.bullets[i].x > cvs.width) {
this.bullets.splice(i, 1);
}
for(var j = 0; j < obstacles.length - 1; j++) { // Same here
if(rectanglesColliding(this.bullets[i], obstacles[j])) {
console.log("Collision");
}
}
}
},
draw: function() {
this.bullets.forEach((bullet) => {
ctx.fillStyle = 'green';
ctx.fillRect(bullet.x, bullet.y, 7, 2);
});
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
ctx.fill();
}
};
Collision Detection Function:
function rectanglesColliding(rect1, rect2) {
if(rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x && // Found on Mozilla.com: https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y) return true;
else return false;
}
Shoot Function:
function shoot() {
player.bullets.push({ x: player.x + 10, y: player.y, speed: 6 });
}
Object of the game:
Survive as long as you can by avoiding the obstacles.
Controls:
Space: Go up
W: Shoot Bullet
Full code snippet:
var cvs = document.getElementById('canvas');
var ctx = cvs.getContext("2d");
var gameEnded = false;
var player = {
score: 0,
x: 50,
y: 150,
radius: 10,
jumping: false,
bullets: [],
velocityX: 0,
velocityY: 1,
angle: 90,
update: function() {
this.draw();
this.score++;
if(this.y + this.radius + 2 > cvs.height - 50 && this.jumping === false || this.y - this.radius + 2 < 0 + 50 && this.jumping === true) {
this.velocityY = 0;
} else if(this.jumping === false){
this.velocityY = 4;
} else {
this.velocityY = -4;
}
obstacles.forEach((obstacle) => {
if(colliding(this, obstacle)) {
gameEnded = true;
}
});
this.x += this.velocityX;
this.y += this.velocityY;
for(var i = 0; i < this.bullets.length - 1; i++) {
this.bullets[i].x += this.bullets[i].speed;
if(this.bullets[i].x > cvs.width) {
this.bullets.splice(i, 1);
}
for(var j = 0; j < obstacles.length - 1; j++) {
if(rectanglesColliding(this.bullets[i], obstacles[j])) {
console.log("Collision");
// obstacles.splice(i, 1);
}
}
}
},
draw: function() {
this.bullets.forEach((bullet) => {
ctx.fillStyle = 'green';
ctx.fillRect(bullet.x, bullet.y, 7, 2);
});
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
ctx.fill();
}
};
var obstacles = [{ x: 150, y: 60, width: 10, height: 20 }];
document.addEventListener('keydown', (event) => {
if(event.key === ' ') {
player.jumping = true;
}
if(event.key === 'w') {
shoot();
}
});
document.addEventListener('keyup', (event) => {
if(event.key === ' ') {
player.jumping = false;
}
});
function randomIntFromRange(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function getWidth() {
return Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
}
function getHeight() {
return Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight,
document.body.offsetHeight,
document.documentElement.offsetHeight,
document.documentElement.clientHeight
);
}
function colliding(circle, rect) {
var distX = Math.abs(circle.x - rect.x - rect.width / 2);
var distY = Math.abs(circle.y - rect.y - rect.height / 2);
if(distX > (rect.width / 2 + circle.radius)) return false;
if(distY > (rect.height / 2 + circle.radius)) return false;
if(distX <= (rect.width / 2)) return true;
if(distY <= (rect.height / 2)) return true;
}
function rectanglesColliding(rect1, rect2) {
if(rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y) {
return true;
}
}
function distance(x1, y1, x2, y2) {
const xDist = x2 - x1;
const yDist = y2 - y1;
return Math.sqrt(Math.pow(xDist, 2) + Math.pow(yDist, 2));
}
function shoot() {
player.bullets.push({ x: player.x + 10, y: player.y, speed: 6 });
}
function generateObstacle() {
var obstacle = {
x: obstacles[0].x + randomIntFromRange(cvs.width - 100, cvs.width + 70),
y: 0 + randomIntFromRange(20, 550),
width: randomIntFromRange(25, 35),
height: randomIntFromRange(10, 25)
};
for(var i = 0; i < obstacles.length; i++) {
if(distance(obstacle.x, obstacle.y, obstacles[i].x, obstacles[i].y) < 65) {
obstacle = {
x: obstacles[0].x + randomIntFromRange(cvs.width - 100, cvs.width + 70),
y: 0 + randomIntFromRange(20, 550),
width: randomIntFromRange(25, 35),
height: randomIntFromRange(10, 25)
};
i = -1;
}
}
obstacles.push({ x: obstacle.x, y: obstacle.y, width: obstacle.width, height: obstacle.height });
}
function removeBadObstacles() {
for(var i = 0; i < obstacles.length; i++) {
if(obstacles[i].x < 0) {
obstacles.splice(i, 1);
}
}
}
function updateObstacles() {
if(obstacles[obstacles.length - 1].x < cvs.width + 5) {
generateObstacle();
generateObstacle();
}
obstacles.forEach((obstacle) => {
obstacle.x -= 10;
ctx.fillStyle = 'red';
ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
});
}
function init() {
cvs.width = getWidth();
cvs.height = getHeight();
update();
}
function update() {
if(gameEnded) {
ctx.font = '50px Verdana';
return ctx.fillText('Game Over', 110, cvs.height / 2);
}
requestAnimationFrame(update);
removeBadObstacles();
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, cvs.width, cvs.height);
updateObstacles();
player.update();
ctx.font = '30px Impact';
ctx.fillText("Score: " + player.score, 20, 40);
}
init();
<!DOCTYPE html>
<html>
<head>
<title>Game</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript" src="./JS/main.js"></script>
</body>
</html>
when iterate through a array, the last item is at length-1 (which mean you should use < length, not < length-1)
the remove code should be obstacles.splice(j, 1); (i is the index for bullet)
you do not assign size to bullet (and you may also want to use this size when draw)
var cvs = document.getElementById('canvas');
var ctx = cvs.getContext("2d");
var gameEnded = false;
var player = {
score: 0,
x: 50,
y: 150,
radius: 10,
jumping: false,
bullets: [],
velocityX: 0,
velocityY: 1,
angle: 90,
update: function() {
this.draw();
this.score++;
if(this.y + this.radius + 2 > cvs.height - 50 && this.jumping === false || this.y - this.radius + 2 < 0 + 50 && this.jumping === true) {
this.velocityY = 0;
} else if(this.jumping === false){
this.velocityY = 4;
} else {
this.velocityY = -4;
}
obstacles.forEach((obstacle) => {
if(colliding(this, obstacle)) {
gameEnded = true;
}
});
this.x += this.velocityX;
this.y += this.velocityY;
for(var i = 0; i < this.bullets.length; i++) {//<==============
this.bullets[i].x += this.bullets[i].speed;
if(this.bullets[i].x > cvs.width) {
this.bullets.splice(i, 1);
}
for(var j = 0; j < obstacles.length; j++) {//<==============
if(rectanglesColliding(this.bullets[i], obstacles[j])) {
console.log("Collision");
obstacles.splice(j, 1);//<==============
}
}
}
},
draw: function() {
this.bullets.forEach((bullet) => {
ctx.fillStyle = 'green';
ctx.fillRect(bullet.x, bullet.y, 7, 2);
});
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
ctx.fill();
}
};
var obstacles = [{ x: 150, y: 60, width: 10, height: 20 }];
document.addEventListener('keydown', (event) => {
if(event.key === ' ') {
player.jumping = true;
}
if(event.key === 'w') {
shoot();
}
});
document.addEventListener('keyup', (event) => {
if(event.key === ' ') {
player.jumping = false;
}
});
function randomIntFromRange(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function getWidth() {
return Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
}
function getHeight() {
return Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight,
document.body.offsetHeight,
document.documentElement.offsetHeight,
document.documentElement.clientHeight
);
}
function colliding(circle, rect) {
var distX = Math.abs(circle.x - rect.x - rect.width / 2);
var distY = Math.abs(circle.y - rect.y - rect.height / 2);
if(distX > (rect.width / 2 + circle.radius)) return false;
if(distY > (rect.height / 2 + circle.radius)) return false;
if(distX <= (rect.width / 2)) return true;
if(distY <= (rect.height / 2)) return true;
}
function rectanglesColliding(rect1, rect2) {
if(rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y) {
return true;
}
}
function distance(x1, y1, x2, y2) {
const xDist = x2 - x1;
const yDist = y2 - y1;
return Math.sqrt(Math.pow(xDist, 2) + Math.pow(yDist, 2));
}
function shoot() {
player.bullets.push({ x: player.x + 10, y: player.y, speed: 6, width: 7, height: 6 }); //<====================
}
function generateObstacle() {
var obstacle = {
x: obstacles[0].x + randomIntFromRange(cvs.width - 100, cvs.width + 70),
y: 0 + randomIntFromRange(20, 550),
width: randomIntFromRange(25, 35),
height: randomIntFromRange(10, 25)
};
for(var i = 0; i < obstacles.length; i++) {
if(distance(obstacle.x, obstacle.y, obstacles[i].x, obstacles[i].y) < 65) {
obstacle = {
x: obstacles[0].x + randomIntFromRange(cvs.width - 100, cvs.width + 70),
y: 0 + randomIntFromRange(20, 550),
width: randomIntFromRange(25, 35),
height: randomIntFromRange(10, 25)
};
i = -1;
}
}
obstacles.push({ x: obstacle.x, y: obstacle.y, width: obstacle.width, height: obstacle.height });
}
function removeBadObstacles() {
for(var i = 0; i < obstacles.length; i++) {
if(obstacles[i].x < 0) {
obstacles.splice(i, 1);
}
}
}
function updateObstacles() {
if(obstacles[obstacles.length - 1].x < cvs.width + 5) {
generateObstacle();
generateObstacle();
}
obstacles.forEach((obstacle) => {
obstacle.x -= 10;
ctx.fillStyle = 'red';
ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
});
}
function init() {
cvs.width = getWidth();
cvs.height = getHeight();
update();
}
function update() {
if(gameEnded) {
ctx.font = '50px Verdana';
return ctx.fillText('Game Over', 110, cvs.height / 2);
}
requestAnimationFrame(update);
removeBadObstacles();
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, cvs.width, cvs.height);
updateObstacles();
player.update();
ctx.font = '30px Impact';
ctx.fillText("Score: " + player.score, 20, 40);
}
init();
<!DOCTYPE html>
<html>
<head>
<title>Game</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript" src="./JS/main.js"></script>
</body>
</html>
So i have my code here:
var canvas = document.getElementById('c');
var ctx = c.getContext('2d');
var player = {
x: 0,
y: 0,
width: 20,
height: 20,
speed: 3,
velX: 0,
velY: 0,
jumping: false,
grounded: false,
gravity: 0.35,
friction: 0,
glitchCooldown: 0,
keys: []
};
var walls = [];
walls.push({
x: 50,
y: 230,
width: 20,
height: 20
})
walls.push({
x: 150,
y: 230,
width: 20,
height: 20
})
player.y = canvas.height - player.width;
document.body.addEventListener("keydown", function(e) {
player.keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function(e) {
player.keys[e.keyCode] = false;
});
function update() {
if (player.keys[68]) {
if (player.velX < player.speed) {
player.velX++;
}
};
if (player.keys[65]) {
if (player.velX > -player.speed) {
player.velX--;
}
};
if (player.keys[87]) {
if (!player.jumping) {
player.jumping = true;
player.grounded = false;
player.velY = -player.speed*2;
}
};
if (player.keys[74]) {
glitch('backward');
};
if (player.keys[75]) {
glitch('down')
};
if (player.keys[76]) {
glitch('forward')
};
player.velY += player.gravity;
player.velX *= player.friction;
player.x += player.velX;
player.y += player.velY;
ctx.clearRect(0, 0, canvas.width, canvas.height);
player.grounded = false;
for (var i = 0; i < walls.length; i++) {
rect('black', walls[i].x, walls[i].y, walls[i].width, walls[i].height);
var dir = colCheck(player, walls[i]);
if (dir === "l" || dir === "r") {
player.velX = 0;
player.jumping = false;
} else if (dir === "b") {
player.grounded = true;
player.jumping = false;
} else if (dir === "t") {
player.velY *= -1;
}
}
if (player.grounded){
player.velY = 0;
}
if (player.glitchCooldown <= 0) {
player.glitchCooldown = 0;
}
player.glitchCooldown--;
rect('black', player.x, player.y, player.width, player.height);
requestAnimationFrame(update);
};
requestAnimationFrame(update)
function rect(color, x, y, width, height) {
ctx.fillStyle = color;
ctx.fillRect(x, y, width, height);
}
function glitch(x) {
if (player.glitchCooldown <= 0) {
setTimeout(function(){player.width = 0}, 200);
setTimeout(function(){player.width = 20}, 220);
setTimeout(function(){player.width = 0}, 400);
setTimeout(function(){player.width = 20}, 420);
setTimeout(function(){player.width = 0}, 500);
setTimeout(function(){player.width = 20}, 510);
setTimeout(function(){player.width = 0}, 530);
setTimeout(function(){player.width = 20}, 550);
if (x == 'forward'){setTimeout(function(){player.x += 20;}, 700)};
if (x == 'backward'){setTimeout(function(){player.x -= 20;}, 700)};
if (x == 'down'){setTimeout(function(){player.y += 20;}, 700)};
setTimeout(function(){player.glitchCooldown = 120}, 700);
}
}
function colCheck(shapeA, shapeB) {
// get the vectors to check against
var vX = (shapeA.x + (shapeA.width / 2)) - (shapeB.x + (shapeB.width / 2)),
vY = (shapeA.y + (shapeA.height / 2)) - (shapeB.y + (shapeB.height / 2)),
// add the half widths and half heights of the objects
hWidths = (shapeA.width / 2) + (shapeB.width / 2),
hHeights = (shapeA.height / 2) + (shapeB.height / 2),
colDir = 'l';
// if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) { // figures out on which side we are colliding (top, bottom, left, or right) var oX = hWidths - Math.abs(vX), oY = hHeights - Math.abs(vY); if (oX >= oY) {
if (vY > 0) {
colDir = "t";
shapeA.y += oY;
} else {
colDir = "b";
shapeA.y -= oY;
}
} else {
if (vX > 0) {
colDir = "l";
shapeA.x += oX;
} else {
colDir = "r";
shapeA.x -= oX;
}
}
}
return colDir;
}
function random() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}
<html>
<head>
<title>CoRRupTed</title>
<link rel="stylesheet" href="design.css">
</head>
<body>
<canvas height='250' width='1350' style='border: 1px solid black' id='c'>Your browser do not support the <canvas> tag. Please update your browser.</canvas>
<script src='main.js'></script>
</body>
</html>
As you can see, my colCheck function is not working properly. It suppose to return colDir as 'l', 'r', 'b' or 't'. Buut the error says "Illegal resturn statement", so I think that colCheck is returning colDir as null. Therefore, in my code, I already write var col = colCheck(player, walls[i]), but it is still not working properly. Any ideas?
This is because you are not consistently styling your code.
The error means you have mismatching opening and closing braces.
the line
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) { // figures out on which side we are colliding (top, bottom, left, or right) var oX = hWidths - Math.abs(vX), oY = hHeights - Math.abs(vY); if (oX >= oY) {
should be. Comments within /* */ have been added by me.
/* DONT make comment run past right edge of screen put them in the line above */
// figures out on which side we are colliding (top, bottom, left, or right)
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
/* DONT use , to separate variable declarations */
const oX = hWidths - Math.abs(vX); /*Use consts for vars that don't change*/
const oY = hHeights - Math.abs(vY);
if (oX >= oY) {
I'm making a game in HTML5 Canvas. Right now I'm trying to make it so the enemy (a ground to air gun) can shoot in the direction of the player (a plane).
My game uses 2 arrays to make a map according to the values in it. Because the game won't know how many enemies to put on the screen until it goes through the map, I have it create a new enemy with a random id, and have it add it to an object that keeps track of the enemies every time it comes across an enemy value in the map.
The problem comes when the enemies shoot at the plane, they all shoot at the same angle, and not at the angle necessary for that particular situation.
Here's the question: How can I get each enemy to shoot at the player at the correct angle?
I realize that this question/explanation may be a little confusing to understand, but please give it a shot. It would be good to start looking at lines 222-257 (The updateEntity function). (Please be aware that this is a separate code example from my real game code, it's not the best.)
Code on google drive: https://drive.google.com/open?id=0By026U5OT4C7OUZSNG5GM19kV1U
JS Fiddle: https://jsfiddle.net/k2xwypkp/
Whole code:
<center><canvas id = "gameCanvas" width = "500" height = "500" style = "border:1px solid navy;"></canvas></center>
var canvas, ctx;
var clip = {};
var arsenal = {};
var enemyClip = {};
var keyDown = {};
var enemy = {};
window.onload = function() {
canvas = document.getElementById("gameCanvas");
ctx = canvas.getContext("2d");
for (var i = 0; i < 3; i++) {
createEnemy(Math.random(), i * 100 + 140);
}
setInterval(function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
update();
}, 1000 / 30);
}
var player = {
x: 240,
y: 240,
w: 20,
h: 20,
color: "navy",
alive: true,
canShoot: true,
canNuke: true,
facingRight: true,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
},
shoot: function() {
if (player.canShoot) {
player.canShoot = false;
if (player.facingRight) {
createPlayerBullet(Math.random(), player.x + player.w, player.y + player.h / 2, true);
} else {
createPlayerBullet(Math.random(), player.x, player.y + player.h / 2, false);
}
setTimeout(function() {
player.canShoot = true;
}, 750);
}
},
nuke: function() {
if (player.canNuke) {
player.canNuke = false;
createNuke(Math.random(), player.x + player.w / 2, player.y + player.h);
setTimeout(function() {
player.canNuke = true;
}, 2000);
}
}
}
//var enemy = {
// x:240,
// y:480,
// w:20,
// h:20,
// color:"maroon",
// alive:true,
// canShoot:true,
//
// draw:function(){
// ctx.fillStyle = this.color;
// ctx.fillRect(this.x, this.y, this.w, this.h);
// },
//
// shoot:function(){
// if(enemy.canShoot){
// enemy.canShoot = false;
//
// if(player.x >= enemy.x && player.y <= enemy.y){// Top Right: TF, Bottom Right: TT, Bottom Left: FT, Top Left: FF
// createEnemyBullet(Math.random(), enemy.x + enemy.w/2, enemy.y, player.x, player.y, true, false); // True equals ___ is greater than
// }else if(player.x >= enemy.x && player.y >= enemy.y){
// createEnemyBullet(Math.random(), enemy.x + enemy.w/2, enemy.y, player.x, player.y, true, true);
// }else if(player.x <= enemy.x && player.y >= enemy.y){
// createEnemyBullet(Math.random(), enemy.x + enemy.w/2, enemy.y, player.x, player.y, false, true);
// }else if(player.x <= enemy.x && player.y <= enemy.y){
// createEnemyBullet(Math.random(), enemy.x + enemy.w/2, enemy.y, player.x, player.y, false, false);
// }
//
// setTimeout(function(){
// enemy.canShoot = true;
// }, 750);
// }
// }
//}
var createEnemy = function(ID, X) {
var e = {
x: X,
y: 480,
w: 20,
h: 20,
color: "maroon",
alive: true,
canShoot: true,
id: ID,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
},
shoot: function() {
if (this.canShoot) {
this.canShoot = false;
if (player.x >= this.x && player.y <= this.y) { // Top Right: TF, Bottom Right: TT, Bottom Left: FT, Top Left: FF
createEnemyBullet(Math.random(), this.x + this.w / 2, this.y, player.x, player.y, true, false); // True means greater than
} else if (player.x >= this.x && player.y >= this.y) {
createEnemyBullet(Math.random(), this.x + this.w / 2, this.y, player.x, player.y, true, true);
} else if (player.x <= this.x && player.y >= this.y) {
createEnemyBullet(Math.random(), this.x + this.w / 2, this.y, player.x, player.y, false, true);
} else if (player.x <= this.x && player.y <= this.y) {
createEnemyBullet(Math.random(), this.x + this.w / 2, this.y, player.x, player.y, false, false);
}
setTimeout(function() {
enemy.canShoot = true;
}, 750);
}
}
};
enemy[e.id] = e;
}
var createPlayerBullet = function(ID, X, Y, dir) {
var playerBullet = {
x: X,
y: Y,
w: 5,
h: 5,
color: "navy",
id: ID,
facingRight: dir,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
clip[playerBullet.id] = playerBullet;
}
var createEnemyBullet = function(ID, X, Y, playerx, playery, dirx, diry) {
var enemyBullet = {
x: X,
y: Y,
w: 5,
h: 5,
color: "maroon",
id: ID,
dirX: dirx,
dirY: diry,
playerX: playerx,
playerY: playery,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
enemyClip[enemyBullet.id] = enemyBullet;
}
var createNuke = function(ID, X, Y) {
var nuke = {
x: X,
y: Y,
w: 5,
h: 5,
color: "green",
id: ID,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
arsenal[nuke.id] = nuke;
}
var updateEntity = function() {
for (var playerBullet in clip) {
clip[playerBullet].draw();
if (clip[playerBullet].facingRight) {
clip[playerBullet].x += 8;
} else {
clip[playerBullet].x -= 8;
}
if (clip[playerBullet].x <= 0) {
delete clip[playerBullet];
} else if (clip[playerBullet].x >= canvas.width) {
delete clip[playerBullet];
}
}
for (var nuke in arsenal) {
arsenal[nuke].draw();
arsenal[nuke].y += 3;
if (arsenal[nuke].y >= canvas.height) {
delete arsenal[nuke];
}
}
for (var enemyBullet in enemyClip) {
for (var e in enemy) {
var dx = enemy[e].x - enemyClip[enemyBullet].playerX;
var dy = enemy[e].y - enemyClip[enemyBullet].playerY;
var angle = Math.atan2(dy, dx);
}
enemyClip[enemyBullet].draw();
if (enemyClip[enemyBullet].dirX && !enemyClip[enemyBullet].dirY) {
enemyClip[enemyBullet].x -= 10 * Math.cos(angle);
enemyClip[enemyBullet].y -= 10 * Math.sin(angle);
} else if (enemyClip[enemyBullet].dirX && enemyClip[enemyBullet].dirY) {
enemyClip[enemyBullet].x -= 10 * Math.cos(angle);
enemyClip[enemyBullet].y -= 10 * Math.sin(angle);
} else if (!enemyClip[enemyBullet].dirX && enemyClip[enemyBullet].dirY) {
enemyClip[enemyBullet].x -= 10 * Math.cos(angle);
enemyClip[enemyBullet].y -= 10 * Math.sin(angle);
} else if (!enemyClip[enemyBullet].dirX && !enemyClip[enemyBullet].dirY) {
enemyClip[enemyBullet].x -= 10 * Math.cos(angle);
enemyClip[enemyBullet].y -= 10 * Math.sin(angle);
}
if (enemyClip[enemyBullet].x <= 0) {
delete enemyClip[enemyBullet];
} else if (enemyClip[enemyBullet].x >= canvas.width) {
delete enemyClip[enemyBullet];
} else if (enemyClip[enemyBullet].y <= 0) {
delete enemyClip[enemyBullet];
} else if (enemyClip[enemyBullet].y >= canvas.height) {
delete enemyClip[enemyBullet];
} else if (enemyClip[enemyBullet].x >= player.x && enemyClip[enemyBullet].x <= player.x + player.w && enemyClip[enemyBullet].y >= player.y && enemyClip[enemyBullet].y <= player.y + player.h) {
delete enemyClip[enemyBullet];
}
}
}
var update = function() {
updateEntity();
if (player.alive) {
player.draw();
}
//if(enemy.alive){
// enemy.draw();
// enemy.shoot();
//}
for (var e in enemy) {
ctx.fillStyle = enemy[e].color;
ctx.fillRect(enemy[e].x, enemy[e].y, enemy[e].w, enemy[e].h);
if (enemy[e].canShoot) {
enemy[e].canShoot = false;
if (player.x >= enemy[e].x && player.y <= enemy[e].y) { // Top Right: TF, Bottom Right: TT, Bottom Left: FT, Top Left: FF
createEnemyBullet(Math.random(), enemy[e].x + enemy[e].w / 2, enemy[e].y, player.x, player.y, true, false); // True equals ___ is greater than
} else if (player.x >= enemy[e].x && player.y >= enemy[e].y) {
createEnemyBullet(Math.random(), enemy[e].x + enemy[e].w / 2, enemy[e].y, player.x, player.y, true, true);
} else if (player.x <= enemy[e].x && player.y >= enemy[e].y) {
createEnemyBullet(Math.random(), enemy[e].x + enemy[e].w / 2, enemy[e].y, player.x, player.y, false, true);
} else if (player.x <= enemy[e].x && player.y <= enemy[e].y) {
createEnemyBullet(Math.random(), enemy[e].x + enemy[e].w / 2, enemy[e].y, player.x, player.y, false, false);
}
setTimeout(function() {
for (var e in enemy) {
enemy[e].canShoot = true;
}
}, 750);
}
}
if (37 in keyDown) {
player.facingRight = false;
player.x -= 5;
}
if (38 in keyDown) {
player.y -= 5;
}
if (39 in keyDown) {
player.facingRight = true;
player.x += 5;
}
if (40 in keyDown) {
player.y += 5;
}
if (32 in keyDown) {
player.shoot();
}
if (90 in keyDown) {
player.nuke();
}
}
addEventListener("keydown", function(e) {
keyDown[e.keyCode] = true;
});
addEventListener("keyup", function(e) {
delete keyDown[e.keyCode];
});
I appreciate your time spent trying (and hopefully) helping me. Thanks.
This code in updateEntity
for (var enemyBullet in enemyClip) {
for (var e in enemy) {
var dx = enemy[e].x - enemyClip[enemyBullet].playerX;
var dy = enemy[e].y - enemyClip[enemyBullet].playerY;
var angle = Math.atan2(dy, dx);
}
Should be written without the for loop. You should just refer to the enemy that shot the bullet.
for (var enemyBullet in enemyClip) {
var bullet = enemyClip[enemyBullet];
var dx = bullet.enemyX - bullet.playerX;
var dy = bullet.enemyY - bullet.playerY;
var angle = Math.atan2(dy, dx);
However, instead of storing all this information when a bullet is shot, you should just calculate the angle of the bullet when it is shot (it is not necessary for the bullet to know the player position and the 'dir' value seems unnecessary)
if (enemy[e].canShoot) {
enemy[e].canShoot = false;
var angle = Math.atan2( enemy[e].y-player.y, enemy[e].x-player.x);
...
createEnemyBullet(Math.random(), angle, enemy[e].x + enemy[e].w/2, enemy[e].y);
Your updateEntity code then just becomes:
for (var enemyBullet in enemyClip) {
var angle = enemyClip[enemyBullet].angle;
Before you go further I would suggest that you look at your code and review how you can simplify it there is a lot that could be removed. You create enemy bullets in 2 places and each place has 4 calls to createEnemyBullet also consider how enemy bullets and player bullets are the same. Also Math.random() is not a good way to generate a unique id. Just use an incrementing number each time (although there is no real reason for the id in this code)
I am having an issue finding the error in my code. I am making my own version of space invaders for a school project. P5 isn't showing any errors, but when I do a test run of the code, all I get is a white screen. I need an extra set of eyes for this. Any help is appreciated. Thanks!!
//initializes bullets
var bullets = {
x: new Array(),
y: new Array(),
shot: new Array()
}
//initializes the ship
var ship = {
x: 625,
y: 475,
photo: loadImage("download.png")
}
function setup() {
createCanvas(1350,650);
//bullet1
append(bullets.x, ship.x);
append(bullets.y, ship.y);
append(bullets.shot, false);
//bullet2
append(bullets.x, ship.x);
append(bullets.y, ship.y);
append(bullets.shot, false);
//bullet3
append(bullets.x, ship.x);
append(bullets.y, ship.y);
append(bullets.shot, false);
}
//Controls
function updateShip()
{
//Right movement
if (keyIsDown(RIGHT_ARROW)) {
ship.x = ship.x+ 10;
if (ship.x >= 1350) {
ship.x = ship.x - 11;
}
}
//Left movement
if (keyIsDown(LEFT_ARROW)) {
ship.x = ship.x - 10;
if (ship.x <= 0) {
ship.x = ship.x + 11;
}
}
//Up movement
if (keyIsDown(UP_ARROW)) {
ship.y = ship.y - 10;
if (ship.y <= 350) {
ship.y = ship.y + 11;
}
}
//Down movement
if (keyIsDown(DOWN_ARROW)) {
ship.y = ship.y + 10;
if (ship.y >= 580) {
ship.y = ship.y - 11;
}
}
}
function drawShip()
{
ship.photo.resize(75,75);
image(ship.photo,ship.x-ship.photo.width/2,ship.y+ship.photo.height/2);
}
//Drawing the bullets
function drawBullets() {
fill(255);
rect(bullets.x[0],bullets.y[0], 5, 10);
rect(bullets.x[1],bullets.y[1], 5, 10);
rect(bullets.x[2],bullets.y[2], 5, 10);
}
//Controls the bullet movement
function updateBullets() {
bullets.y[0] = bullets.y[0] + 10;
}
//Checks if bullet is shot
function checkShoot() {
if (keyIsPressed && keyCode === 32) {
bullets.y[0] = ship.y;
}
}
function draw() {
background(0);
updateShip();
drawShip();
checkShoot();
updateBullets();
drawBullets();
}
You should move loadImage() function into your sketch's setup() function.
Like this
var ship;
function setup() {
createCanvas(1350,650);
ship = {
x: 625,
y: 475,
photo: loadImage("download.png")
}
//something
}
So for our project my group and I are trying to program a game. The objective of the game is to change the color of the other player's ship.
For example: If Player 1's ship is colored Red, and Player 2's ship is colored green, each bullet from player 1 that hits Player 2 will slowly turn player 2 from red to green. This is done by the help of bit shifts that is explained below. So for the majority of the time we have been encountering the Uncaught Type Error and we cannot find what the problem is. This file uses : https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js
and
http://craftyjs.com/release/0.4.2/crafty.js
as dependencies to help run the program.
$(document).ready(function() {
Crafty.init();
Crafty.canvas();
Crafty.load(["player.png"], function() {
//splice the spritemap
Crafty.sprite(1, "player.png",
{
ship: [0,0]
});
//start the main scene when loaded
Crafty.scene("main");
});
//player entity for player 1
var player1 = Crafty.e("2D, Canvas, Controls, Collision, Color, ship, player")
.attr({move: {left: false, right: false, up: false, down: false}, xspeed: 0, yspeed: 0, decay: 0.9, h: 50, w: 50, radius: 50, start_time: 0, x: Crafty.viewport.width / 2, y: Crafty.viewport.height / 2 })
.color('red')
.bind("keydown", function(e) {
//on keydown, set the move booleans
if(e.keyCode === Crafty.keys.RIGHT_ARROW) {
this.move.right = true;
} else if(e.keyCode === Crafty.keys.LEFT_ARROW) {
this.move.left = true;
} else if(e.keyCode === Crafty.keys.UP_ARROW) {
this.move.up = true;
} else if(e.keyCode === Crafty.keys.SPACE) {
var d = new Date();
this.start_time = d.getTime();
}
}).bind("keyup", function(e) {
//on key up, set the move booleans to false
if(e.keyCode === Crafty.keys.RIGHT_ARROW) {
this.move.right = false;
} else if(e.keyCode === Crafty.keys.LEFT_ARROW) {
this.move.left = false;
} else if(e.keyCode === Crafty.keys.UP_ARROW) {
this.move.up = false;
} else if(e.keyCode === Crafty.keys.SPACE) {
var time = new Date().getTime();
if((time - this.start_time) >= 5000)
var charge = 5;
//else
//var charge = (time - this.start_time)/1000;
Crafty.e("2D, DOM, Color, bullet")
.attr({
x: this._x,
y: this._y,
w: 1.5,
h: 1.5,
rotation: this._rotation,
xspeed: 20 * Math.sin(this._rotation / 57.3),
yspeed: 20 * Math.cos(this._rotation / 57.3),
})
.color('red')
.bind("enterframe", function() {
this.x += this.xspeed;
this.y -= this.yspeed;
//destroy if it goes out of bounds
if(this._x > Crafty.viewport.width || this._x < 0 || this._y > Crafty.viewport.height || this._y < 0) {
this.destroy();
}
});
}
}).bind("enterframe", function() {
if(this.move.right) this.rotation += 5;
if(this.move.left) this.rotation -= 5;
//acceleration and movement vector
var vx = Math.sin(this._rotation * Math.PI / 180) * 0.3,
vy = Math.cos(this._rotation * Math.PI / 180) * 0.3;
//if the move up is true, increment the y/xspeeds
if(this.move.up) {
this.yspeed -= vy;
this.xspeed += vx;
} else {
//if released, slow down the ship
this.xspeed *= this.decay;
this.yspeed *= this.decay;
}
//move the ship by the x and y speeds or movement vector
this.x += this.xspeed;
this.y += this.yspeed;
//if ship goes out of bounds, put him back
if(this._x > Crafty.viewport.width) {
this.x = -64;
}
if(this._x < -64) {
this.x = Crafty.viewport.width;
}
if(this._y > Crafty.viewport.height) {
this.y = -64;
}
if(this._y < -64) {
this.y = Crafty.viewport.height;
}
}).collision()
.onHit("bullet", function(e) {
//basically the bullet is color A and hits ship B and changes the color to ship A
//bullets are based on ship A
//red to green
if(e.color() != 'red'){
/*
if(e.color() === "#FF0000" && this.start_color === "#00FF00")
{
this.color = this.color + ("#010000" - "#000001") * e.radius;
//red to blue
} else if(e.color === "#FF0000" && this.color === "#0000FF")
{
this.color = this.color + ("#010000" - "#000001") * e.radius;
}
*/
//green to red
if(e.color() === "#00FF00")
{
this.color(this.color() + ("#010000" - "#000001") * e.radius);
}
/*
//green to blue
else if(e.color === "#00FF00" && this.color === "#0000FF")
{
this.color = this.color + ("#010000" - "#000001") * e.radius;
}
*/
//blue to red
else if(e.color() === "#0000FF")
{
this.color(this.color() + ("#010000" - "#000001") * e.radius);
}
/*
//blue to green
else (e.color === "#0000FF" && this.color === "#00FF00")
{
this.color = this.color + ("#010000" - "#000001") * e.radius;
}
*/
if(this.color() === e.color()){
Crafty.scene("end");
}
this.xspeed = this.xspeed - .1*e.xspeed;
this.yspeed = this.yspeed - .1*e.yspeed;
e[0].obj.destroy();
}
}).onHit("player", function(e) {
var diff = "#ff" - (this.color()>>4);
this.color(this.color() + (.2*diff) << 4);
if(e.color() === "green") {
this.color(this.color() - (.2*diff) << 2);
}
else {
this.color(this.color() - .2*diff);
}
this.xspeed = this.xspeed - e.xspeed;
this.yspeed = this.yspeed - e.yspeed;
});
});
EDIT: I managed to take out the comments and some irrelevant code
I fixed the error by basically making a new read to main in the html file and deleting the $(document) prompt. Thanks for all your help!