I've tried making a spritesheet move for a while now and tried various ways that are in the easeljs documentation. I still can't get the bloody thing to work though. So i was hoping some of you could take a look at it.
The spritesheet i'm using is 160x40 where 1 sprite is 40x40.
Here's my enemy function which should have the animation: (line 25-ish is the creation. In the move function is the gotoandplay)
var enemyWidth = 40;
var enemyHeight = 40;
function Enemy(number) {
this.number = number;
this.id = 'enemy';
var randomStartLoc = new locationOutsidePlayfield();
enemyLoc = new locationOutsidePlayfield();
this.x = randomStartLoc.x;
this.y = randomStartLoc.y;
this.health = 100;
//The damage a collision the enemy with a player does
this.damage = 30;
var target = new Target(this.x, this.y);
this.velX = target.velX;
this.velY = target.velY;
this.hitScore = 25;
this.killScore = this.hitScore*2;
var spriteSheet = new createjs.SpriteSheet({
images: ["resources/sprites/enemy_spritesheet.png"],
frames: {width:40, height:40},
animations: {
walk: [0, 3]
}
});
this.sprite = new createjs.BitmapAnimation(spriteSheet);
this.sprite.currentFrame = 0;
this.sprite = new createjs.BitmapAnimation(spriteSheet);
this.sprite.x = this.x;
this.sprite.y = this.y;
this.sprite.width = enemyWidth;
this.sprite.height = enemyHeight;
this.collide = function(arrayIndex, bullet) {
if (bullet) {
this.health -= player.damage;
}
if (this.health <= 0) {
//Generate a number between 0 and 10. If it's 1(10% chance) a powerup will be made on the spot of the death.
var percentage = Math.round(getRandomNumber(0, 10));
//If the percentage is one and there are no powerUps on the stage it's okay to add a powerup.
if (percentage < 6 && powerUp.length == 0) {
var pwrp = new Powerup(this.x, this.y);
powerUp.push(pwrp);
if (!powerUpLayer) {
powerUpLayer = new createjs.Container();
stage.addChild(powerUpLayer);
}
}
//Increase the score
score.increaseScore(this.killScore);
//Delete the object
delete this;
//Remove the sprite
enemyLayer.removeChild(this.sprite);
//Remove the enemy and the bullets from their array
enemies.splice(arrayIndex, 1);
for (var i in this.bullets) {
ammoLayer.removeChild(this.bullets[i].sprite);
delete this.bullets[i];
}
this.bullets = [];
} else {
//If the enemy didnt die, update the score with the hit score.
score.increaseScore(this.hitScore);
}
countEnemies();
}
this.draw = function() {
//enemyLayer.draw();
}
this.move = function() {
this.sprite.gotoAndPlay("walk");
//Set a boolean that will check later on if the enemy should change direction. Therefore getting a new X an Y.
var directionChange = false;
this.x += this.velX;
this.y += this.velY;
this.sprite.x = this.x;
this.sprite.y = this.y;
if (this.y <= -150) {
directionChange = true;
}
if (this.y >= (stage.canvas.height-this.sprite.height)+150) {
directionChange = true;
}
if (this.x <= -150) {
directionChange = true;
}
if (this.x >= (stage.canvas.width-this.sprite.width)+150) {
directionChange = true;
}
if (directionChange == true) {
var target = new Target(this.x, this.y);
this.velX = target.velX;
this.velY = target.velY;
}
}
this.flickr = function() {
this.sprite.alpha = 0.5;
var enem = this.sprite;
setTimeout(function() {
enem.alpha = 1;
}, 100);
}
this.bullets = [];
}
As request the enemy creation function. (p.s the stage is updated in the ticker, which is running fine)
var enemies = [];
var newEnemiesAmount;
var oldEnemiesAmount;
function createEnemies(amount) {
oldEnemiesAmount = (amount > 0) ? amount : oldEnemiesAmount;
newEnemiesAmount = amount+(Math.floor(oldEnemiesAmount)/5)
//Create a layer to spawn the enemies on
enemyLayer = new createjs.Container();
//Loop through the amount wanted.
for (var i = 0; i < newEnemiesAmount; i++) {
enemy = new Enemy(i);
createEnemyBullet(enemy);
//push the object in an array and add it to the newly made layer
enemies.push(enemy);
enemyLayer.addChild(enemy.sprite);
}
stage.addChild(enemyLayer);
}
Try specifying the number of frames in the spritesheet when constructing the spritesheet.
var spriteSheet = new createjs.SpriteSheet({
images: ["resources/sprites/enemy_spritesheet.png"],
frames: {width:40, height:40, count: 4},
animations: {
walk: [0, 3]
}
});
Related
For my space invader like game I want to make bullets that get shot by the enemies but the problem is that the bullets dont appear in this loop that I made. I tried several things like making only one bullet appear while that works it is not the result that I want. My idea behind the code is that a new bullet gets shot from the position of the enemies when the enemybullet.position == 1 and if it exceeds the height of the canvas I want the bullet to return to the enemies and be shot again.
The code that I used for this result is here:
sketch.js
var enemies = [];
var enemybullet = [];
function setup() {
createCanvas(800, 600);
for (var i = 0; i < 2; i++) {
enemies[i] = new Enemy(i*300+300, 100);
}
// I tried enemybullet = new Enemybullet(120, 200); and that drew the bullet but it wasnt assigned to the enemy
rectMode(CENTER);
}
function draw() {
background(0);
// enemybullet.show(); this is wat I used to draw the single projectile
// enemybullet.move();
var edge = false;
for (var i = 0; i < enemies.length; i++) {
enemies[i].show();
enemies[i].move();
if(enemies[i].x > width || enemies[i].x < 0) {
edge = true;
}
}
if (edge) {
for (var i = 0; i < enemies.length; i++) {
enemies[i].shiftDown();
}
}
for (var i = 0; i < enemybullet.length; i++) {
enemybullet[i].show();
enemybullet[i].move();
for (var j = 0; j < enemies.length; j++) {
if(enemybullet[i].position == 1){
var enemybullets = new Enemybullet(enemies[j].x(), enemies[j].y());
enemybullet.push(enemybullets);
enemybullet[i].x = enemybullet[i].x;
enemybullet[i].y = enemybullet[i].y + enemybullet[i].speed;
if(enemybullet[i].y >= height){
enemybullet[i].position = 2;
}
}
else{
enemybullet[i].y = enemies[i].y;
enemybullet[i].x = enemies[i].x;
}
if(enemybullet[i].position == 2 ){
enemybullet[i].y = enemies[i].y;
enemybullet[i].x = enemies[i].x;
enemybullet[i].position = 1;
}
}
}
enemybullet.js
function Enemybullet(x, y) {
this.x = x;
this.y = y;
this.width = 10;
this.height = 20;
this.position = 1;
this.speed = 2;
this.show = function() {
fill('#ADD8E6');
rect(this.x, this.y, this.width, this.height);
}
this.move = function() {
this.x = this.x;
this.y = this.y + this.speed;
}
}
enemy.js
function Enemy(x, y) {
this.x = x;
this.y = y;
this.r = 100;
this.xdir = 1;
this.shot = function() {
this.r = this.r * 0;
this.xdir = this.xdir * 0;
}
this.shiftDown = function() {
this.xdir *= -1;
this.y += this.r/2;
}
this.show = function() {
fill('#0000FF');
rect(this.x, this.y, this.r, this.r);
}
this.move = function() {
this.x = this.x + this.xdir;
}
}
Rather than having the bullets be in their own global array, try having the bullets be a variable in the Enemy class.
this.bullet = new Enemybullet(this.x, this.y);
Then you can give the enemies functions such as the following to update the bullets.
this.updateBullet = function() {
this.bullet.move();
this.bullet.show();
}
this.resetBullet = function() {
this.bullet = new Enemybullet(this.x, this.y);
}
Where you were looping through each bullet before, you can instead call enemies[i].updateBullet(); when you move and show the enemies.
And when you want the enemies to shoot another shot, call enemies[i].resetBullet();
You can see my implementation here.
i tried doing 'loadImage()' using preload() but it stuck in loading only
it did not help me because
i just copied code from a source
now it is working but if i add image using loadImage() it doesn't work
i am new to it please help me
html code
<!DOCTYPE html>
<html>
<head >
<meta charset="UTF-8">
<title> Kill Corona Virus </title>
<script src="libraries/p5.js" type="text/javascript"></script>
<script src="libraries/p5.dom.js" type="text/javascript"></script>
<script src="libraries/p5.sound.js" type="text/javascript"></script>
<script src="game.js" type="text/javascript"></script>
<script src="scoreboard.js" type="text/javascript"></script>
<script src="ship.js" type="text/javascript"></script>
<script src="bubble.js" type="text/javascript"></script>
<script src="sketch.js" type="text/javascript"></script>
<style>
body {
padding: 0;
margin: 0;
}
canvas {
vertical-align: top;
}
</style>
</head>
<body style="background-color:grey;">
</body>
</html>
bubble.js
function Bubble(x, y, size, speed, col, crazyness) {
// position
this.x = x;
this.y = y;
this.size = size;
this.speed = speed;
this.col = col;
// should we delete?
this.alive = true;
// crazy fx
this.crazyness = crazyness;
// schedule ball for destroyal
this.destroy = function() {
this.alive = false;
}
this.setSpeed = function(newSpeed) {
this.speed = newSpeed;
}
this.display = function() {
strokeWeight(1);
stroke(0);
fill(this.col);
ellipse(this.x, this.y, this.size, this.size);
};
// move the ball down (towards the ground)
this.move = function() {
this.y += this.speed;
this.size += random(-this.crazyness, this.crazyness);
};
// detects intersection with another Bubble()
this.intersects = function(other) {
d = dist(this.x, this.y, other.x, other.y);
r1 = this.size / 2;
r2 = other.size / 2;
if (d < r1 + r2)
return true
else
return false
}
}
game.js
function Game(ship, scoreboard) {
this.debug = false;
this.ship = ship;
this.scoreBoard = scoreboard;
var canvas = document.querySelector("canvas")
this.reset = function() {
this.gameActive = false;
this.scoreBoard.reset();
this.meteors = [];
this.projectiles = [];
this.meteorsDensity = 0.985;
this.meteorsDensityInc = 0.0001;
this.meteorsMinSpeed = 0.25;
this.meteorsMinSpeedInc = 0.0001;
this.meteorsMaxSpeed = 2;
this.meteorsMaxSpeedInc = 0.0001;
this.meteorsMinSize = 25;
this.meteorsMaxSize = 125;
}
this.isActive = function() {
return this.gameActive;
}
this.start = function() {
this.gameActive = true;
}
this.showWelcomeScreen = function() {
background(255);
textFont("Courier New");
fill(0);
noStroke();
textAlign(CENTER);
welcome_msg = "Kill Corona-virus";
textSize(random(65, 68));
text(welcome_msg, width / 2, height / 2);
action_msg = "Click to start, click to play.";
textSize(25);
text(action_msg, width / 2, height / 4);
score_msg = "Your previous score was " + scoreBoard.score + ".";
textSize(25);
text(score_msg, width / 2, height / 4 * 3);
credits_msg = "(c) 2020 - Haseef Azhaan";
textSize(15);
text(credits_msg, width / 2, height / 4 * 3.75);
}
this.createNewMeteor = function() {
if (random() > this.meteorsDensity) {
// pick random color, speed, size and horizontal position
col = color(random(255), random(255), random(255), 50);
speed = random(this.meteorsMinSpeed, this.meteorsMaxSpeed);
size = random(this.meteorsMinSize, this.meteorsMaxSize);
x = random(0 + size / 2, width - size / 2);
// vertical position is fixed
y = -size / 2;
// crzyness is just a visual FX
crazyness = random(0.5, 1.5);
//create a new "meteor" (a Bubble)
this.meteors.push(new Bubble(x, y, size, speed, col, crazyness));
}
};
this.updateAndDisplayMeteors = function() {
for (var i = this.meteors.length - 1; i >= 0; i--) {
this.meteors[i].move();
this.meteors[i].display();
}
};
this.updateAndDisplayProjectiles = function() {
for (var i = this.projectiles.length - 1; i >= 0; i--) {
this.projectiles[i].move();
this.projectiles[i].display();
}
};
this.updateAndDisplayShip = function() {
this.ship.updatePosition();
this.ship.display();
};
this.displayScoreboard = function() {
this.scoreBoard.display();
};
canvas.addEventListener("keyup",(e)=>{
if(e.key==='Enter'){alert("p")}
})
this.shoot = function() {
this.projectiles.push(this.ship.shoot());
}
this.stopIfMeteorHitGround = function() {
// iterate through all the meteors
for (var i = this.meteors.length - 1; i >= 0; i--) {
// when a meteor hits the ground, it's game over
if (this.meteors[i].y > height) {
this.gameActive = false;
}
}
};
this.removeLostProjectiles = function() {
// iterate through all the projectiles
for (var i = this.projectiles.length - 1; i >= 0; i--) {
// if a projectile passes the screen top, it's lost (can delete it)
if (this.projectiles[i].y < 0)
this.projectiles.splice(i, 1);
}
};
this.detectSuccessfullShots = function() {
// iterate through all the meteors
for (var i = this.meteors.length - 1; i >= 0; i--) {
// for each meteor, now consider all projectiles
for (var j = this.projectiles.length - 1; j >= 0; j--) {
// is there a hit?
if (this.meteors[i].intersects(this.projectiles[j])) {
// destroy both projectile and meteor
this.meteors[i].destroy();
this.projectiles[j].destroy();
// increment score!
this.scoreBoard.incrementScore();
// increment game difficulty! :)
this.meteorsMinSpeed += this.meteorsMinSpeedInc;
this.meteorsMaxSpeed += this.meteorsMaxSpeedInc;
this.meteorsDensity -= this.meteorsDensityInc;
}
}
}
};
this.removeKilledMeteors = function() {
// remove meteors scheduled for removal
for (var i = this.meteors.length - 1; i >= 0; i--) {
if (!this.meteors[i].alive)
this.meteors.splice(i, 1);
}
};
this.removeUsedProjectiles = function() {
for (var i = this.projectiles.length - 1; i >= 0; i--) {
if (!this.projectiles[i].alive)
this.projectiles.splice(i, 1);
}
};
this.setDebug = function(v) {
this.debug = v;
}
this.showDebugInfo = function() {
if (this.debug == true) {
print("# meteors: " + this.meteors.length);
print("# projectiles: " + this.projectiles.length);
}
}
}
scoreboard.js
function ScoreBoard(x,y) {
// position
this.x = x;
this.y = y;
// initial score
this.score = 0;
this.display = function() {
noStroke();
fill(0);
textAlign(RIGHT);
textFont("Courier new");
textSize(22);
text("score: " + this.score,this.x,this.y);
};
this.incrementScore = function() {
this.score++;
};
this.reset = function() {
this.score = 0;
}
}
ship.js
,
in the place of this triangle i want a image
function Ship(x,y) {
// ship position
this.x = x;
this.y = y;
// width and height
this.width = 25;
this.height = 50;
this.display = function() {
fill(color(255,0,0,50));
stroke(0);
strokeWeight(1);
triangle(this.x - this.width, this.y,this.x, this.y - this.height,this.x + this.width, this.y);
};
// update position based on mouseX
this.updatePosition = function() {
this.x = mouseX;
this.y = height - 10;
};
// shoot a projectile
this.shoot = function(){
projectile = new Bubble(this.x, this.y - 50, 10,-10,0,0);
return projectile;
}
}
sketch.js
var game;
var ship_im;
function setup() {
var a = createCanvas(windowWidth, windowHeight);
ship = new Ship(width / 2, height / 2);
var b = createCanvas(windowWidth, windowHeight);
ship_im = loadImage("ship.png")
scoreBoard = new ScoreBoard(width - 10, 20);
game = new Game(ship, scoreBoard);
game.reset();
game.setDebug(true);
}
function draw() {
if (game.isActive()) {
background(255);
// create new meteors
game.createNewMeteor();
// update position of and display stuff (meteors, projectiles, ship)
game.updateAndDisplayMeteors();
game.updateAndDisplayProjectiles();
game.updateAndDisplayShip();
// display the scoreboard
game.displayScoreboard();
// remove projectiles that passed the top of screen
game.removeLostProjectiles();
// detect successfull shots (projectile hits meteor)
// after a successfull shoot, projectile and meteor will be marked as "dead"
game.detectSuccessfullShots();
// remove "dead" meteors and projectiles
game.removeKilledMeteors();
game.removeUsedProjectiles();
// if a meteor hits the ground, it's game over.
game.stopIfMeteorHitGround();
// show debug info when enables
//game.showDebugInfo();
} else {
game.showWelcomeScreen();
}
}
function mouseClicked() {
// when the game is active, clicking the mouse shots
if (game.gameActive)
game.shoot();
// when the game is inactive, clicking the mouse restarts the game
else {
game.reset();
game.start();
}
}
function keyPressed(){
if(keyCode===ENTER){
if (game.gameActive)
game.shoot();
// when the game is inactive, clicking the mouse restarts the game
else {
game.reset();
game.start();
}
}
}
please ignore bad indentation
This is a question from javascript.
if (game.ship.livesPool.getPool[0].getDamaged())
I got an error on this getDamaged() function as undefined inside another function.
game = new Game();
game is defined outside this function as a global variable.
this.ship = new Ship();
ship is defined inside Game class.
this.livesPool = new Pool();
var pool = [];
this.getPool = function(){
return pool;
}
livesPool is defined inside Pool class. pool is an array defined in Pool class.
getPool function will return this array.
pool[i] = new Lives();
each of the pool[i] will be assigned Lives object in Pool class.
this.getDamaged = function(){
return this.damaged;
}
getDamaged() function is defined this way inside Lives class.
Why does it show me that this function is undefined?
Game class
function Game() {
this.init = function () {
// Obtain the canvas from HTML
this.bgCanvas = document.getElementById('background');
this.shipCanvas = document.getElementById('ship');
this.mainCanvas = document.getElementById('main');
// Load the context
/* Just one of them passing to conditional statement is enough to test
* the availability
*/
if (this.bgCanvas.getContext) {
this.bgContext = this.bgCanvas.getContext('2d');
this.shipContext = this.shipCanvas.getContext('2d');
this.mainContext = this.mainCanvas.getContext('2d');
Background.prototype.context = this.bgContext;
Background.prototype.canvasHeight = this.bgCanvas.height;
Background.prototype.canvasWidth = this.bgCanvas.width;
Ship.prototype.context = this.shipContext;
Ship.prototype.canvasHeight = this.shipCanvas.height;
Ship.prototype.canvasWidth = this.shipCanvas.width;
Lives.prototype.context = this.shipContext;
Lives.prototype.canvasHeight = this.shipCanvas.height;
Lives.prototype.canvasWidth = this.shipCanvas.width;
Bullet.prototype.context = this.mainContext;
Bullet.prototype.canvasHeight = this.mainCanvas.height;
Bullet.prototype.canvasWidth = this.mainCanvas.width;
Bullet.prototype.bossContext = this.shipContext;
Enemy.prototype.context = this.mainContext;
Enemy.prototype.canvasHeight = this.mainCanvas.height;
Enemy.prototype.canvasWidth = this.mainCanvas.width;
Boss.prototype.context = this.shipContext;
Boss.prototype.canvasHeight = this.shipCanvas.height;
Boss.prototype.canvasWidth = this.shipCanvas.width;
// Define background in the game
this.background = new Background();
this.background.init(0, 0, imageRepository.background.width, imageRepository.background.height);
// Define ship in the game
this.ship = new Ship();
var shipStartX = this.shipCanvas.width / 2 - imageRepository.ship.width / 2;
var shipStartY = this.shipCanvas.height / 4 * 3 + imageRepository.ship.height / 2;
this.ship.init(shipStartX, shipStartY, imageRepository.ship.width, imageRepository.ship.height);
this.ship.type = "ship";
this.ship.hasExplored = false;
// Define enemy pools in the game
this.enemyPool = new Pool(10);
this.enemyPool.init("enemy");
this.boss = new Boss();
return true;
}
else {
return false;
}
};
this.runGame = function () {
this.ship.draw();
animate();
};
this.restart = function () {
this.bgContext.clearRect(0, 0, this.bgCanvas.width, this.bgCanvas.height);
this.mainContext.clearRect(0, 0, this.mainCanvas.width, this.mainCanvas.height);
this.shipContext.clearRect(0, 0, this.shipCanvas.width, this.shipCanvas.height);
this.enemyPool.init("enemy");
var shipStartX = this.shipCanvas.width / 2 - imageRepository.ship.width / 2;
var shipStartY = this.shipCanvas.height / 4 * 3 + imageRepository.ship.height / 2;
this.ship.x = shipStartX;
this.ship.y = shipStartY;
this.ship.hasExplored = false;
this.ship.bulletPool.init("bullet");
score = 0;
displayedScore = 0;
bossExist = false;
this.boss.life = 100;
this.boss.bulletPool.init("boss_bullet");
this.boss.fireRate = 0;
while(this.ship.livesPool.getSize() < 3){
this.ship.livesPool.increaseLives();
}
document.getElementById('game-over').style.display = "none";
this.runGame();
};
this.start = function () {
gameStarted = true;
document.getElementById('main-menu').style.display = 'none';
document.getElementById('score-board').style.display = 'block';
};
this.backHome = function () {
gameStarted = false;
document.getElementById('game-over').style.display = 'none';
document.getElementById('score-board').style.display = 'none';
document.getElementById('main-menu').style.display = 'block';
this.restart();
};
}
Ship class.
function Ship() {
this.speed = 5;
this.bulletPool = new Pool(maxNumOfBullets);
this.bulletPool.init("bullet");
this.bulletSoundPool = new SoundPool(maxNumOfBullets);
this.bulletSoundPool.init("bullet");
this.livesPool = new Pool(3);
this.livesPool.init("lives");
this.hasExplored = false;
this.life = 3;
var fireRate = 15;
var counter = 0;
this.draw = function () {
if (this.livesPool.getSize() <= 0) {
this.context.clearRect(this.x, this.y, this.width, this.height);
}
else {
this.context.drawImage(imageRepository.ship, this.x, this.y);
}
}
this.move = function () {
counter++;
// Determine if the action is move action
if (KEY_STATUS.left || KEY_STATUS.right ||
KEY_STATUS.down || KEY_STATUS.up) {
// The ship moved, so erase it's current image so it can
// be redrawn in it's new location
this.context.clearRect(this.x, this.y, this.width, this.height);
// Update x and y according to the direction to move and
// redraw the ship. Change the else if's to if statements
// to have diagonal movement.
if (KEY_STATUS.left) {
this.x -= this.speed
if (this.x <= 0) // Keep player within the screen
this.x = 0;
} else if (KEY_STATUS.right) {
this.x += this.speed
if (this.x >= this.canvasWidth - this.width)
this.x = this.canvasWidth - this.width;
} else if (KEY_STATUS.up) {
this.y -= this.speed
if (this.y <= this.canvasHeight / 4 * 3)
this.y = this.canvasHeight / 4 * 3;
} else if (KEY_STATUS.down) {
this.y += this.speed
if (this.y >= this.canvasHeight - this.height)
this.y = this.canvasHeight - this.height;
}
}
this.draw();
if (KEY_STATUS.space && counter >= fireRate) {
this.fire();
counter = 0;
}
};
this.fire = function () {
this.bulletPool.getTwo(this.x + imageRepository.ship.width / 10, this.y, 3);
this.bulletSoundPool.get();
};
}
Pool class.
function Pool(maxSize) {
var size = maxSize;
var pool = [];
var type = "";
// This design enables us to not need to create an object each loop
this.init = function (obj) {
if (obj === "bullet") {
type = "bullet";
for (var i = 0; i < size; i++) {
var bullet = new Bullet("bullet");
bullet.init(0, 0, imageRepository.bullet.width, imageRepository.bullet.height);
bullet.collidableWith = "enemy";
bullet.type = "bullet";
pool[i] = bullet;
}
}
else if (obj === "enemy") {
type = "enemy";
for (var i = 0; i < size; i++) {
var enemy = null;
var rand = Math.floor(Math.random() * 10);
if (rand < 8) {
enemy = new Enemy("enemy", 0, 10);
enemy.init(0, 0, imageRepository.enemy.width, imageRepository.enemy.height);
}
else {
enemy = new Enemy("enemy2", 2, 15);
enemy.init(0, 0, imageRepository.enemy2.width, imageRepository.enemy2.height);
}
enemy.collidableWith = "ship";
enemy.type = "enemy";
pool[i] = enemy;
}
}
else if (obj === "boss_bullet") {
type = "boss_bullet";
for (var i = 0; i < size; i++) {
var bullet = new Bullet("boss_bullet");
bullet.init(0, 0, imageRepository.boss_bullet.width, imageRepository.boss_bullet.height);
bullet.collidableWith = "ship";
bullet.type = "bullet";
pool[i] = bullet;
}
}
else if (obj === "lives") {
type = "lives";
for (var i = 0; i < size; i++) {
var lives = new Lives();
lives.init(imageRepository.background.width - ((i + 1) * imageRepository.lives.width) - 10,
imageRepository.background.height - imageRepository.lives.height - 10,
imageRepository.lives.width, imageRepository.lives.height);
pool[i] = lives;
}
}
};
// Return pool attribute for usage in checking collision
this.getPool = function () {
var res = [];
for (var i = 0; i < pool.length; i++) {
if (pool[i].alive) {
res.push(pool[i]);
}
}
return res;
};
this.get = function (x, y, speed) {
if (pool[size - 1] instanceof Bullet) {
if (!pool[size - 1].alive) {
pool[size - 1].spawn(x, y, speed);
pool.unshift(pool.pop());
}
}
else if (pool[size - 1] instanceof Enemy) {
if (!pool[size - 1].alive) {
if (!(pool[0].alive && pool[0].y <= pool[0].height)) {
pool[size - 1].spawn(x, y, speed);
pool.unshift(pool.pop());
}
}
}
};
this.getTwo = function (x, y, speed) {
if (type === "bullet") {
if (!pool[size - 1].alive && !pool[size - 2].alive) {
this.get(x, y, speed);
this.get(x + (imageRepository.ship.width * 8) / 10
- imageRepository.bullet.width, y, speed);
}
}
else if (type === "boss_bullet") {
if (!pool[size - 1].alive && !pool[size - 2].alive) {
this.get(x, y, speed);
// This will have the center of boss as the center between two bullets
// x + 2 * (imageRepository.boss.width / 2 - x) - imageRepository.boss_bullet.width
this.get(x + imageRepository.boss.width * 3 / 5 - imageRepository.boss_bullet.width,
y, speed);
console.log(x);
console.log(x + imageRepository.boss.width * 3 / 5 - imageRepository.boss_bullet.width);
}
}
};
this.animate = function () {
for (var i = 0; i < size; i++) {
if (pool[i].alive) {
if (pool[i].draw()) {
pool[i].clear();
pool.push((pool.splice(i, 1))[0]);
}
}
else
break;
}
};
this.getSize = function () {
return size;
};
this.setSize = function (input) {
size = input;
};
this.decreaseLives = function () {
if (size >= 1) {
if (pool[size - 1] instanceof Lives) {
pool[size - 1].setDamaged(true);
size--;
}
}
};
this.increaseLives = function(){
if (pool[size - 1] instanceof Lives){
pool[size - 1].setDamaged(true);
size++;
}
};
}
Lives class.
function Lives() {
this.alive = true;
this.damaged = false;
this.draw = function () {
this.context.clearRect(this.x, this.y, this.width, this.height);
this.context.drawImage(imageRepository.lives, this.x, this.y);
if (this.damaged)
return true;
}
this.clear = function () {
alive = false;
this.x = -1 * this.width;
this.y = -1 * this.height;
}
this.getDamaged = function(){
return this.damaged;
}
this.setDamaged = function(input){
this.damaged = input;
}
}
getPool is a function, you need to call it:
if (game.ship.livesPool.getPool()[0].getDamaged())
// ^^
What is confusing is how this simple script works fine:
function A() {
this.value = 0;
}
A.prototype.foo = function() {
console.log(this.value);
};
function B() {
this.value = 1;
this.foo();
}
B.prototype = Object.create(A.prototype);
B.prototype.bar = function() {
console.log(this instanceof A);
}
new B().bar();
// outputs 1, true
However, this larger script gives an error this.loadDimensions is not a function:
Basically, there is a Player class, which inherits from a MovingComponent class, which inherits from a VisibleComponent class. They all have methods attached to them.
const PX_SZ = 4, MAX_HEIGHT = 100, MIN_HEIGHT = 300;
var resources = {};
resources.sprites = {};
resources.sprites.player = new Image();
resources.sprites.player.src = "resources/sprites/player.png";
resources.sprites['default'] = new Image();
resources.sprites['default'].src = "resources/sprites/default.png";
resources.sprites.items = {};
resources.sprites.backgroundEntities = {};
var itemsTemp = ['default', 'coin0'];
for (var i=0; i<itemsTemp.length; i++) {
var item = itemsTemp[i];
resources.sprites.items[item] = new Image();
resources.sprites.items[item].src = "resources/sprites/items/" + item + ".png";
}
var backgroundEntitiesTemp = ['tree0'];
for (var i=0; i<backgroundEntitiesTemp.length; i++) {
var ent = backgroundEntitiesTemp[i];
resources.sprites.backgroundEntities[ent] = new Image();
resources.sprites.backgroundEntities[ent].src = "resources/sprites/background-entities/" + ent + ".png";
}
var canvas, ctx;
var player = new Player();
var keys = {};
var game = new Game(Math.floor(Math.random()*1000000));
var world = new World();
/** #class */
function Game(seed) {
this.seed = seed;
}
/** #class */
function World() {
this.gravity = 0.4;
this.chances = {
items: {
coin0: 0.005
},
backgroundEntities: {
tree0: 0.05
}
};
this.itemsFloating = [];
this.backgroundEntities = [];
// for spawning
this.exploredRightBound = 0;
this.exploredLeftBound = 0;
}
World.prototype.generate = function(left, right) {
if (left >= right) throw "left >= right in World#generate(left,right)";
for (x = left; x < right; x += PX_SZ) {
// world generation code here
// coin0
var level = getGroundHeightAt(x)
if (Math.random() <= this.chances.items.coin0) {
var item = new ItemFloating("coin0", x, level-20);
this.itemsFloating.push(item);
}
if (Math.random() <= this.chances.backgroundEntities.tree0) {
var ent = new BackgroundEntity("tree0", x, level-resources.sprites.backgroundEntities.tree0.height);
this.backgroundEntities.push(ent);
}
}
};
/**
* #class
* anything that has a sprite attached to it
*/
function VisibleComponent() {
this.sprite = resources.sprites['default'];
}
VisibleComponent.prototype.loadDimensions = function() {
console.log('load');
};
VisibleComponent.prototype.draw = function() {
ctx.drawImage(this.sprite, this.x, this.y, this.width, this.height);
};
/** #class */
function Item(name="default") {
VisibleComponent.call(this);
this.name = name || "default";
this.sprite = resources.sprites.items[name];
this.loadDimensions();
}
Item.prototype = Object.create(VisibleComponent.prototype);
/** #class */
function ItemFloating(name, x, y) {
Item.call(this, name);
this.name = name;
this.x = x;
this.y = y;
this.loadDimensions(); // (when ready of now)
}
ItemFloating.prototype = Object.create(Item.prototype);
/** #class */
function BackgroundEntity(name="default", x=0, y=0) {
VisibleComponent.call(this);
this.name = name;
this.x = x;
this.y = y;
this.width = 1;
this.height = 1;
this.sprite = resources.sprites.backgroundEntities[this.name];
this.loadDimensions();
}
BackgroundEntity.prototype = Object.create(VisibleComponent.prototype);
/** #class */
function MovingEntity(x=0, y=0) {
VisibleComponent.call(this);
this.x = x;
this.y = y;
this.width = 1;
this.height = 1;
}
MovingEntity.prototype = Object.create(VisibleComponent.prototype);
MovingEntity.prototype.collisionWith = function(ent) {
return ((this.x>=ent.x&&this.x<=ent.x+ent.width) || (ent.x>=this.x&&ent.x<=this.x+this.width))
&& ((this.y>=ent.y&&this.y<=ent.y+ent.height) || (ent.y>=this.y&&ent.y<=this.y+this.height));
};
/** #class */
function Player() {
MovingEntity.call(this);
this.inventory = {};
console.log(this instanceof VisibleComponent);
this.speed = 4;
this.jumpSpeed = 8;
this.vspeed = 0;
this.sprite = resources.sprites.player;
this.loadDimensions();
this.direction = "right";
}
Player.prototype = Object.create(MovingEntity.prototype);
Player.prototype.draw = function() {
ctx.save();
ctx.translate(this.x, this.y);
if (this.direction == "left") ctx.scale(-1, 1); // flip over y-axis
ctx.translate(-this.sprite.width, 0);
ctx.drawImage(this.sprite, 0, 0, this.width, this.height);
ctx.restore();
}
Player.prototype.move = function() {
if (keys['ArrowLeft']) {
this.x -= this.speed;
this.direction = "left";
var leftEdge = this.x-canvas.width/2-this.width/2;
if (leftEdge < world.exploredLeftBound) {
world.generate(leftEdge, world.exploredLeftBound);
world.exploredLeftBound = leftEdge;
}
}
if (keys['ArrowRight']) {
this.x += this.speed;
this.direction = "right";
var rightEdge = this.x+canvas.width/2+this.width/2;
if (rightEdge > world.exploredRightBound) {
world.generate(world.exploredRightBound, rightEdge);
world.exploredRightBound = rightEdge;
}
}
var level = getGroundHeightAt(this.x+this.width/2);
if (this.y + this.height < level) {
this.vspeed -= world.gravity;
} else if (this.y + this.height > level) {
this.y = level - this.height;
this.vspeed = 0;
}
if (keys[' '] && this.y+this.height == getGroundHeightAt(this.x+this.width/2)) this.vspeed += this.jumpSpeed;
this.y -= this.vspeed;
for (var i=0; i<world.itemsFloating.length; i++) {
var item = world.itemsFloating[i];
if (this.collisionWith(item)) {
if (this.inventory.hasOwnProperty(item.name)) this.inventory[item.name]++;
else this.inventory[item.name] = 1;
world.itemsFloating.splice(i, 1);
}
}
};
I'm fairly new to javascript inheritance, so I don't understand what I'm doing wrong. Also, since the first script worked, I figured there's something I'm just overlooking in my second script. Any help would be appreciated.
EDIT
In the beginning of the file, I declare player as a new Player(). resources contains Image instances that point to various image files. ctx and canvas are pretty self-explanatory globals.
Also, player isn't recognized as an instance of MovingEntity or VisibleComponent, even though Player's prototype is set to Object.create(MovingEntity.prototype), which has its prototype set to Object.create(VisibleComponent.prototype).
One other thing to mention is that in the definition of loadDimensions() in VisibleComponent, either the onload property of this.sprite is set to a function, or addEventListener() is called for 'load', depending on whether this.sprite has loaded (width != 0) or not.
In the beginning of the file, I declare player as a new Player().
That's the problem, you need to call the constructor after having set up your class. It currently doesn't throw an error about Player not being a function because the declaration is hoisted, but the prototype is not yet initialised with the value you expect so it indeed does not have a .loadDimensions() method yet.
I'm working on getting all the components for my final together using the P5.play engine and while I have made some progress with setting up aspects of my mini game I'm having a hard time with the collision. It should be easy but for whatever reason when I set up my two objects (the fish and the garbage) they do not collide. I am trying to set it up so that when the garbage collides with the fish the fish either get removed or are reset to a place where they can continue to move on the screen while tallying the score. I managed to get the player sprite to collect the garbage and add to the score using overlapPoint and placing the condition in the update for the garbage object. But when I attempt the same technique for the fish on the garbage object an error occurs and everything disappears on the screen. I commented out the portion that is I have tried multiple ways including the collide() function on the objects with the proper conditionals but nothing seems to work. A bit frustrating. I have tried various other ways. So I'm asking for expert advice. Any assistance is appreciated. this is the code that i have thus far:
var bg;
var player;
var player_stand_sprites;
var player_stand;
var fish_swim_sprites;
var fish_swim;
var fish = [];
var garbage_drop_sprites;
var garbage_drop;
var garbage = [];
var score = 0;
function preload() {
bg = loadImage("final-bg.png");
player_stand_sprites = loadSpriteSheet("player2.png", 100, 100, 1);
player_stand = loadAnimation(player_stand_sprites);
fish_swim_sprites = loadSpriteSheet("fish.png", 75, 75, 1);
fish_swim = loadAnimation(fish_swim_sprites);
garbage_drop_sprites = loadSpriteSheet("metal.png", 41, 75, 1);
garbage_drop = loadAnimation(garbage_drop_sprites);
}
function setup() {
createCanvas(720, 360);
player = createSprite(100, 0);
player.addAnimation("stand", player_stand);
player.setCollider("circle", 0, 0, 32, 32);
player.depth = 10;
//player.debug = true;
//to make fish
for (var i = 0; i < 10; i++){
fish.push( new Fish(random(0,width), random(height/2, height)) );
for (var i = 0; i < fish.length; i++) {
fish[i].init();
}
}
//to make garbage
for (var a = 0; a < 5; a++){
garbage.push( new Garbage(random(0,width), random(width/2, width)));
}
}
function draw() {
background(bg);
player.position.x = mouseX;
player.position.y = mouseY;
for (var i = 0; i < fish.length; i++) {
fish[i].update();
}
for (var a = 0; a < garbage.length; a++) {
garbage[a].update();
}
/**for (var b = 0; b < fish.length; b++) {
if(fish[b].collide(garbage[b])){
fish[b].remove;
}
}**/
text(score,100,100);
drawSprites();
}
function Garbage(x,y){
this.sprite = createSprite(x, y);
this.sprite.addAnimation("drop", garbage_drop);
this.sprite.setCollider("circle",0,0,32,32);
this.speed = random(1,2);
this.sprite.debug = true;
this.update = function() {
this.sprite.position.y += this.speed;
if(this.sprite.position.y > height){
this.sprite.position.y = 0;
}
if(this.sprite.overlapPoint(player.position.x, player.position.y)){
this.sprite.position.x = random(0,width);
this.sprite.position.y = -75;
score++;
}
}
}
function Fish(x,y) {
this.sprite = createSprite(x, y);
this.sprite.addAnimation("swim", fish_swim);
this.sprite.setCollider("rectangle",0,0,75,32);
this.speed = 0;
this.sprite.debug = true;
this.init = function() {
if (this.sprite.position.x < width/2) {
this.sprite.mirrorX(-1);
this.speed = random(1, 2);
} else {
this.speed = -random(1,2);
}
}
this.update = function() {
this.sprite.position.x += this.speed;
if(this.sprite.position.x > width){
this.sprite.position.x = 0;
}else if(this.sprite.position.x < -width){
this.sprite.position.x = width;
}
}
}
I actually found the answer to my question a while back but am going to post it here.
The initial problem was that the sprites would not collide but with a simple for loop nested within another for loop and adding a .sprite to each of the objects being checked, I was able to get all the elements to collide properly.
Here is the code I revised to make it work seamlessly using the P5.play.js library:
var bg;
var img;
var dead = false;
var deadFish = 0;
var player;
var player_stand_sprites;
var player_stand;
var fish_swim_sprites;
var fish_swim;
var fish = [];
var garbage_drop_sprites;
var garbage_drop;
var garbage = [];
var score = 0;
//////////////////////////////////////////
function preload() {
bg = loadImage("final-bg.png");
img = loadImage("fish.png");
player_stand_sprites = loadSpriteSheet("player2.png", 100, 100, 1);
player_stand = loadAnimation(player_stand_sprites);
fish_swim_sprites = loadSpriteSheet("fish.png", 75, 75, 1);
fish_swim = loadAnimation(fish_swim_sprites);
garbage_drop_sprites = loadSpriteSheet("metal.png", 41, 75, 1);
garbage_drop = loadAnimation(garbage_drop_sprites);
}
//////////////////////////////////////////
function setup() {
createCanvas(720, 360);
player = createSprite(100, 0);
player.addAnimation("stand", player_stand);
player.setCollider("circle", 0, 0, 32, 32);
player.depth = 10;
//player.debug = true;
//to make fish
for (var i = 0; i < 10; i++){
fish.push( new Fish(random(0,width), random(height/2, height)) );
for (var i = 0; i < fish.length; i++) {
fish[i].init();
}
}
//to make garbage
for (var a = 0; a < 5; a++){
garbage.push( new Garbage(random(0,width), random(width/2, width)));
}
}
function draw() {
scene_start();
}
//////////////////////////////////////////
function scene_start(){
push();
background("green");
fill("white");
textAlign(CENTER);
textSize(50);
textStyle(BOLD);
text("SPOT A FISH", width/2,height/3.5);
image(img, width/2.3, height/3);
textSize(15);
text("Rules: dont let the cans touch the fish. 5 fish die and you must start over", width/2, height/1.5);
textSize(30);
text("press up arrow key to start", width/2, height/1.2);
pop();
if (keyCode == UP_ARROW) {
scene_1();
}
}
function scene_1(){
background(bg);
score_card();
if(!dead){
player.position.x = mouseX;
player.position.y = mouseY;
for (var i = 0; i < fish.length; i++) {
fish[i].update();
}
for (var i = 0; i < garbage.length; i++) {
garbage[i].update();
}
for (var a = 0; a < garbage.length; a++) {
for (var b = 0; b < fish.length; b++) {
if(fish[b].sprite.collide(garbage[a].sprite)){
fish[b].sprite.position.x = random(-500, -100);
deadFish ++;
if(deadFish === 5){
dead = true;
}
}
}
}
drawSprites();
}else{
score_card();
textSize(30);
textStyle(BOLD);
textAlign(CENTER);
text("YOU DIED PLEASE TRY AGAIN",width/2,height/2);
text("press any button to start again",width/2,height/1.5);
if(keyIsPressed === true){
deadFish = 0;
dead = false;
}
}
}
function Garbage(x,y){
this.sprite = createSprite(x, y);
this.sprite.addAnimation("drop", garbage_drop);
this.sprite.setCollider("circle",0,0,32,32);
this.speed = random(1,2);
//this.sprite.debug = true;
this.update = function() {
this.sprite.position.y += this.speed;
if(this.sprite.position.y > height){
this.sprite.position.y = 0;
}
if(this.sprite.overlapPoint(player.position.x, player.position.y)){
this.sprite.position.x = random(0,width);
this.sprite.position.y = random(-200,-75);
score++;
}
if(score === 100){
this.speed = random(2,3);
score += 1000;
}else if(score === 1200){
this.speed = random(3,3.5);
score += 1000;
}
}
}
var score_card = function(){
fill("black");
rect(0,0,width,30);
textStyle(BOLD);
fill("white");
text("SCORE: "+score,10,20);
text("DEAD FISH: "+deadFish,width/1.2,20)
}
function Fish(x,y) {
this.sprite = createSprite(x, y);
this.sprite.addAnimation("swim", fish_swim);
this.sprite.setCollider("rectangle",0,0,75,32);
this.speed = 0;
this.sprite.debug = true;
this.init = function() {
if (this.sprite.position.x < width/2) {
this.sprite.mirrorX(-1);
this.speed = random(1, 2);
} else {
this.speed = -random(1,2);
}
}
this.update = function() {
this.sprite.position.x += this.speed;
if(this.sprite.position.x > width){
this.sprite.position.x = 0;
}else if(this.sprite.position.x < -width){
this.sprite.position.x = width;
}
}
}