Libgdx: как определить, был ли задет враг?

#java #android #libgdx

#java #Android #libgdx

Вопрос:

Я хочу добавить к счету моей игры 1 когда враг был задет, я попробовал два метода addListener , touchDown но у меня не сработало, или я неправильно их использовал.

Как я могу сделать, чтобы мой (вражеский объект был связан с классами userData и Actor, я перегруппировал много разных размеров для своего врага в классе enum, и эти враги переместились из верхней части экрана в bot. Как определить, был ли задет враг?

 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);
    }
}
  

Скрин из моей игры:

Комментарии:

1. Вы не настроили окно просмотра для своей сцены (суперкласса), если только вы не делаете это извне. Фактический этап ничего не знает об этой вторичной камере, которую вы настроили в подклассе и используете только для рендеринга формы.

2. спасибо за ваш ответ, можете ли вы показать мне, как это сделать, плз, я пытаюсь определить события касания для актеров из учебника Уильяма Мора, я новичок в libgdx, и эта проблема останавливала меня до сегодняшнего дня

3. Разместите сообщение на форумах Libgdx. Слишком много, чтобы пройти через этот сайт.

4. хорошо, спасибо, я попробую

Ответ №1:

Это должно работать так, как вы это делали (с addListener() помощью метода). Но вы должны установить правильные границы субъекта (ширина, высота, позиция) : actor.setBounds(x, y, width, height) . Я бы использовал тело для получения этих значений. Вы также можете использовать a ClickListener вместо InputListener .

Комментарии:

1. спасибо , enemy.setBounds(enemy.getBody().GetPosition().x, enemy.getBody().GetPosition().y, enemy.getUserData().getWidth(), enemy.getUserData().getHeight()); я пробовал, но не сработало, для границX, Y, WIDTH , HEIGHT я инициализировал их раньше в EnemyTyp enum, а не в классе GameStage

2. Я бы использовал тело, которое вы создаете с WorldUtils.createEnemy(world) помощью метода. Убедитесь, что границы не равны 0 (например, при ведении журнала, Gdx.app.log() ).

3. вы можете взглянуть на мой вопрос я установил картинку из своей игры, я пытаюсь создать врага в фиксированных координатах, чтобы применить событие касания, но событие касания не обнаружено

4. Да, и я думаю, что причина этого в том, что границы актера неверны. У меня была такая же проблема

5. хорошо, спасибо за ваши усилия, я постараюсь найти для них решение