Making the enemy die when hit with a bullet - javascript

I am making a javascript game, and I can't make the enemy die when hit with a bullet. Here is the part of the code that I just can't understand:
for(var i=0;i<enemies.length;i++){
ctx.fillRect(enemies[i].x,enemies[i].y,30,100);
if(player.x+player.width>enemies[i].x && player.x<enemies[i].x+30 && player.y+player.height>enemies[i].y && player.y<enemies[i].y+100){
document.location.reload();
}
}
for (var b=0;b<bullets.length;b++){
ctx.beginPath();
ctx.arc(bullets[b].x,bullets[b].y,2,0,Math.PI*2);
ctx.fill();
bullets[b].x += bullets[b].dx;
if(bullets[b].x>enemies[i].x && bullets[b].x<enemies[i].x+enemies[i].width && bullets[b].y>enemies[i].y && bullets[b].y<enemies[i].y+enemies[i].height){
enemies.splice(i,1);
}
}
So, I know that the problem is that it can't read the property "x" of enemies[i] because I didn't put it in the enemies for loop, but if i put it there then it can't read the property "x" of bullets[b]. I've been stuck on this for two days now and searched everything I could find, but didn't find anything useful at all. I would appreciate any help...
Thanks in advance!

What you want is to check all the ennemies, for each bullet.
This is done using nested loops:
for (var b=0;b<bullets.length;b++){
ctx.beginPath();
ctx.arc(bullets[b].x,bullets[b].y,2,0,Math.PI*2);
ctx.fill();
bullets[b].x += bullets[b].dx;
for (var j=ennemies.length; j-- >0;) {
if(bullets[b].x>enemies[j].x && bullets[b].x<enemies[j].x+enemies[j].width && bullets[b].y>enemies[j].y && bullets[b].y<enemies[j].y+enemies[j].height){
enemies.splice(j,1);
}
}
}
Note: In this example I loop over enemies in reverse order in order to avoid missing an ennemy when splicing.

Related

Logic: Prevent infinite loop when using portals

In a game that I am currently working on, there are portals, which are linked in pairs of two. Whenever the player enters a portal, it should be teleported to the other portal that is linked to the portal that they just entered. The problem is, that once it is teleported over, the other portal see's that the player is collding with it, and will teleport it back to the first, which will send it back and so on. The code for this porject is large and over many files, but here is the most important:
(Javascript, ignore the frame and pause vaibles, those are for animation)
export class Portal extends gameObject{
constructor(x, y, size, id){
super(x, y, size);
this.currentFrame = 0;//updated when (below) > (2 below)
this.countingFrame =0;//update every time;
this.pause = 3;//frames between frames
this.id = id;
this.justVisited = false;
}
update(player, portals){
if(this.countingFrame >= this.pause){
this.currentFrame = (this.currentFrame + 1) % 4;
this.countingFrame = 0;
}else{
this.countingFrame ++;
}
if(super.checkPlayerCollision(player)){
this.justVisited = true;
for(let i in portals){
if(this.id === portals[i].id && portals[i] !== this && !portals[i].justVisited){
player.x = portals[i].x;
player.y = portals[i].y;
}
}
}else{
for(let i in portals){
if(this.id === portals[i].id && portals[i] !== this && portals[i].justVisited){
this.justVisited = false;
}
}
}
}
render(canvas, spritesheet){
super.render(canvas, spritesheet, this.currentFrame , 26);
}
}
This is one attempt at patching it up, but it still failed. How can I make it so that the player goes throught the first one as soon as it collides, comes out the second, and won't retrun to the first untill the player moves off and then back on?
EDIT:After a little bit of seaching, the answer that was most often given to this question was "Move the player outside the reach of the second portal when it teleports over there". This will not work in my case, because when the player updates, his position changes with respect to the amount of time seince the last frame. In a perfet world, that would be ok, but because it is not perfect, the player cannot reliably be on a single point. Also, it would look weird if I moved it out of the hitbox entirely, so that doesn't work either.

Collision detection is not returning inside limits

Full code here
I am trying to setup the functions to detect collisions and for now just log to the console. This is the section for checkCollision function;
Player.prototype.update = function(dt) {
checkCollision(this.leftLimit, this.rightLimit);
this.leftLimit = this.x - 40.5;
this.rightLimit = this.x + 40.5;
}
function checkCollision(playerl,playerr) {
for (var i = 0; i < 5; i++) {
var thisEnemy = allEnemies[i];
if (thisEnemy.leftlimit > playerl && thisEnemy.rightLimit < playerr) {console.log("1")}
else {console.log('else')}
}
}
Question
The character is never registering as colliding with the enemy, why is this not working?
Testing/Debugging
I know this function is working as consoles logging else, I've also put logging in other locations and when in the Enemy.prototype.update function, console was showing values like 202.000000093, since the for..else function is using < or >, not absolute values, that should be fine, but still nothing is matching inside the player left and right limits. I also tried changing the Enemy limits to be smaller, +/- 40.5, incase the enemy was too wide to fit inside the player limits.
player.leftLimit and player.rightLimit are undefined when checkCollision method is first running
I added a better if statement to check if there's a collision;
if (
thisEnemy.leftLimit < player.rightLimit &&
thisEnemy.rightLimit > player.leftLimit &&
thisEnemy.upperLimit > player.lowerLimit &&
thisEnemy.lowerLimit < player.upperLimit) {
console.log("collision");
}

Collision detection simple snake game

Together with a friend of mine we are creating a multiplayer snake game. We are both beginners with JavaScript, so it is a real challenge for us.
So far I've managed to create this:
http://jsfiddle.net/tbmluijten/RG76t/3/
This is the collision detection code I have so far:
Snake.prototype.collision = function (x, y, array) {
for(var i = 0; i < Snake.length; i++){
if(Snake.pieces[0].x == x && Snake.pieces[0].y == y)
return true;
}
return false;
};
The problem I have is the collision with the snake itself. I can't figure out what I am doing wrong. Note that I am looking for collision with the snake itself not with the borders since we are going to put a loop into that. :-)
The short answer is - you are not checking for collision at all!
The working collision: http://jsfiddle.net/RG76t/10/
Explanation:
At first you need to put the collision method in the game loop function.
// line 32
if (game.snakes.length !== 0) {
for (i = 0; i < game.snakes.length; i++) {
var s = game.snakes[i];
s.paint(ctx, game);
// Check for collision.
if (s.collision()) {
// Do something, if the collision happens.
alert('collision');
}
}
}
Then in the collision method check if the first piece collides with any other. The loop starts from the 4th piece, since the snake's head can't really touch it's "neck" (2nd and 3rd pieces).
Snake.prototype.collision = function () {
// Loop the snake pieces from the 4th one.
for(var i = 3; i < this.length; i++){
// Check if this piece collides with the first piece.
if(
this.pieces[0].x === this.pieces[i].x &&
this.pieces[0].y === this.pieces[i].y
) {
return true; // collision
}
}
return false;
};
Also notice that Snake.length and Snake.pieces[i] are changed to this.length and this.pieces[i]. The keyword this refers to the instance of a Snake on which you invoke the collision method. When you were using Snake in this piece of code, you were checking the properties of a constructor.

Javascript Objects in array selection

Hello stackoverflowians~!
It is I, a lonesome programmer who has encountered a problem during my trails.
You see the problem is with this piece of code.
for(var a = 0; a < bullets.length; a++) {
for(var b = 0; b < pigs.length; b++) {
if(bullets[a].y < 300) {
if(bullets[a].x > pigs[b].x && bullets[a].x < pigs[b].x + pigImage.width &&
bullets[a].y > pigs[b].y && bullets[a].y < pigs[b].y + pigImage.height) {
pigExplode(pigs[b].x);
bullets.pop(a);
pigs.pop(b);
player.kills++;
}
}
}
}
The problem is as following.
I have 2 arrays with objects inside of them;
one array Bullets holding all bullet objects
and one array Pigs which hold all the pigs (Targets to shoot in my game)
(However, I do not encourage shooting pigs in any way)
Now what I'm trying to do is see if one of the bullets in the array hits one of the pigs in the array, i've added the pigs and bullets into the arrays like this:
bullets.push(new Bullet());
pigs.push(new Pig());
Where shit goes south is when I try to remove a certain object in this array, lets say I have 5 pigs.
that would be 0, 1, 2, 3, 4.
If I were to shoot pig 2. 4 will die.
If I were to shoot pig 1. 4 will die.
If I were to shoot pig 4. 4 will die.
So no matter who I shoot it will always remove the last pig.
the error I get with this problem is this:
Uncaught TypeError: Cannot read property 'y' of undefined
The line it indicates is this:
if(bullets[a].y < 300) {
this is in the double for loop where I check for any bullets hitting the pig.
the error however only pops up when I hit a pig that is not the last in the array.
Does anyone have any idea what's going on with my code?
I've been dealing with this for several days now and I have no idea what I'm doing wrong.
Thanks in advance!
There are two problems with the code:
You are using pop to remove items from the arrays, that will always remove the last item. That's why it's always killing the last pig.
You are continuing the inner loop after a hit, so you will be checking hits for a bullet that's not in the array any more. If you were checking the last bullet, the variable a is now pointing beyond the last item in the array.
Use splice to remove items in an array, loop backwards through the bullets so that you can remove one without messing up the loop, and end the inner loop after a hit:
for (var a = bullets.length - 1; a >= 0; a--) {
for (var b = 0; b < pigs.length; b++) {
if (bullets[a].y < 300) {
if (bullets[a].x > pigs[b].x && bullets[a].x < pigs[b].x + pigImage.width &&
bullets[a].y > pigs[b].y && bullets[a].y < pigs[b].y + pigImage.height) {
pigExplode(pigs[b].x);
bullets.splice(a, 1);
pigs.splice(b, 1);
player.kills++;
break; // end the inner loop
}
}
}
}
This will remore the pig from your pigs array if it's hit
if(bullets[a].x > pigs[b].x && a bunch of other stuff) {
pigExplode(pigs[b].x);
bullets.splice(a,1);//remove bullit at a
pigs.splice(b,1);//remove pig at b
player.kills++;//smell bacon, jummy
//always forget this both bullits and pigs are one shorter
// if you dont decrease the counters you'll skip one pig and bullit
a--;
b--;
}
.pop always removes the last item of the array.

life decrease on collision

I am making a little game using HTML5 Canvas and javascript. I am so far that I have a kite moving some sort of power up on collision and an obstacle on collision.
Now I'm at the point I want to add lives and when you hit an obstacle your life will decrease 1.
I tried some stuff and when you hit an obstacle the life decreases but it decreases constantly and the player image gets removed instead of the obstacle image.
here is the life thing you can check all the code there.
http://nickzijlstra.com/kite
Here the code I think is the most important for the problem.
function hitObject(player, obj){
var a = (obj.x - player.x),
b = (obj.y - player.y),
c = Math.sqrt(a*a + b*b),
r0 = player.image.width/2,
r1 = obj.image.width/2;
if (c < r0+r1) {
player.drawable = false;
lifes -=1;
window.location.reload(true);
}
}
If someone sees the problem or knows the solution I would really appreciate it!
The reason the player disappears is because of this line in the hitObject function:
player.drawable = false;
This will cause the player to not be drawn because of this condition in your drawing function:
if (player.drawable == true) {
context.drawImage(player.image, player.x, player.y, player.image.width, player.image.height);
}
I presume you actually want to move the obj back to a random spot on the top of the screen if the player gets hit. It doesn't do this at the moment, which is why the lives go down rapidly: the object hits the player, it removes a life, and then the next frame it hits the player again (even though the player isn't visible).
What you might want is something like:
...
if (c < r0+r1) {
lifes -=1;
// Respawn the object.
obj.y = -50;
obj.x = Math.random() * canvas.width;
...
At a guess, I'd say that you should replace the
player.drawable = false;
with
obj.drawable = false;
and wrap the whole collision detection inside of an if obj.drawable=true so that removed obstacles won't collide with the kite.

Categories