Libgdx碰撞检测来自一个物体上的两个来源[数组越界激发-1]

时间:2014-09-03 21:45:42

标签: android arrays libgdx

为了论证和简单,这里的代码有一个矩形精灵/纹理向上射击(因为它是一把枪)。并且敌人的矩形/精灵/纹理向下生成。然后玩家检测它是否击中了敌人。当玩家击中敌人时,我会获得越界异常-1

package com.TheGame.Pack;

import java.util.Iterator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;

public class GameScreen implements Screen {
final MasterClass game;

Texture FleetTexture;
Texture PlayerTexture;
Texture ShootingTexture;





OrthographicCamera camera;

Rectangle Player;


Array<Rectangle> Emma;
Array<Rectangle> Shooting;

long EmmaSpawnTime;
long ShootingTime;
public static int EmmaKilled = 0;

public GameScreen(final MasterClass gam) {
    this.game = gam;

    // load the images for the droplet and the Player, 64x64 pixels each
    FleetTexture = new Texture(Gdx.files.internal("cirA.png")); //Enemies
    PlayerTexture = new Texture(Gdx.files.internal("BoxA.png"));
    ShootingTexture = new Texture(Gdx.files.internal("gun.png"));


    // load the drop sound effect and the rain background "music"
//  dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
//  rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
//  rainMusic.setLooping(true);

    // create the camera and the SpriteBatch
    camera = new OrthographicCamera();
    camera.setToOrtho(false, 800, 480);

    // create a Rectangle to logically represent the Player
    Player = new Rectangle();
    Player.x = 800 / 2 - 64 / 2; // center the Player horizontally
    Player.y = 20; // bottom left corner of the Player is 20 pixels above
    // the bottom screen edge
    Player.width = 40;
    Player.height = 30;

    // create the Emma array and spawn the first EmmaInArray
    Emma = new Array<Rectangle>();
    Shooting = new Array<Rectangle>();
    spawnEmma();

}

private void spawnEmma() {
    Rectangle EmmaInArray = new Rectangle();
    EmmaInArray.x = MathUtils.random(0, 800 - 64);
    EmmaInArray.y = 480;
    EmmaInArray.width = 40;
    EmmaInArray.height = 30;
    Emma.add(EmmaInArray);
    EmmaSpawnTime = TimeUtils.nanoTime();
}

private void spawnShooting(){
    Rectangle ShootingInArray = new Rectangle();
    ShootingInArray.x = Player.x;
    ShootingInArray.y = Player.y;
    ShootingInArray.width = 40;
    ShootingInArray.height = 30;
    Shooting.add(ShootingInArray);
    ShootingTime = TimeUtils.nanoTime();


} 

@Override
public void render(float delta) {
    // clear the screen with a dark blue color. The
    // arguments to glClearColor are the red, green
    // blue and alpha component in the range [0,1]
    // of the color to be used to clear the screen.
    Gdx.gl.glClearColor(0, 0, 0.2f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

     // tell the camera to update its matrices.
     camera.update();

    // tell the SpriteBatch to render in the
    // coordinate system specified by the camera.
    game.batch.setProjectionMatrix(camera.combined);

    // begin a new batch and draw the Player and
    // all drops
    game.batch.begin();
    game.font.draw(game.batch, "Drops Collected: " + EmmaKilled, 0, 480);
    game.batch.draw(PlayerTexture, Player.x, Player.y, Gdx.graphics.getWidth() / 20,

     Gdx.graphics.getHeight()/ 20);


    for (Rectangle EmmaInArray : Emma) {
        game.batch.draw(FleetTexture, EmmaInArray.x, EmmaInArray.y);
    }

    for(Rectangle ShootingInArray : Shooting){
        game.batch.draw(ShootingTexture, ShootingInArray.x, ShootingInArray.y);
        ShootingInArray.y +=10;
    }  


    game.batch.end();

    // process user input
    if (Gdx.input.isTouched()) {
        Vector3 touchPos = new Vector3();
        touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
        camera.unproject(touchPos);
        Player.x = touchPos.x - 64 / 2;
    }
    if (Gdx.input.isKeyPressed(Keys.LEFT))
        Player.x -= 400 * Gdx.graphics.getDeltaTime();
    if (Gdx.input.isKeyPressed(Keys.RIGHT))
        Player.x += 400 * Gdx.graphics.getDeltaTime();

    // make sure the Player stays within the screen bounds
    if (Player.x < 0)
        Player.x = 0;
    if (Player.x > 800 - 64)
        Player.x = 800 - 64;

    // check if we need to create a new EmmaInArray
    if (TimeUtils.nanoTime() - EmmaSpawnTime > 100000000){
        spawnEmma();
    }

    if(TimeUtils.nanoTime() - ShootingTime > 100000000){
        spawnShooting();
    } 
    // move the Emma, remove any that are beneath the bottom edge of
    // the screen or that hit the Player. In the later case we play back
    // a sound effect as well.
    Iterator<Rectangle> EmmaIterator = Emma.iterator();


    while (EmmaIterator.hasNext()) {
        Rectangle EmmaInArray = EmmaIterator.next();
        EmmaInArray.y -= 200 * Gdx.graphics.getDeltaTime();

        if (EmmaInArray.y + 64 < 0){
            EmmaIterator.remove();
        }


        Iterator<Rectangle> ShootingIterator = Shooting.iterator();
        while(ShootingIterator.hasNext()){

            Rectangle ShootingInArray = ShootingIterator.next();
        //  ShootingInArray.y += 200 * Gdx.graphics.getDeltaTime();

            if(ShootingInArray.y > 480){
                ShootingIterator.remove();
            }

            if(EmmaInArray.overlaps(ShootingInArray)){

                ShootingIterator.remove();
                EmmaIterator.remove();
            }   
            if (Player.overlaps(EmmaInArray)) {
                EmmaKilled++;
                game.setScreen(game.HS);
            //  dropSound.play();

如果我注释掉EmmaIterator.remove();它运行良好,没有注释它在撞击时崩溃。

为什么这次崩溃不是正确的方法呢?我是否需要以某种方式同时检测到命中?当显然屏幕上还有敌人时,阵列如何处于负1?

                EmmaIterator.remove();
            }
        } 

虽然这不是我设置的方式,但代码仍然可以运行而没有问题。我遇到了同样的问题,而不是检测到玩家的敌人碰撞,我有2支枪检查碰撞。这对我来说似乎是一个大问题,这就是为什么我说我做错了但文档很轻,所以我来到这里。

    }
}

@Override
public void resize(int width, int height) {
}

@Override
public void show() {
    // start the playback of the background music
    // when the screen is shown
    //rainMusic.play();
}

@Override
public void hide() {
}

@Override
public void pause() {
}

@Override
public void resume() {
}

@Override
public void dispose() {
    FleetTexture.dispose();
    PlayerTexture.dispose();
    ShootingTexture.dispose();
//  dropSound.dispose();
//  rainMusic.dispose();
}

}

2 个答案:

答案 0 :(得分:0)

除非使用多线程,否则不可能完全同时发生任何事情。您的代码中存在许多可能的拼写错误,但有一个会破坏它:

Rectangle var1_holder = iter.next();

对iter的相同引用是在应该使用它的第一个块和第二个块中,它应该使用iter1。您应该考虑使用匹配的变量名称,例如

Iterator<Rectangle> iter3 = var3.iterator();

如果您必须将数字作为唯一的区别特征。

答案 1 :(得分:0)

notostraca是对的。但是为了使它更清楚,我将向你展示一个用于碰撞的for循环的例子。它不会造成任何伤害,我希望它会让你更清楚

int v2 = var2.size();
for (int i = 0; i < v2; i++) {
    if (object.getBounds().overlaps(var2.get(i).getBounds())) {
        var2.remove(i);  
        v2--;
        //in this line u might use break; if u know that just one object 
        //from var2 array can hit at a time
    }
}