1

I am new to JavaScript and HTML and am working on a small game.

I have four 'enemies' whose position on the canvas is determined by the values in the arrays 'enemyX' and 'enemyY'.

Very simply, I want to detect if the enemies have 'collided', i.e have moved within 30px of each other (the enemy image is 30px by 30px).

What I want to do is subtract the value of the i th value in the array with the other values in the same array and see if this value is less than 30. The less than 30 part is an if statement, so how do I go about subtracting all the values from each other without many lines of code?

Here's what I have tried based on the answers below:

    var count = 0;
var innercount = 0;

while (count <= 3) {

    while (innercount<=3) {
        collisionDetect(count, innercount, enemyX[count], enemyY[count], enemyX[innercount], enemyY[innercount])
        innercount++
    }
    count++    
}

var i = 0;
while (i < enemyX.length) {

    if (collisionX[i] == 1) {
        directionX  = directionX*-1;
    }

    if (collisionY[i] == 1) {
        direction = directionY*-1;
    }
}


}



}

function   collisionDetect(count, innercount, x, y, xX, yY ) {


if ((Math.abs(x-xX)) <=30) {
    collisionX[count] = 1
    collisionX[innercount] = 1
}

if ((Math.abs(y - yY)) <=30) {
    collisionY[count] = 1
    collisionY[innercount] = 1
}

return collisionX, collisionY;
}

This code gives me a blank canvas.

4
  • Consider clarify your question. Add some pieces of code may help us to properly answer your question. Commented May 17, 2013 at 4:19
  • are enemyX and enemyY positioned in the center of the enemy object? Commented May 17, 2013 at 4:26
  • you can use jsfiddle to easily share your code. Commented May 17, 2013 at 4:36
  • Sorry. Question edited :) Commented May 18, 2013 at 5:54

4 Answers 4

1

Detection of an intersection between two objects (assuming rectangular shape) and the position defines the center of the object.

function getRect(x, y, w, h)
{
    var left = x - Math.floor(w / 2),
    top = y - Math.floor(h / 2);

    return {
        left: left,
        top: top,
        right: left + w,
        bottom: top + h
    };
}

function intersects(A, B)
{
    return A.right >= B.left && 
       A.left <= B.right && 
       A.bottom >= B.top && 
       A.top <= B.bottom;
}

alert(intersects(getRect(12, 56, 30, 30), getRect(30, 40, 30, 30))); // true

The getRect() function can be modified to accommodate for a different anchor position, e.g. top left.

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

2 Comments

Sorry I'm quite new. What do you mean by left:left, top:top, etc.?
Those are part of an object declaration in JavaScript, the property name is followed by a colon and the value.
1

You could use a function:

function colliding(x1, y1, x2, y2){
  return Math.abs(x1-x2) <= 30 && Math.abs(y1-y2) <= 30;
}

then use the function to test the different combination of enemies: (1,2), (1,3), (1,4), (2,3), (2,4), and (3,4).

So, for example, you would use: colliding(enemyX[2], enemyY[2], enemyX[3], enemyY[3]) to check if enemy 2 and 3 are colliding. Do that with all the combinations above.

EDIT: to make it more readable, you could define an additional function:

function enemiesColliding(e1, e2){
  return colliding(enemyX[e1], enemyY[e1], enemyX[e2], enemyY[e2])
}

and then use it:

enemiesColliding(1,2) || enemiesColliding(1,3) || enemiesColliding(1,4) ||
enemiesColliding(2,3) || enemiesColliding(2,4) || enemiesColliding(3,4)

3 Comments

This doesn't take the corners into consideration, e.g. left top of A collides with right bottom of B.
@Jack: true; chanegd the check to <= instead of <. Thanks.
Thanks for the answer. I was thinking of something similar to this, but I actually wanted something that used loops to minimize the amount of code i have to write. I think I can combine this with john B's loop within loop idea below.
1

I am going to restate my understanding of you question, just so there is no confusion. You have two arrays in paralleled , one for x cords, and one for y cords. Each ship has a element in both arrays.

So, for example, ship 12 could be found at xPos[12] and yPos[12], where xPos and yPos are the arrays from above.

It also stands to reason that this a communicative. If ship[a] collides with ship[b] then ship[b] has collided with ship[a]. And I think that hold for 3 + ships.

I would start by writing a distance function.

 dist(x1,y1,x2,y2)
 {
     return Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
 }

Then I would write code run through the arrays. Every element must be compared to every other element, one time.

 var counter = 0;
 var indexOfShipThatHaveCollided = [];
 while(counter < Xpos.length)
 {
      var innerCounter = counter;           
      while(innerCounter < Xpos.length)
      {
            t = dist(Xpos[counter],Ypos[counter],Xpos[innerCounter],Ypos[innerCounter])
            if(t < 30)
            {
                 indexOfShipThatHaveCollided.push(counter)
                 indexOfShipThatHaveCollided.push(innerCounter)

            }
      }

 }

The code above compares every ship to every other ship ONCE. It will compare ship[1] to ship[8], but it will not compare ship[8] to ship[1].

I did not test ANY of this code, but I hope it moves you in the right direction. If you have anymore question just give me a comment.

5 Comments

It seems this code will also compare enemy[1] to enemy[1] once, giving a value of 0. Any workaround for that?
@user2392394: yes, use var innerCounter = counter + 1.
@Eduardo: Thanks, but then if counter = 2, then innercounter will only take the value 3. I also want innercounter to be 1, so that all the values are compared.
@JohnDoe: you don't need that. You will have already compared 1 and 2 when counter == 1 and innerCounter == 2.
You are correct. sorry about that bug, and thank you for correcting it. I will not update the code. I will leave the bug so others might learn from my error.
0

According my understanding of your question below is my solution:

I think you need to find distance between two points. by using distance you can apply your logic. To find distance following is the formula:

Given the two points (x1, y1) and (x2, y2), the distance between these points is given by the formula:

enter image description here

1 Comment

Thanks. I think I wasn't able to clarify this in the question. My main problem is not finding the distance between the objects. I want to find a way to compare each object to every other object.

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.