Как мне определить, был ли затронут спрайт в Java libGDX?

#java #android #libgdx

#java #Android #libgdx

Вопрос:

В последние несколько дней я портировал свою игру (Apopalypse) на мобильную платформу Android. Я быстро поискал в Google по обнаружению касания спрайта, но не нашел ничего полезного. Каждый воздушный шар всплывет после касания, и мне просто нужно определить, был ли он затронут. Вот мой код для создания воздушного шара:

Рендеринг (x, y, ширина и высота рандомизированы):

 public void render() {
    y  = 2;
    balloon.setX(x);
    balloon.setY(y);
    balloon.setSize(width, height);
    batch.begin();
    balloon.draw(batch);
    batch.end();
}
  

Создание в основном классе игры:

 addBalloon(new Balloon());

public static void addBalloon(Balloon b) {
    balloons.add(b);
}
  

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

1. Что вы пробовали? Вы читали wiki? ( github.com/libgdx/libgdx/wiki — проверьте разделы Обработки входных данных.)

Ответ №1:

в вашем классе, использующем метод рендеринга, можно выполнить следующий код:

 Vector3 touchPoint=new Vector3();

void update()
{
  if(Gdx.input.justTouched())
   {
    //unprojects the camera
    camera.unproject(touchPoint.set(Gdx.input.getX(),Gdx.input.getY(),0));
    if(balloon.getBoundingRectangles().contains(touchPoint.x,touchPoint.y))
     {
      // will be here when balloon will be touched
     }
    }
   }
  

Ответ №2:

Вот как я это сделал, но в зависимости от используемой вами сцены и элементов, к которым можно прикоснуться, могут быть немного более оптимизированные способы сделать это:

 public GameScreen implements Screen, InputProcessor
{

  @Override
  public void show()
  {
      Gdx.input.setInputProcessor(this);
  }

  @Override
  public boolean touchDown(int screenX, int screenY, int pointer, int button)
  {
      float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
      float pointerY = InputTransform.getCursorToModelY(windowHeight, screenY);
      for(int i = 0; i < balloons.size(); i  )
      {
          if(balloons.get(i).contains(pointerX, pointerY))
          {
              balloons.get(i).setSelected(true);
          }
      }
      return true;
   }

   @Override
   public boolean touchUp(int screenX, int screenY, int pointer, int button)
   {
       float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
       float pointerY = InputTransform.getCursorToModelY(windowHeight, screenY);
       for(int i = 0; i < balloons.size(); i  )
       {
           if(balloons.get(i).contains(pointerX, pointerY) amp;amp; balloons.get(i).getSelected())
           {
               balloons.get(i).execute();
           }
           balloons.get(i).setSelected(false);
       }
       return true;
    }

public class InputTransform
{
    private static int appWidth = 480;
    private static int appHeight = 320;

    public static float getCursorToModelX(int screenX, int cursorX) 
    {
        return (((float)cursorX) * appWidth) / ((float)screenX); 
    }

    public static float getCursorToModelY(int screenY, int cursorY) 
    {
        return ((float)(screenY - cursorY)) * appHeight / ((float)screenY) ; 
    }
}
  

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

1. windowWidth, windowHeight не определены в коде

2. Действительное утверждение, если я правильно помню, они напрямую инициализируются из Gdx.graphics.getWidth() и Gdx.graphics.getHeight()

3. Работает для меня, но это безумие, что нет чего-то встроенного для обработки этого!

Ответ №3:

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

 public class SpriteTouchable extends Sprite {

    public SpriteTouchable(Texture texture) {
        super(texture);
    }

    public SpriteTouchable(Sprite sprite) {
        set(sprite);
    }

    public static float xTrans(float x)
    {
        return x*Gdx.graphics.getWidth()/480;
    }

    public static float yTrans(float y)
    {
        return y*Gdx.graphics.getHeight()/320;
    }

    private boolean isTouched;

    /**
     * Type: Input Listener function
     * listen if this sprite button was pressed (touched)
     * @param marge : the extra touchable space out of sprite
     * @param x     : x position touched by user
     * @param y     : y position touched by user
     * 
     * return true  : Sprite touched
     * return false : Sprite not touched
     */
    public boolean isPressing(int marge,int x, int y) {
        if((x>getX() -xTrans(marge))amp;amp; x<getX()  getWidth() xTrans(marge)) {
            if((y>getY() -yTrans(marge))amp;amp; y<getY() getHeight() yTrans(marge)) {
                return true;
            }
        }
        return false;
    }
}

 public boolean isTouched() {
    return isTouched;
 }
  

вот как я это использую

 Gdx.input.setInputProcessor(new GameInputListener() {

            @Override
            public boolean touchUp(int screenX, int screenY, int pointer, int button) {

                return false;
            }

            @Override
            public boolean touchDown(int x, int yy, int pointer, int button) {
                int y = Gdx.graphics.getHeight() - yy;
                // if sprite   10 of px marge is touched
                if(mySpriteTouchable.isPressing(10, x, y)) {
                    // sprite is touched down
                }
                return false;
            }
}
  

с помощью той же логики вы можете обнаружить высвобождение спрайта, а также настроить его для размера эффекта при прикосновении к спрайту и многое другое…

надеюсь, это было полезно!

Ответ №4:

У вас есть Gdx.input.getX() и Gdx.input.getY() . Координаты X и Y последнего касания. Просто сравните их с рамкой воздушного шара.

Ответ №5:

Вы могли бы добавить крошечный прямоугольник размером 1×1 пиксель к вашей мыши и проверить, пересекается ли он или содержит другие поля. Вам нужно использовать поля для всех ваших объектов, которые вы хотите сделать интерактивными таким образом.

Ответ №6:

у меня есть простое решение, это похоже на создание небольшого прямоугольника размером 1 пиксель на один пиксель

Rectangle rect;

rect = new Rectangle(0, 0, 1, 1);

затем создайте метод, вызываемый

touching_checking();

в этом методе мы сделаем три вещи

сначала проверьте, затронут ли экран

во-вторых, поместите прямоугольник, в котором вы касаетесь экрана

затем, наконец, проверьте, перекрывается ли ваш прямоугольник с прямоугольником спрайта. вот так

private void touching_checking() {
if (Gdx.input.isTouched()) {
rect.setPosition(Gdx.input.getX(), Gdx.input.getY());
if (rect.overlaps(back.getBoundingRectangle())) {
//do what you want here
}
}
}
у меня есть массив спрайтов, называемых уровнями, я проверяю, какой из них я нажал вот так

 private void touching_checking() {
    if (Gdx.input.isTouched()) {
        rect.setPosition(Gdx.input.getX(), Gdx.graphics.getWidth() - Gdx.input.getY());
        for (int i = 0; i < levels.size; i  ) {
            if (rect.overlaps(levels.get(i).getBoundingRectangle())) {
                //do what you want here
            }
        }
    }
}
  

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

1. хорошее и простое решение. спасибо за пример кода. возможно, потребуется перенести координаты касания для рисования координат (или наоборот) перед тестированием .overlaps()

Ответ №7:

Вот что я использую в своем классе sprite. Я даю ему вектор, на который я нажал camera.unproject(new Vector3().set(x,y,0)); . возвращает true, если щелкнуть в области спрайта.

     /***
     * 
     * @param v3 Vector with MouseClickPosition
     * @return true if click was inside rectangle x --> x   width, y --> y   
     * height
     */

    public boolean clicked(Vector3 v3){
    Rectangle rec = getBoundingRectangle();

    if(v3.x >= rec.x amp;amp; v3.x < rec.x   getWidth()){
        if(v3.y >= rec.y amp;amp; v3.y < rec.y   getHeight()){
            System.out.println("click_ont"   v3.x   ", "   v3.y);
            return true;
        }
        else{
            return false;
        }
    }
    else{
        return false;
    }
}