【问题标题】:AndEngine how to remove bullets and shoot one bullets at a time?AndEngine如何去除子弹并一次发射一颗子弹?
【发布时间】:2011-08-24 22:15:18
【问题描述】:

我正在使用 Android 版 Andengine,我创建了一个代码,当我触摸屏幕时,我的播放器会发射子弹。

现在我想做两件事

首先:我希望子弹与敌人相撞时被移除 第二:我希望一次只能发射子弹。所以只要子弹没有击中敌人我不想调用发射子弹的方法。

这是我创建的代码 我把所有不重要的代码都最小化了

public class ShooterActivity extends BaseGameActivity implements IOnSceneTouchListener,IAccelerometerListener{

//Variables
private static final int CAMERA_WIDTH = 720;
private static final int CAMERA_HEIGHT = 480;
private Camera mCamera;
private BitmapTextureAtlas mBitmapTextureAtlas;
private TiledTextureRegion mTiledTextureRegion;
private TextureRegion mBulletTextureRegion;
private AnimatedSprite facebox;
private AnimatedSprite enemy;
private Sprite bulletsprite;
private Scene mScene;
private PhysicsWorld mPhysicsWorld;
private Shape ground, roof, right, left;
private Body body, bulletbody, enemybody;
private FixtureDef mFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
private TiledTextureRegion enemyTiled;
private boolean pFlippedHorizontal = true;



@Override
public Engine onLoadEngine() {
    // TODO Auto-generated method stub
    this.mCamera = new Camera(0,0,CAMERA_WIDTH,CAMERA_HEIGHT);
    return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH,CAMERA_HEIGHT),this.mCamera));
}

@Override
public void onLoadResources() {
    // TODO Auto-generated method stub
    this.mBitmapTextureAtlas = new BitmapTextureAtlas(1024,1024, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
    this.mTiledTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mBitmapTextureAtlas, this, "gfx/player.png", 0, 0, 8, 1);
    this.enemyTiled = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mBitmapTextureAtlas, this, "gfx/enemy.png", 200, 500, 8, 1);
    this.mBulletTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mBitmapTextureAtlas, this, "gfx/badge.png", 200, 200);
    this.mEngine.getTextureManager().loadTexture(mBitmapTextureAtlas);
}

@Override
public Scene onLoadScene() {
    // TODO Auto-generated method stub
    this.mEngine.registerUpdateHandler(new FPSLogger());
    mScene = new Scene();
    mScene.setBackground(new ColorBackground(0,0,0));
    this.mPhysicsWorld = new PhysicsWorld(new Vector2(0,SensorManager.GRAVITY_EARTH), false);
    //Walls
    final FixtureDef wallFixture = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
    roof = new Rectangle(0, 0, CAMERA_WIDTH, 2);
    ground = new Rectangle(0,CAMERA_HEIGHT ,CAMERA_WIDTH,2);
    left = new Rectangle(0,0,2,CAMERA_HEIGHT);
    right = new Rectangle(CAMERA_WIDTH -2, 0,2,CAMERA_HEIGHT);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixture);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixture);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixture);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixture);
    this.mScene.attachChild(roof);
    this.mScene.attachChild(ground);
    this.mScene.attachChild(left);
    this.mScene.attachChild(right);
    //facebox
    facebox = new AnimatedSprite(150,150, this.mTiledTextureRegion);
    facebox.setScale(.75f);
    facebox.animate(200);
    body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, facebox, BodyType.DynamicBody, mFixtureDef);
    this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(facebox,body,true,false));
    this.mScene.attachChild(facebox);
    //enemy
    enemy = new AnimatedSprite(500,150,this.enemyTiled);
    enemy.animate(200);
    enemy.setScale(.75f);
    enemy.setFlippedHorizontal(pFlippedHorizontal);
    this.mScene.attachChild(enemy);
    enemybody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, enemy, BodyType.DynamicBody, mFixtureDef);
    this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(enemy,enemybody,true,false));
    //scene
    this.mScene.setOnSceneTouchListener(this);
    this.mScene.registerUpdateHandler(mPhysicsWorld);
    return mScene;

}

@Override
public void onLoadComplete() {
    // TODO Auto-generated method stub

}

//touch the screen to create bullets
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
    // TODO Auto-generated method stub
    if(pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN){
        runOnUpdateThread(new Runnable(){

            @Override
            public void run() {
                // TODO Auto-generated method stub
            fire();
            }

        });

        //here I want to be able to remove the bullets when it hits the enemy but not sure what method to use
        this.mScene.registerUpdateHandler(new IUpdateHandler(){

            @Override
            public void onUpdate(float pSecondsElapsed) {
                // TODO Auto-generated method stub
                if(bulletsprite.collidesWith(enemy)){
                }   
            }
            @Override
            public void reset() {
                // TODO Auto-generated method stub
            }
        });
    }
    return false;
}
//method to create bullets
public void fire(){
    bulletsprite = new Sprite(this.facebox.getX() + 15, this.facebox.getY() -5, this.mBulletTextureRegion);
    bulletsprite.setScale(.5f);
    bulletbody = PhysicsFactory.createCircleBody(this.mPhysicsWorld, bulletsprite, BodyType.DynamicBody, mFixtureDef);
    this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(bulletsprite, bulletbody, true, true));
    final Vector2 speed = Vector2Pool.obtain(50, 0);
    bulletbody.setLinearVelocity(speed);
    Vector2Pool.recycle(speed);
    this.mScene.attachChild(bulletsprite);
}

//nothing here just accelerometer
@Override
public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
    // TODO Auto-generated method stub
    final Vector2 gravity = Vector2Pool.obtain(pAccelerometerData.getX() *3, 10);
    this.mPhysicsWorld.setGravity(gravity);
    Vector2Pool.recycle(gravity);
}
@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    this.enableAccelerometerSensor(this);
}
@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    this.disableAccelerometerSensor();
}   

}

【问题讨论】:

  • 我已经提供了一个答案,可以帮助你到达某个地方,但 Dan 有一点 - 你的问题的答案是“实现碰撞检测”,这不是可以简洁解释的东西 - 因此它是除非您的问题更狭窄、更集中,否则您不太可能得到代码示例作为答案。
  • 我是否知道要提供更多信息或我是如何提出问题的?

标签: java android andengine


【解决方案1】:

首先,google 碰撞检测 - 这将帮助您解决第一个问题。

其次,只保留一个子弹对象的实例,当它(a)与敌人或其他物体碰撞,或(b)离开屏幕时,你就可以让子弹再次被射击。

【讨论】:

  • 我知道碰撞检测。如果您查看了我的代码,我会在其中找到它,并且还有关于它的评论。我不知道的是当碰撞发生时我将如何移除子弹。我只知道 2 种删除精灵的方法。 detachChild() 和 detachSelf();
  • 你可以在它上面设置一个布尔值,叫做inFlight,当true表示子弹在飞行中,并且还没有与任何东西相撞时。当它确实与某物发生碰撞时,计算伤害,并将inFlight 设置为 false。这表明子弹 (a) 不应渲染到屏幕上,并且 (b) 它已准备好再次发射。您还需要重置它的位置,并且在inFlight 为假时根本不让它移动。点击屏幕会将inFlight 更改为真,前提是它已经为假,并触发触发。
  • 感谢您。我解决了一次只能发射一颗子弹的问题,您知道如何完全清除子弹吗?将其可见设置为 false 并将其分离只会使其不可见。这就像我游戏中的玩家正在与一个看不见的物体发生碰撞。
  • 这完全取决于您 - 但您可以简单地将子弹设置为 null,或者在每次碰撞时重新初始化它,将其重置为某种默认状态。有几种不同的方法可以做到这一点,但基本上将碰撞视为一个事件,visible 属性应该用作程序其余部分重置子弹的信号。你如何做到这一点,取决于你的具体实施方式。我希望这会有所帮助。
猜你喜欢
  • 2022-12-31
  • 1970-01-01
  • 2023-03-30
  • 2023-03-15
  • 2018-04-30
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
相关资源
最近更新 更多