简体   繁体   中英

Box2d Collision Detection with Arrays

I'm developing in AndEngine I have nearly completed my game, but unfortunately, it suffers from a low fps occasionally due to the fact that I am checking .collideswith a lot in my update loop. I now understand that this is the problem, and I have been trying to change it using Box2d with bodies and such as in theory, this is exactly what I need, but I can't get a grasp around it!

Basically, I have 4 arrays; one for cars, three for enemies. Cars drive from left to right, and if they make contact with any of these enemies, it's speed changes depending. Do I have to allocate a body to each one of cars and enemies when I am loading their arrays? And then how do I check? do I run a for loop, and then an 'isBodyContacted(carBody, iceBergBody);' in the update look? It's a bit cofusing!

For reference, loading my car:

private void loadCar() {
            for (int i = 0; i < rManager.getInstance().carArray.length; i++) {
                    rManager.getInstance().carArray[i] = new Car(new Sprite(
                                    rManager.getInstance().spawnPoint[i].getSpawnPos().x,
                                    rManager.getInstance().spawnPoint[i].getSpawnPos().y,
                                    rManager.getInstance().car_region,
                                    engine.getVertexBufferObjectManager()) {
                            @Override
                            public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
                                            final float pTouchAreaLocalX,
                                            final float pTouchAreaLocalY) {

                                    if (pSceneTouchEvent.isActionMove()
                                                    && GameManager.getInstance().getDebugMode() == true) {
                                            this.setPosition(pSceneTouchEvent.getX(),
                                                            pSceneTouchEvent.getY());
                                    }
                                    return true;
                            }
                    });
            }

            for (int i = 0; i < rManager.getInstance().carArray.length; i++) {
                    rManager.getInstance().carArray[i].getCarSprite().setScale(0.5f);
                    rManager.getInstance().carArray[i].getCarSprite().setAnchorCenter(
                                    0, 0);
                    colourX = (randNumber(2, 9));
                    colourY = (randNumber(2, 9));
                    colourZ = (randNumber(2, 9));
                    colourX /= 10;
                    colourY /= 10;
                    colourZ /= 10;
                    rManager.getInstance().carArray[i].getCarSprite().setColor(colourZ,
                                    colourY, colourZ);
                    attachChild(rManager.getInstance().carArray[i].getCarSprite());
                    this.registerTouchArea(rManager.getInstance().carArray[i]
                                    .getCarSprite());
                    this.setTouchAreaBindingOnActionDownEnabled(true);
            }
    }

Loading an enemy..

void loadIceBerg() {
            for (int i = 0; i < rManager.getInstance().iceBergArray.length; i++) {
                    rManager.getInstance().iceBergArray[i] = new IceBergEnemy(
                                    new Sprite(randNumber(200, 700), randNumber(0, 480),
                                                    rManager.getInstance().iceBerg_region,
                                                    engine.getVertexBufferObjectManager()) {
                                            @Override
                                            public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
                                                    this.setPosition(pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
                                                    if (this.getY() > rManager.getInstance().camera.getHeight() - (this.getHeight() / 2) || this.getY() < 0 + (this.getHeight() / 2))
                                                    {
                                                            this.setPosition(200 - (pDifficultyLevel * 20),
                                                                            -100);
                                                                                                                            showScore(50, " ice berg!");
                                                            this.setVisible(false);

                                                    }      

                                                    if(pSceneTouchEvent.isActionUp())
                                                    {
                                                            updateScore(50);
                                                            GameManager.getInstance().updateTotalIceBergEnemiesKilled();

                                                    }



                                                    return true;
                                            }
                                    });

                    rManager.getInstance().iceBergArray[i].getIceBergSprite()
                                    .setPosition(
                                                    rManager.getInstance().iceBergArray[i]
                                                                    .getIceBergSprite().getX(),
                                                    rManager.getInstance().iceBergArray[i]
                                                                    .getIceBergSprite().getY());
                    rManager.getInstance().iceBergArray[i].getIceBergSprite().setScale(
                                    0.8f);
                    this.registerTouchArea(rManager.getInstance().iceBergArray[i]
                                    .getIceBergSprite());
                    this.setTouchAreaBindingOnActionDownEnabled(true);

                    attachChild(rManager.getInstance().iceBergArray[i]
                                    .getIceBergSprite());
            }
    }

Some collision!

else if (rManager.getInstance().iceBergArray[2]
                                                    .getIceBergSprite().collidesWith(
                                                                    rManager.getInstance().carArray[r]
                                                                                    .getCarSprite())) {
                                            rManager.getInstance().carArray[r].setCarSpeed(0f);
                                    }

                                    else if (rManager.getInstance().iceBergArray[3]
                                                    .getIceBergSprite().collidesWith(
                                                                    rManager.getInstance().carArray[r]
                                                                                    .getCarSprite())) {
                                            rManager.getInstance().carArray[r].setCarSpeed(0f);
                                    }

                                    else if (rManager.getInstance().iceBergArray[4]
                                                    .getIceBergSprite().collidesWith(
                                                                    rManager.getInstance().carArray[r]
                                                                                    .getCarSprite())) {
                                            rManager.getInstance().carArray[r].setCarSpeed(0f);
                                    }

                                    else if (rManager.getInstance().iceBergArray[5]
                                                    .getIceBergSprite().collidesWith(
                                                                    rManager.getInstance().carArray[r]
                                                                                    .getCarSprite())) {
                                            rManager.getInstance().carArray[r].setCarSpeed(0f);
                                    }

I have found many tutorials, but none seem to reference an array of objects, and that is exactly what I need. If someone could help me or provide some sort of quick tutorial, then that would be greatly appreciated. Thanks!!

You should not use any loops to check each possible combination of collision. Instead, you should register a listener for the whole World and set user data on your bodies (eg type = "car", "enemy"). Then in the listener, you just check which two objects collided. Check out this example:

http://www.andengine.org/forums/gles2/collision-events-t7140.html#p31300

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM