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

这是我第一次尝试游戏开发。 我刚开始尝试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阶段和演员概念,但排除了没有场景API。 我开始尝试基本游戏的不同方面,并更好地理解libgdx背后的概念。 所以我制作了这个简单的应用程序,我能够使对象随机掉落。

 public class A1GameScreen implements Screen { OrthographicCamera camera; ShapeRenderer debugRenderer = new ShapeRenderer(); Array boxes; long lastFlew; int fliesCaught; A1GameScreen(){ camera = new OrthographicCamera(); camera.setToOrtho(false, 800, 480); boxes=new Array(); 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 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. 我通过触摸坐标来contains Rectangle (Box)的方法来弄清楚

这样的事情

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

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

  1. Box每帧在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 rx <= x && rx + r.width >= x && ry <= y && ry + 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类型的库,因为如果移动速度很高,你可能不会得到任何碰撞回调。 事情可能会相互影响。 您可以尝试使用velocity和deltaTime在碰撞发生之前预测碰撞,但它仍然不够,您将最终重新发明轮子。

Mario的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中的坐标系。 要进行测试,请在屏幕上创建一个矩形。 单击,打印/调试矩形和touchPoint的坐标。

我已经通过制作一个隐藏的矩形来解决问题,该矩形将跟随点击位置,我做了一个if语句检查不可见矩形的重叠并检查屏幕是否刚被点击。

这是代码:

 if(Gdx.input.isTouched()) { Vector3 pointerPos = new Vector3(); pointerPos.set(Gdx.input.getX(), Gdx.input.getY(), 0); cam.unproject(pointerPos); touchPos.x = pointerPos.x /*+ 64 / 2*/; touchPos.y = pointerPos.y /*+ 64 / 2*/; } Iterator iter = raindrops.iterator(); while(iter.hasNext()) { Rectangle raindrop = iter.next(); raindrop.y -= 300 * Gdx.graphics.getDeltaTime(); if(raindrop.y + 64 < 0) { iter.remove(); } if(raindrop.overlaps(touchPos) && Gdx.input.justTouched()) { iter.remove(); dropSound.play(); } 

所有这些代码都在render方法中。

PS:将雨滴改为你想要的苍蝇对象