0
\$\begingroup\$

I have written a small game in javascript and I was wondering if the code is acceptable. I am reasonably new to javascript although I can't really get past the basics. All this code was originally in multiple files.

function Enemy(x,y,w,h,moveX){
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.speedX = 1;
	this.speedY = 1;
	this.dead = false;

	this.show = function(){
		ctx.fillRect(this.x, this.y, this.w, this.h);
	}

	this.update = function(){
		if(this.dead == true){
			ctx.clearRect(this.x, this.y, this.w, this.h);		
		}
		else{
			this.show();
		}		

		this.move();

	}

	this.move = function(){
		this.x += this.speedX;
		if(this.x > canvas.width - this.w){
			this.speedX = -this.speedX;
		}
		else if (this.x < 0){
			this.speedX = -this.speedX;
		}
		
		this.y += this.speedY;
		if(this.y > canvas.height - this.h){
			this.speedY = -this.speedY;
		}
		else if (this.y < 0){
			this.speedY = -this.speedY;
		}
		
	}

}

function Bullet(x,y,w,h,up,down,left,right, sprite){
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.hit = false;
	this.show = function(){
		if(sprite == null){
			ctx.fillRect(this.x,this.y,this.w,this.h);
		}
		else{
			let img = new Image();
			img.src = sprite;
			ctx.drawImage(img,this.x,this.y,this.w,this.h)
		}
	}

	this.moveX = function(dir){
		this.x += dir;
	}

	this.moveY = function(dir){
		this.y += dir;
	}

	this.update = function(){
		this.show();
		if(up) this.moveY(-5);
		if(down) this.moveY(5);
		if(left) this.moveX(-5);
		if(right) this.moveX(5);
	}

	this.clear = function(){
		ctx.clearRect(this.x,this.y,this.w,this.h);
	}
}

function Player(x, y, w, h, sprite){
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.show = function(){
		if(sprite == null){
			ctx.fillRect(this.x,this.y,this.w,this.h);
		}
		else {
			let img = new Image();
			img.src = sprite;
			ctx.drawImage(img,this.x,this.y,this.w,this.h);
		}
	}

	this.moveX = function(moveX){
		this.x += moveX;
	}

	this.moveY = function(moveY){
		this.y += moveY;
	}
	this.wallCollide = function(){
		if(this.x <= 0) this.x = 0;
		else if(this.x >= canvas.width - this.w) this.x = canvas.width - this.w;

		if(this.y <= 0) this.y = 0;
		else if(this.y >= canvas.height - this.h) this.y = canvas.height - this.h;
	}
	this.update = function(){
		this.show();
		this.wallCollide();
		if(keys.up) player.moveY(-2);
		if(keys.down) player.moveY(2);
		if(keys.right) player.moveX(2);
		if(keys.left) player.moveX(-2); 
	}


}


let canvas = document.getElementById('mainCanv');
let ctx = canvas.getContext('2d');
let keys = {
	up: false,
	down: false,
	left: false,
	right: false
};
let player = new Player(canvas.width/2, canvas.height/2, 40, 40);
let bullets = [];
let enemy = [];
let enemyCount = 3;
let totalEnemy = enemyCount;
let scoreNum = 0;

for(let i = 0; i < enemyCount; i++){
	enemy.push(new Enemy(Math.floor(Math.random()*canvas.width),Math.floor(Math.random()*canvas.height),20,20, Math.floor(Math.random()*2)));
}
function Update(){
	ctx.clearRect(0,0, canvas.width, canvas.height);
	drawScore();
	player.update();

	//Draw Enemies
	for(let j = 0; j < enemy.length; j++){
		enemy[j].update();
		if(Collides(enemy[j], player)){
			location.reload();
		}
	}
	
	if(enemyCount == 0){
		enemyCount = totalEnemy;
		totalEnemy += 1;
		for(let i = 0; i < enemyCount; i++){
			enemy.push(new Enemy(Math.floor(Math.random()*canvas.width),Math.floor(Math.random()*canvas.height),20,20, Math.floor(Math.random()*2)));
		}
		for(let j = 0; j < enemy.length; j++){
			enemy[j].speedX += 1;
			enemy[j].speedY += 1;
		}
	}


	//Draw bullets
	for(let i = 0; i < bullets.length; i++){
		bullets[i].update();
		if(bullets[i].x > canvas.width - bullets[i].w || bullets[i].x < 0){
			bullets.splice(i,1);
		}
		for(let j = 0; j < enemy.length; j++){
			if (Collides(bullets[i], enemy[j])){
				bullets.splice(i,1);
				enemy.splice(j,1);
				enemyCount -= 1;
				scoreNum +=  1;
			}
		}
	}

}


window.addEventListener('keydown', function(event){
	switch(event.keyCode){
		case 87:
			keys.up = true;
			break;
		case 83:
			keys.down = true;
			break;
		case 68:
			keys.right = true;
			break;
		case 65:
			keys.left = true;
			break;
		case 38:
			bullets.push(new Bullet(player.x+15, player.y+15, 5, 5,true,false,false,false));
			break;
		case 40:
			bullets.push(new Bullet(player.x+15, player.y+15, 5, 5,false,true,false,false))
			break;
		case 37:
			bullets.push(new Bullet(player.x+15, player.y+15, 5, 5,false,false,true,false))
			break;
		case 39:
			bullets.push(new Bullet(player.x+15, player.y+15, 5, 5,false,false,false,true))

	}
});

window.addEventListener('keyup', function(event){
	switch(event.keyCode){
		case 87:
			keys.up = false;
			break;
		case 83:
			keys.down = false;
			break;
		case 68:
			keys.right = false;
			break;
		case 65:
			keys.left = false;
			break;
	
	}
});

function Collides(spriteOne, spriteTwo){
	if(spriteOne.x > spriteTwo.x && spriteOne.x < spriteTwo.x+spriteTwo.w && spriteOne.y > spriteTwo.y && spriteOne.y < spriteTwo.y + spriteTwo.h){
		return true;
	}
}



function drawScore(){
	let scoreText = document.getElementById('score').innerHTML = scoreNum + " Enemies Killed";
}
setInterval(Update, 1);
<canvas id="mainCanv" width="800" height="600" style="background-color: lightgrey"></canvas>
<p id="score" style="position:absolute; top:0px"></p>

\$\endgroup\$
4
  • \$\begingroup\$ I get NS_ERROR_UNEXPECTED when running this -- does it work for everyone else? \$\endgroup\$
    – user1149
    Nov 8 '17 at 13:50
  • \$\begingroup\$ Yes but it does not actually affect the code. It is an error thrown because I have not managed deleting objects very efficiently. \$\endgroup\$
    – Asher
    Nov 8 '17 at 21:08
  • \$\begingroup\$ OK, it makes it difficult for me to play the game because the error screen is fairly large and apparently can't be closed. \$\endgroup\$
    – user1149
    Nov 9 '17 at 11:57
  • \$\begingroup\$ I think that is just a problem with the way they are run on this site. If you want you can try to copy and paste all the code into a separate file. \$\endgroup\$
    – Asher
    Nov 9 '17 at 22:25
1
\$\begingroup\$

I was wondering if the code is acceptable

The code is somewhat acceptable, though please consider the suggestions below- especially the first one!

Instance/Prototype Methods

It would be much more efficient to define the methods on the prototypes instead of attaching to each instance.

For example, take the methods out of the Enemy constructor:

this.show = function(){
    ctx.fillRect(this.x, this.y, this.w, this.h);
}

this.update = function(){
    ....

And make those methods of the prototype (after the definition of the constructor function):

Enemy.prototype.show = function(){
    ctx.fillRect(this.x, this.y, this.w, this.h);
}

Enemy.prototype.update = function(){
         ...

That way each method is declared only once instead of once per each instance. That would have huge impacts on the memory used by the browser. For more information about that topic, read about it in this post

Conditional logic

The logic in the Enemy method move() that conditionally negates the speed, I.e.:

if(this.x > canvas.width - this.w){
    this.speedX = -this.speedX;
}
else if (this.x < 0){
    this.speedX = -this.speedX;
}

Could be simplified using Logical OR:

if(this.x <0 || this.x > canvas.width - this.w){
    this.speedX = -this.speedX;
}

Comparison operators

The first Enemy method has an if statement like below:

if(this.dead == true){

If the aim is to ensure that this.dead is both true and in fact a Boolean, then the strict equality comparison operator (I.e. ===) can be used.

if(this.dead === true){

Otherwise if any value that is truthy will suffice then remove the == true.

if(this.dead){
\$\endgroup\$
1
  • \$\begingroup\$ Thanks. I recently learnt about the prototype class in javascript so in the future I will use that. Next time I will also use the other suggestions you made. \$\endgroup\$
    – Asher
    Nov 16 '17 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.