Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/198.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 计算碰撞后的对象位置和方向_Android_Game Engine_Surfaceview_Game Physics - Fatal编程技术网

Android 计算碰撞后的对象位置和方向

Android 计算碰撞后的对象位置和方向,android,game-engine,surfaceview,game-physics,Android,Game Engine,Surfaceview,Game Physics,我正在写我自己的游戏引擎(一个非常基础的),我想学习物理是如何在游戏开发中工作的,而不是使用已经构建的游戏引擎。我正在用Java为Android设备编写代码(使用SurfaceView) 问题是我不知道如何计算碰撞后对象的位置。我已经创建了自己的碰撞检测,它工作得非常好 如你所见,红色矩形是我的球应该移动的区域。箭头显示碰撞发生后球应移动的位置。球有不同的位置,标记为1-11(注意,在渲染“世界”时,你只能看到一个球!) 球实际上是长方形的!但是你看不到边缘 我已经创建了自己的游戏对象类,其中

我正在写我自己的游戏引擎(一个非常基础的),我想学习物理是如何在游戏开发中工作的,而不是使用已经构建的游戏引擎。我正在用Java为Android设备编写代码(使用SurfaceView)

问题是我不知道如何计算碰撞后对象的位置。我已经创建了自己的碰撞检测,它工作得非常好

如你所见,红色矩形是我的球应该移动的区域。箭头显示碰撞发生后球应移动的位置。球有不同的位置,标记为1-11(注意,在渲染“世界”时,你只能看到一个球!)

球实际上是长方形的!但是你看不到边缘

我已经创建了自己的游戏对象类,其中保存了有关对象位置、速度、原点等的数据:

public abstract class GameObject
{
    public Vector2 dimension;
    public Vector2 position;
    public Vector2 velocity;
    public Vector2 origin;

    public Rectangle rectangle;

    public GameObject(Resources resources)
    {
        this.dimension = new Vector2();
        this.position = new Vector2();
        this.velocity = new Vector2();
        this.origin = new Vector2();

        this.rectangle = new Rectangle();
    }

    public void update(float deltaTime)
    {
        position.x += velocity.x;
        position.y += velocity.y;

        rectangle.set(position.x, position.y, dimension.x, dimension.y);

        origin.x = position.x + dimension.x / 2;
        origin.y = position.y + dimension.y / 2;
    }
}
如果球与红色矩形边距之一碰撞,则调用此方法:

protected void onBallCollideWithLevelEdge(Ball ball)
{
   // Calculate next position:
   ??????????
}
我的球有速度和位置。我应该保存球的上一个位置吗?

1)为什么将球表示为矩形?圆更容易处理,特别是当你们想把碰撞延伸到球上时

2) 如果你想做一个物理引擎,你必须有所有物体的坐标,以及相应的一阶和二阶导数,也就是速度和加速度。此外,每个对象都需要一个质量,可能还需要一些其他参数,例如材质(用于摩擦)和弹性,但在开始时不需要

3) 当发生与墙的碰撞时,您将获得当前球的位置和速度。根据这些数据,你必须计算法向力。法向力是这样的,球不能穿过墙壁,所以我会用这样的方法计算它的大小:

Nx = DELTAx*k;
Ny = DELTAy*k;
式中,k是一些可以修剪的弹性常数,x是球穿透墙壁的量。请注意,这仅适用于“慢速”对象。如果你要对付子弹,你最好用射线或其他东西。
另一种方法是计算碰撞时的动能,并将其转换为弹性能。一旦你有了弹性能,你就可以在垂直于墙的方向上释放它,把它转化为一种力。 一旦你有了力,它就变成了加速度,除以质量

4) 在每次模拟迭代中,您将速度添加到位置,将加速度添加到速度,记住将其乘以积分时间(dt)。这个时间可以任意设定,它是一个常数。如果你想要一个100Hz的模拟,你可以将dt设置为10ms。您还必须重新计算加速度,即力的总和除以质量

5) 正如你所注意到的,我从来没有提到方向,因为如果你在推理分解每个轴上的坐标(在2D引擎中是x,y),你不需要它。如果法向力为“右”,如您的示例所示,Ny分量将设置为零,而Nx将转换为加速度,并改变水平速度。这也会改变球的方向


这些只是建议,实际上你应该先学习运动学,然后再学习理性力学。

我有一个函数,看起来像这样:

Nx = DELTAx*k;
Ny = DELTAy*k;
位置calculateValidPosition(位置开始,位置结束) 位置中点=(开始+结束)/2

我只是在运行中编写了这个代码,所以有很大的改进空间。。。首先不要让它递归

当检测到碰撞时,将调用此函数,并将对象的最后有效位置和当前无效位置作为参数传递。在每次迭代中,第一个参数始终有效(无冲突),第二个参数无效(有冲突)


但是我认为这可以给你一个可能的解决方案的想法,这样你就可以根据自己的需要调整它。

我猜你的碰撞检测器已经确定球和墙重叠了。如果只是更改速度而不是位置,则将渲染一个球与墙重叠的帧。你需要把物体往后退一点。您可以在中找到一个讨论(和一个非常基本的实现)