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