java - 从 libgdx 中的集合中检测触摸对象(移动)的最佳方法

标签 java android libgdx game-engine

这是我第一次尝试游戏开发。我刚刚开始尝试 libgdx 并了解游戏编程的不同方面。我查看了示例项目,我可以了解 libgdx 游戏的整体架构。但是为了掌握游戏动力学的基础知识,我开始玩一些低级的东西,比如如何绘制简单的形状,如何移动它们,如何处理这样的碰撞。

所以我打算写一个非常简单的安卓游戏(它甚至不是游戏)。这是思路

1. Create random shapes and make it fly (move)
2. When user touches the shape, it ll explode or hide or play simple animation
3. Has to show Hit & Miss count

最初我想尝试 libgdx 舞台和 Actor 概念,但排除了没有场景 API 的可能性。我开始尝试基本游戏的不同方面并更好地理解 libgdx 背后的概念。所以我做了这个简单的应用程序,我可以让物体随机掉落。

public class A1GameScreen implements Screen {

    OrthographicCamera camera;
    ShapeRenderer debugRenderer = new ShapeRenderer();
    Array<Rectangle> boxes;   
    long lastFlew;
    int fliesCaught;

    A1GameScreen(){

         camera = new OrthographicCamera();
         camera.setToOrtho(false, 800, 480);       
         boxes=new Array<Rectangle>();
         throwboxes();
    }
@Override
public void render(float delta) {

    Gdx.gl.glClearColor(0, 0, 0.2f, 1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);


          camera.update();


    debugRenderer.setProjectionMatrix(camera.combined);
    debugRenderer.begin(ShapeType.Line);

    for (Rectangle fly : boxes) {
        debugRenderer.rect(fly.x, fly.y, fly.width, fly.height);
    }
    debugRenderer.end();

    //Handle the user input

    if (Gdx.input.isTouched()){          
        hit(Gdx.input.getX(),Gdx.input.getY());
    }

    if (TimeUtils.nanoTime() - lastFlew > 1000000000)
        throwboxes();


    Iterator<Rectangle> iter = boxes.iterator();
    while (iter.hasNext()) {
        Rectangle fly = iter.next();        
        fly.x -= 2;
        if (fly.x + 32 < 0)
            iter.remove();

    }

}

//Method to create flies at random interval
private void throwBoxes(){

    Rectangle fly = new Rectangle();
    fly.y = MathUtils.random(0, 480 - 32);
    fly.x = 800;
    fly.width = 32;
    fly.height = 32;
    boxes.add(fly);

    lastFlew = TimeUtils.nanoTime();

}

private boolean hit (float x, float y) {
    boolean found=false;

    for (Rectangle fly : boxes) {
        found = fly.contains(x,y);
        if (found){
            found = true;
            fly.width=100;
            break;
        }


    }

    return found;

}

}

但我无法从掉落的物体中找出被触摸的元素。这就是我正在做的事情,以确定盒子是否在触摸范围内

  1. 遍历数组中的所有框
  2. 检查触摸坐标是否落在框坐标内
  3. 我将触摸坐标传递给 Rectangle (Box) 的 contains 方法来计算

像这样

  for (Rectangle fly : boxes) {
        found = fly.contains(x,y);
        if (found){
            found = true;
            fly.width=100;
            break;
        }


    }

但是它不起作用。我想我想通了这个问题。它的

  1. 盒子每帧在 x 轴上移动 2px,以产生飞行效果
  2. 但我假设,自触摸事件以来已经过去了一些帧。这就是为什么我没有得到预期的结果

我的问题是

  1. 如何解决这个问题?
  2. 在 libgdx 中检测碰撞的最佳方法是什么?

更新

我发现触摸坐标和框坐标之间有很多不匹配的地方。触摸范围内没有任何框。怎么可能。示例迹线下方

Touch coords: x-651.0 y-362.0

Fly coords: x-384.0 y-277.0
Fly coords: x-504.0 y-34.0
Fly coords: x-624.0 y-103.0
Fly coords: x-744.0 y-238.0



Touch coords: x-441.0 y-193.0

Fly coords: x-52.0 y-34.0
Fly coords: x-172.0 y-103.0
Fly coords: x-292.0 y-238.0
Fly coords: x-414.0 y-261.0
Fly coords: x-534.0 y-109.0
Fly coords: x-656.0 y-283.0
Fly coords: x-776.0 y-323.0


Touch coords: x-568.0 y-162.0

Fly coords: x-42.0 y-267.0
Fly coords: x-162.0 y-166.0
Fly coords: x-282.0 y-266.0
Fly coords: x-404.0 y-52.0
Fly coords: x-526.0 y-296.0
Fly coords: x-646.0 y-64.0
Fly coords: x-766.0 y-16.0

最佳答案

public static boolean pointInRectangle (Rectangle r, float x, float y) {
    return r.x <= x && r.x + r.width >= x && r.y <= y && r.y + r.height >= y;
}

在你的更新中-

if(pointInRectangle(flyRectangle, Gdx.input.getX(), Gdx.input.getY())){
  // Do whatever you want to do with the rectangle. maybe register them for effect
}

您还可以查看 Intersector类。

现在碰撞,如果你的游戏节奏很快,有很多敌人四处移动,玩家可能会与之发生碰撞,迟早你会使用 box2d 类型库,因为如果移动速度很高,你可能无法获得任何碰撞回调。事情可能会相互影响。您可以尝试使用速度和 deltaTime 在碰撞发生之前预测碰撞,但这仍然不够,您最终将重新发明轮子。

Mario's SuperJumper 是启动 libGDX 的绝佳演示。尝试一下。

编辑:

有一个实例成员-

Vector3 touchPoint;

在创建时-

touchPoint = new Vector3();

关于更新-

camera.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));

if (Gdx.input.justTouched()) {
    if (pointInRectangle(rectangle, touchPoint.x, touchPoint.y)) {
    }
}

请注意 libGDX 中的坐标系。为了测试,在屏幕上创建一个矩形。单击时,打印/调试矩形和触摸点的坐标。

关于java - 从 libgdx 中的集合中检测触摸对象(移动)的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17954204/

相关文章:

java - 如何在饼图之外显示测试

android - 如何在 Libgdx 中处理 Sprite ?

eclipse - LibGDX 双 Assets 设置、Eclipse、Gradle

java - 安卓错误 : The application has stopped unexpectedly please try again

android - whatsapp 超链接 - 结合 whatsapp ://send? 与 intent://send/

android - 在 Android 上继续使用旧的 Google Drive API

libgdx - Scene2d.ui 窗口的顶部颜色?

java - 使用 JProfiler 进行分析时,方法名称会触发基元的自动装箱

java - 基于代理的重载

java - 计算代码行数 - 质量指标