Thanks for the help, code below now is functional.
Previous problem (resolved):
I'm creating a game, and the enemy loads, but doesn't move. The player moves, so I've been searching for the error specific to the enemy's movement, but I haven't been able to determine the fault.
Enemy gets called to move by this function.
function moveAll() {
redShip.move(); // moves player, working
enemy.move(); // moves enemy, works now after correction.
}
The Enemy's move function
const UFO_SPEED = 1.9;
const UFO_TIME_BETWEEN_CHANGE_DIR = 85;
UFOClass.prototype = new movingWrapPositionClass();
function UFOClass() {
this.x = Math.random()*600;
this.y = Math.random()*800;
this.xv = 0;
this.yv = 0;
this.cyclesTilDirectionChange = 0; // added line to make work
this.superclassMove = this.move;
this.move = function() {
this.superclassMove();
this.cyclesTilDirectionChange--;
if(this.cyclesTilDirectionChange <= 0) {
var randAng = Math.random() * Math.PI*2.0;
this.xv = Math.cos(randAng) * UFO_SPEED;
this.yv = Math.sin(randAng) * UFO_SPEED;
this.cyclesTilDirectionChange = UFO_TIME_BETWEEN_CHANGE_DIR;
}
}
Shared movement function between player and enemy
function movingWrapPositionClass() {
this.move = function() {
this.x += this.xv;
this.y += this.yv;
this.handleScreenWrap();
}
Adding the Ship's function which is working
const SPACESPEED_DECAY_MULT = 0.99;
const THRUST_POWER = 0.15;
const TURN_RATE = 0.06;
shipClass.prototype = new movingWrapPositionClass();
function shipClass() {
this.myShot = new shotClass();
this.x = 400;
this.y = 300;
this.ang = -3;
this.xv = 0;
this.yv = 0;
this.myShipPic; // which picture to use
this.keyHeld_Gas = false;
this.keyHeld_TurnLeft = false;
this.keyHeld_TurnRight = false;
this.controlKeyUp;
this.controlKeyRight;
this.controlKeyDown;
this.controlKeyLeft;
this.controlKeyForShotFire;
this.setupInput = function(upKey, rightKey, downKey, leftKey, shotKey) {
this.controlKeyUp = upKey;
this.controlKeyRight = rightKey;
this.controlKeyDown = downKey;
this.controlKeyLeft = leftKey;
this.controlKeyForShotFire = shotKey;
}
this.superclassMove = this.move;
this.move = function() {
this.x += Math.cos(this.ang) * this.xv;
this.y += Math.sin(this.ang) * this.yv;
this.superclassMove();
this.xv *= SPACESPEED_DECAY_MULT;
this.yv *= SPACESPEED_DECAY_MULT;
if(this.keyHeld_Gas) {
this.xv += THRUST_POWER;
this.yv += THRUST_POWER;
this.superclassMove();
}
if(this.keyHeld_TurnLeft) {
this.ang -= TURN_RATE;
}
if(this.keyHeld_TurnRight) {
this.ang += TURN_RATE;
}
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.
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())
// ^^
I tried to rewrite a vanilla JavaScript Pong game in addition with PixiJS, mainly because I had resizing issues to get the canvas responsive.
The resizing works fine with PixiJS, but all the objects started to have trailing paths: Fiddle1
I figured that's because added new instances on update instead of just updating the position, so I tried to rework it from scratch again. The movement of the player works so far but I can't manage to get the ball working...I am kinda lost and willed to learn. Help is much appreciated ...Thanks a lot!
Fiddle2
import 'pixi.js';
// define gamne variables
const appWidth = window.innerWidth;
const appHeight = window.innerHeight;
const paddleWidth = 150;
const paddleHeight = 30;
const ballSize = 15;
const halfBall = ballSize / 2;
const appWidthHalf = appWidth / 2;
const appHeightHalf = appHeight / 2;
const paddleWidthHalf = paddleWidth / 2;
const pongColor = 0x57dfbf;
const bgColor = 0x282625;
const computerPositionX = appWidthHalf - paddleWidthHalf;
const computerPositionY = 50;
const playerPositionX = computerPositionX;
const playerPositionY = appHeight - computerPositionY - paddleHeight;
const ballPositionX = appWidthHalf - halfBall;
const ballPositionY = appHeightHalf - halfBall;
const playerSpeed = 4;
const computerSpeed = 4;
const ballSpeed = 3;
// Setup the ticker and the root stage PIXI.Container.
const app = new PIXI.Application(appWidth, appHeight, {
antialias: false,
backgroundColor: bgColor,
transparent: false,
resolution: 1,
});
// append app to body
document.body.appendChild(app.view);
// create graphic elements
const player = new PIXI.Graphics();
const computer = new PIXI.Graphics();
const ball = new PIXI.Graphics();
// Player
player
.beginFill(pongColor)
.drawRect(playerPositionX, playerPositionY, paddleWidth, paddleHeight)
.endFill();
// Computer
computer
.beginFill(pongColor)
.drawRect(computerPositionX, computerPositionY, paddleWidth, paddleHeight)
.endFill();
// Ball
ball
.beginFill(pongColor)
.drawRect(ballPositionX, ballPositionY, ballSize, ballSize)
.endFill();
// Player Movement
player.update = function () {
for (const key in keysDown) {
const value = Number(key);
if (value === 37) {
player.move(-playerSpeed, 0);
} else if (value === 39) {
player.move(playerSpeed, 0);
} else {
player.move(0, 0);
}
}
};
player.move = function (x, y) {
this.x += x;
this.y += y;
this.x_speed = x;
this.y_speed = y;
if (this.x < -appWidthHalf + paddleWidthHalf) {
this.x = -appWidthHalf + paddleWidthHalf;
this.x_speed = 0;
} else if (this.x + this.width - paddleWidthHalf > appWidthHalf) {
this.x = appWidthHalf - this.width + paddleWidthHalf;
this.x_speed = 0;
}
};
// computer Movement
// eslint-disable-next-line
computer.update = function(ball) {
const x_pos = ball.x;
let diff = -(computer.x + paddleWidthHalf - x_pos);
if (diff < 0 && diff < -computerSpeed) {
diff = -ballSize;
} else if (diff > 0 && diff > computerSpeed) {
diff = ballSize;
}
computer.position.set(diff, 0);
if (computer.x < 0) {
computer.x = 0;
} else if (computer.x + paddleWidthHalf > appWidth) {
computer.x = appWidth - paddleWidthHalf;
}
};
// Ball Movement
ball.update = function (paddle1, paddle2) {
this.x += this.x_speed;
this.y += this.y_speed;
const top_x = this.x - ballSize;
const top_y = this.y - ballSize;
const bottom_x = this.x + ballSize;
const bottom_y = this.y + ballSize;
if (this.x - ballSize < 0) {
this.x = ballSize;
this.x_speed = -this.x_speed;
} else if (this.x + ballSize > appWidth) {
this.x = appWidth - ballSize;
this.x_speed = -this.x_speed;
}
if (this.y < 0 || this.y > appHeight) {
this.x_speed = 0;
this.y_speed = ballSpeed;
this.x = appWidthHalf;
this.y = appHeightHalf;
}
if (top_y > appHeightHalf) {
if (
top_y < paddle1.y + paddle1.height &&
bottom_y > paddle1.y &&
top_x < paddle1.x + paddle1.width &&
bottom_x > paddle1.x
) {
this.y_speed = -ballSpeed;
this.x_speed += paddle1.x_speed / 2;
this.y += this.y_speed;
}
} else if (
top_y < paddle2.y + paddle2.height &&
bottom_y > paddle2.y &&
top_x < paddle2.x + paddle2.width &&
bottom_x > paddle2.x
) {
this.y_speed = ballSpeed;
this.x_speed += paddle2.x_speed / 2;
this.y += this.y_speed;
}
};
// controls
const keysDown = {};
window.addEventListener('keydown', (event) => {
keysDown[event.keyCode] = true;
});
window.addEventListener('keyup', (event) => {
delete keysDown[event.keyCode];
});
// update function
function update() {
player.update();
computer.update(ball);
ball.update(player, computer);
}
// append childs to app
app.stage.addChild(player);
app.stage.addChild(computer);
app.stage.addChild(ball);
// game loop
app.ticker.add(update);
Fiddle 1 definitely had issue, as you were not changing the ball.x and y there, but instead changing the graphics object, in fiddle2 it seemed, you were doing
good job with it. You just have some logical errors in the code, regarding setting the x- and y-coordinates and the ball movement.
So if you add console.log(this.x, this.y) inside the ball.update function in fiddle2, you will notice the NaN values.
To see the ball moving, if you set the initial values with:
ball.x_speed = 0;
ball.y_speed = 0;
And then
paddle.x_speed
paddle.y_speed
To
paddle.x
paddle.y
You see the ball moving at least (though collision logic doesn't work), (modified example in the fiddle below)
https://jsfiddle.net/4L6zbd01/
I have a problem with using the interp to improve my drawing function. For some reason the realX returns undefined every 3 frames. I'm using this guide to implement this functionality. The end goal is to make the collision system work so it would reflect bullets on an incomming shield (basicly how the bullets currently interact with the canvas borders. This is part of the code:
//INT
var canvas = document.getElementById('ctx'),
cw = canvas.width,
ch = canvas.height,
cx = null,
bX = canvas.getBoundingClientRect().left,
bY = canvas.getBoundingClientRect().top,
mX,
mY,
lastFrameTimeMs = 0,
maxFPS = 60,
fps = 60,
timestep = 1000/fps,
lastTime = (new Date()).getTime(),
currentTime = 0,
delta = 0,
framesThisSecond = 0,
lastFpsUpdate = 0,
running = false,
started = false,
frameID = 0;
var gametimeStart = Date.now(),
frameCount = 0,
score = 0,
player,
enemyList = {},
boostList = {},
bulletList = {},
pulseList = {},
shieldList = {};
//CREATE , create object
var Unit = function(){
this.x;
this.y;
this.realX;
this.realY;
this.type = "unit";
this.hp = 0;
this.color;
this.collision = function(arc){
return this.x + this.r + arc.r > arc.x
&& this.x < arc.x + this.r + arc.r
&& this.y + this.r + arc.r > arc.y
&& this.y < arc.y + this.r + arc.r
};
this.position = function(delta){
boundX = document.getElementById('ctx').getBoundingClientRect().left;
boundY = document.getElementById('ctx').getBoundingClientRect().top;
this.realX = this.x;
this.realX = this.y;
this.realR = this.r;
this.x += this.spdX * delta / 1000;
this.y += this.spdY * delta / 1000;
if (this.x < this.r || this.x + this.r > cw){
this.spdX = -this.spdX;
if (Math.random() < 0.5) {
this.spdY += 100;
} else {
this.spdY -= 100;
}
}
if (this.y < this.r || this.y + this.r > ch){
this.spdY = -this.spdY;
if (Math.random() < 0.5) {
this.spdX += 100;
} else {
this.spdX -= 100;
}
}
};
this.draw = function(interp){
ctx.save();
ctx.fillStyle = this.color;
ctx.beginPath();
//THIS DOESN'T WORK, the code is working perfectly without it
this.x = (this.realX + (this.x - this.realX) * interp);
this.y = (this.realY + (this.y - this.realY) * interp);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ctx.arc(this.x,this.y,this.r,0,2*Math.PI,false);
ctx.fill();
ctx.restore();
};
}
//Player
var Player = function(){
//Coördinates
this.x = 50;
this.y = 50;
this.r = 10;
//Stats
this.spdX = 30;
this.spdY = 5;
this.atkSpd = 1;
this.hp = 100;
//Other
this.name;
this.color = "green";
this.type = "player";
this.angle = 1;
this.attack = function attack(enemy){
enemy.hp -= 10;
};
};
Player.prototype = new Unit();
//Boost
var Boost = function(){
//Coördinates
this.x = 300;
this.y = 300;
this.r = 5;
};
Boost.prototype = new Unit();
//Bullet
var Bullet = function(){
//Coördinates
this.x = player.x;
this.y = player.y;
this.r = 3;
//Stats
var angle = player.angle*90;
this.spdX = Math.cos(angle/180*Math.PI)*200;
this.spdY = Math.sin(angle/180*Math.PI)*200;
//Other
if (player.angle === 4)
player.angle = 0;
player.angle++;
};
Bullet.prototype = new Unit();
var player = new Player();
var boost = new Boost();
var bullet = new Bullet();
//UPDATE
update = function(delta){
bullet.position(delta);
if(player.collision(boost)){
alert("collide");
}
};
//DRAW
draw = function(interp){
ctx.clearRect(0,0,cw,ch);
fpsDisplay.textContent = Math.round(fps) + ' FPS';
boost.draw(interp);
bullet.draw(interp);
player.draw(interp);
};
//LOAD
if (!document.hidden) { console.log("viewed"); }
function panic() { delta = 0; }
function begin() {}
function end(fps) {
if (fps < 25) {
fpsDisplay.style.color = "red";
}
else if (fps > 30) {
fpsDisplay.style.color = "black";
}
}
function stop() {
running = false;
started = false;
cancelAnimationFrame(frameID);
}
function start() {
if (!started) {
started = true;
frameID = requestAnimationFrame(function(timestamp) {
draw(1);
running = true;
lastFrameTimeMs = timestamp;
lastFpsUpdate = timestamp;
framesThisSecond = 0;
frameID = requestAnimationFrame(mainLoop);
});
}
}
function mainLoop(timestamp) {
if (timestamp < lastFrameTimeMs + (1000 / maxFPS)) {
frameID = requestAnimationFrame(mainLoop);
return;
}
delta += timestamp - lastFrameTimeMs;
lastFrameTimeMs = timestamp;
begin(timestamp, delta);
if (timestamp > lastFpsUpdate + 1000) {
fps = 0.25 * framesThisSecond + 0.75 * fps;
lastFpsUpdate = timestamp;
framesThisSecond = 0;
}
framesThisSecond++;
var numUpdateSteps = 0;
while (delta >= timestep) {
update(timestep);
delta -= timestep;
if (++numUpdateSteps >= 240) {
panic();
break;
}
}
draw(delta / timestep);
end(fps);
frameID = requestAnimationFrame(mainLoop);
}
start();
if (typeof (canvas.getContext) !== undefined) {
ctx = canvas.getContext('2d');
ctx.font = '30px Arial';
}
//CONTROLLES
//Mouse Movement
document.onmousemove = function(mouse){
var mouseX = mouse.clientX - bX;
var mouseY = mouse.clientY - bY;
if(mouseX < player.width/2)
mouseX = player.width/2;
if(mouseX > cw-player.width/2)
mouseX = cw-player.width/2;
if(mouseY < player.height/2)
mouseY = player.height/2;
if(mouseY > ch-player.height/2)
mouseY = ch-player.height/2;
player.x = mX = mouseX;
player.y = mY = mouseY;
}
//Pauze Game
var pauze = function(){
if(window.event.target.id === "pauze"){
stop();
}
if(window.event.target.id === "ctx"){
start();
}
};
document.addEventListener("click", pauze);
html {
height: 100%;
box-sizing: border-box;
}
*,*:before,*:after {
box-sizing: inherit;
}
body {
position: relative;
margin: 0;
padding-bottom: 6rem;
min-height: 100%;
font-family: "Helvetica Neue", Arial, sans-serif;
}
main {
margin: 0 auto;
padding-top: 64px;
max-width: 640px;
width: 94%;
}
main h1 {
margin-top: 0;
}
canvas {
border: 1px solid #000;
}
<canvas id="ctx" width="500" height="500"></canvas>
<div id="fpsDisplay" style="font-size:50px; position:relative; margin: 0 auto;"></div>
<p id="status"></p>
<button id="pauze">Pauze</button>
Declare, define, use.
The problem is you are using a variables that are undefined.
You have 3 objects, Player, Boost, and Bullet each of which you assign the object Unit to their prototypes.
You declare and define unit
function Unit(){
this.x;
this.y;
this.realX;
this.realY;
// blah blah
this.draw = function(){
// blah blah
this.draw = function (interp) {
ctx.save();
ctx.fillStyle = this.color;
ctx.beginPath();
// this.realX and this.realY are undefined
this.x = (this.realX + (this.x - this.realX) * interp);
this.y = (this.realY + (this.y - this.realY) * interp);
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
ctx.fill();
ctx.restore();
};
}
Then Player
var Player = function () {
//Coördinates
this.x = 50;
this.y = 50;
this.r = 10;
//Stats
// etc....
};
Then add a Unit to the prototype.
Player.prototype = new Unit();
This gives Player the unit properties x, y, realX, realY But realX and realY are undefined. Same with the two other objects Boost, Bullet
Any existing properties with the same name stay as is and keep their values. Any properties not in Player will get them from Unit, but in unit you have only declared the properties realX, realY you have not defined them.
You need to define the properties by giving them a value before you use them. You can do this in Unit
function Unit(){
this.x = 0; // default value I am guessing
this.y = 0;
this.realX = 10;
this.realY = 10;
Then in Player
function Player(){
this.x = 50; // these will keep the value they have
this.y = 50;
// realX and realY will have the defaults when you add to the prototype
// Or you can define them here
this.realX = 20;
this.realY = 20;
Before you can use a variable you must define what it is or check if it is defined and take the appropriate action.
// in draw function.
if(this.realX === undefined){
this.realX = 100; // set the default if not defined;
}
BTW you should get rid of the alerts they are very annoying when you have them appear one after the other without a chance to navigate away from the page.
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]
}
});