简体   繁体   中英

Libgdx: how to detect if an enemy was touched?

I want to add to the score of my game +1 when an enemy was touched, I tried two methods addListener and touchDown but not worked for me or I didn't use them right.

How can I do that my (enemy object is linked to an userData and Actor classes, I regroup many different sizes for my enemy in an enum class also those enemies move from the top of the screen to bot. How to detect if an enemy was touched?

public class GameStage extends Stage {
    // This will be our viewport measurements while working with the debug renderer
    private static final int VIEWPORT_WIDTH = 13;
    private static final int VIEWPORT_HEIGHT = 20;

    private World world;
    private Ground ground;
    private Enemy enemy;
    private final float TIME_STEP = 1 / 300f;
    private float accumulator = 0f;
    private Rectangle bounds;
    private Vector3 touchPoint = new Vector3();;
    private int score;
    private String yourScoreName;
    BitmapFont yourBitmapFontName;
    private SpriteBatch batch;
    private OrthographicCamera camera;
    private Box2DDebugRenderer renderer;

    public GameStage() {
        world = WorldUtils.createWorld();
        renderer = new Box2DDebugRenderer();
        Gdx.input.setInputProcessor(this);
        batch = new SpriteBatch();
        score = 0;
        yourScoreName = "score: 0";
        yourBitmapFontName = new BitmapFont();
        setUpWorld();
        setUpCamera();
    }

    public void setUpWorld(){
        world = WorldUtils.createWorld();
        setUpGround();
        createEnemy();
    }

    private void setUpGround(){
        ground = new Ground (WorldUtils.createGround(world));
        addActor(ground);
    }

    private void createEnemy() {
        enemy = new Enemy(WorldUtils.createEnemy(world));

     // (1) *****using addListener method
        enemy.addListener(new InputListener()
        {
            @Override
            public boolean touchDown(InputEvent event, float x, float y,
                                     int pointer, int button)
            {
                score++;
                yourScoreName = "score: " + score;
                return true;
            }
        });
        /*enemy.addListener(new ClickListener() {
            public void clicked() {
                world.destroyBody(enemy.getBody());
            }});*/
        //bounds = new Rectangle(enemy.getX(), enemy.getY(), enemy.getWidth(),  enemy.getHeight());
        addActor(enemy);

    }

    private void setUpCamera() {
        camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
        camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0f);
        camera.update();
    }

    @Override
    public void act(float delta) {
        super.act(delta);
        checkEnemy();

        // Fixed timestep
        accumulator += delta;

        while (accumulator >= delta) {
            world.step(TIME_STEP, 6, 2);
            accumulator -= TIME_STEP;
        }

        //TODO: Implement interpolation

    }

    private void checkEnemy(){
       final Body  body = enemy.getBody();
        UserData userData = enemy.getUserData();

       bounds = new Rectangle(enemy.getBody().getPosition().x, enemy.getBody().getPosition().y, enemy.getUserData().getWidth(),  enemy.getUserData().getHeight());
       // bounds = new Rectangle(body.getPosition().x, body.getPosition().y,userData.getWidth() ,userData.getHeight());

       if (!BodyUtils.enemyInBounds(body,userData)){
           world.destroyBody(body);
             createEnemy();}
    }

    public World getWorld(){
        return world;
    }

 // (2) ****using TouchDown method
      @Override
        public boolean touchDown(int x, int y, int pointer, int button) {

            // Need to get the actual coordinates
            translateScreenToWorldCoordinates(x, y);
          //  score++;
           // yourScoreName = "score: " + score;
            if(enemyTouched(touchPoint.x,touchPoint.y)){
              //  world.destroyBody(enemy.getBody());
                score++;
                yourScoreName = "score: " + score;
            }
            return super.touchDown(x, y, pointer, button);
        }
    private boolean enemyTouched(float x, float y) {
        return bounds.contains(x, y);
    }

    private void translateScreenToWorldCoordinates(int x, int y) {
        getCamera().unproject(touchPoint.set(x, y, 0));
    }




    @Override
    public void draw() {
        super.draw();
        batch.begin();
        yourBitmapFontName.setColor(1.0f, 1.0f, 1.0f, 1.0f);
        yourBitmapFontName.draw(batch, yourScoreName, 25, 100);
        batch.end();
        enemy.setBounds(enemy.getBody().getPosition().x,enemy.getBody().getPosition().y,enemy.getUserData().getWidth(),enemy.getUserData().getHeight());
        renderer.render(world, camera.combined);
    }
}

A screen from my game:

It should work the way you did it (with the addListener() method). But you have to set the correct bounds of the actor (width, height, position): actor.setBounds(x, y, width, height) . I would use the body to get these values. You can also use a ClickListener instead of the InputListener .

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