0

I'm making a very basic space invaders game, but having some trouble with the collisionDetection. enemy are the ones I need to hit, they are inside "fiende". "missile" is the div for the missiles.

I haven't tried much, since I'm very new to js, hence I don't have enough knowledge to improve on it.

EDIT: After some testing, I've found out that the collisionDetection breaks when the animations is running.

function collisionDetection() {
    for (var enemy = 0; enemy < fiende.length; enemy++) {
        for (var missile = 0; missile < missiles.length; missile++) {
            if (
                missiles[missile].left >= fiende[enemy].left &&
                missiles[missile].left <= (fiende[enemy].left + 50) &&
                missiles[missile].top <= (fiende[enemy].top + 50) &&
                missiles[missile].top >= fiende[enemy].top
            ) {
                fiende.splice(enemy, 1);
                missiles.splice(missile, 1);
            }
        }
    }
}

HTML

<div id="background">
    <div id="missiles"></div>
    <div id="fiende"></div>
</div>

CSS

div.missile1 {
    width: 10px;
    height: 28px;
    background-image: url('missile1.png');
    position: absolute;
}

div.enemy {
    width: 50px;
    height: 50px;
    background-image: url('enemy.png');
    position: absolute;
}

Some of the animation, it's basically the same after that.

@keyframes bevegelse {
0% {
    left: -230px;
    top: 0%;
}
5% {
    left: 250px;
    top: 0%;
}
10% {
    left: 250px;
    top: 40px;
}
15% {
    left: -230px;
    top: 40px;
}

When a missile hits the enemy, it destroys some other enemies, which the missile didn't hit. Sometimes it doesn't even destroy the randoms ones.

9
  • HTMLDivElement doesn't have a length property Commented Feb 19, 2019 at 9:21
  • @nickzoum Could you explain a bit more about that? Commented Feb 19, 2019 at 9:22
  • 1
    you need to declare your friende and missiles variables or pass them as arguments to function collisionDetection Commented Feb 19, 2019 at 9:24
  • @molamk So how and where do I do that? Commented Feb 19, 2019 at 9:27
  • @Ben You said "fiende" and "missile" are div(s) in html.. Then you are doing fiende.length. The JavaScript object for div doesn't have a length property. Commented Feb 19, 2019 at 9:27

1 Answer 1

1

You have a problem in your loop. You are stepping through the indices into the array, but also modifying the array as you go, so you may get confusing results. This may or may not be the cause of your other issues (clearly this is not all of your code) however fixing this may help.

There are a number of ways to fix this. My usual method is to count backwards through the array so that removing elements does not impact the locations of indices the loop is yet to visit.

function collisionDetection() {
    //because this loop is continued once the array is modified, count from the end
    for (var enemy = fiende.length-1; enemy >=0 ; enemy--) {
        //this loop exits when a clash is found, so count as normal
        for (var missile = 0; missile < missiles.length; missile++) {
            if (
                missiles[missile].left >= fiende[enemy].left &&
                missiles[missile].left <= (fiende[enemy].left + 50) &&
                missiles[missile].top <= (fiende[enemy].top + 50) &&
                missiles[missile].top >= fiende[enemy].top
            ) {
                fiende.splice(enemy, 1);
                missiles.splice(missile, 1);
                //the enemy has already been hit, exit and dont consider other missiles
                break;
            }
        }
    }
}

I've made the assumption here that it is one missile gone per enemy. If you want more than one missile to be destroyed, then remove the break and also count backwards in the inner loop.


Thank you for supplying a reference to your git code (see the comments below).

The above is an error in the code, however not one which is typically causing any problem. The issue seems to be that when the enemies are animated the bullets don't hit them. The problem here is that you are detecting collisions with your js code's view of the enemy location, but you are enhancing the animation with css animation. If you wish to detect the collisions then you need to animate entirely in JS.

Try removing the css animation to verify you can hit the enemies. Then if that works you need to do all the movement in js.

Sign up to request clarification or add additional context in comments.

21 Comments

Yes, you're correct. It's one missile per enemy. Could you elaborate on how I can fix it, since I'm very new to js, so I need a bit more guidance.
See the code I posted above. This fixes a bug in your code. Note that this is not a js-specific issue but the more general problem of modifying an array while looping through it.
This may not sort exactly the bug you are seeing. There is not really enough of your code to know for sure.
What more of the code do you need to help me find what is causing the trouble?
Try changing the loop to the code in my answer. If that does not help then the minimum is usually enough code to actually have something that runs (e.g. on jsfiddle or similar) and demonstrates your problem.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.