【LWJGL官方教程】游戏逻辑

原文:https://github.com/SilverTiger/lwjgl3-tutorial/wiki/Game-logic
译注:并没有逐字逐句翻译一切,只翻译了自己觉得有用的部分。另外此翻译仅供参考,请一切以原文为准。代码例子文件链接什么的都请去原链接查找。括号里的内容一般也是译注,供理解参考用。总目录传送门:http://blog.csdn.net/zoharwolf/article/details/49472857

现在我们已经知道怎样渲染游戏和怎样处理输入,但是怎样做游戏呢?本教程来我们来看看游戏逻辑。

Updating Entity Position 更新实体坐标

之前提过时间间隔这个概念,即两次循环的时间差,更新实体的时候需要它。
为此需要些物理知识。物理中,力是质量乘以加速度(F = m*a),也就是加速度是力除以质量(a = F/m)。加速度即速度的变化率,a = dv/dt, 其中dt就是时间间隔。速度是时间经过时的位置变化率,v = dx/dt。

Euler integration 欧拉积分

用这些定义,就可以更新位置了。时间间隔很明确了,速度可以用speed变量计算出来,这个变量表示物体每秒的移动距离。还需要一个单位向量表示移动方向。这样就可以用以下伪代码计算速度了。

// You shouldn't normalize a null vectorif (direction.length() != 0) {
    direction = direction.normalize();
}
velocity = direction * speed;

用欧拉积分可以更新实体的位置和速度,伪代码如下:

position += velocity * delta;
velocity += (force / mass) * delta;

例子里没有加速度,所以实体的更新方法如下:

public void update(float delta) {
    previousPosition = new Vector2f(position.x, position.y);
    if (direction.length() != 0) {
        direction = direction.normalize();
    }
    Vector2f velocity = direction.scale(speed);
    position = position.add(velocity.scale(delta));
}

第一行可有可无,当你需要用插值时有用。

Checking for collision 碰撞检测

有许多算法可以检测碰撞,比如轴分离定理(Separating Axis Theorem ,SAT)或包围盒算法(Axis-Aligned Bounding Boxes ,AABB)。对于简单的程序来说,AABB就够了,更复杂的需求可以使用SAT等更复杂的算法。

Axis-Aligned Bounding Boxes (AABB) 包围盒

定义一个包围盒很容易,用两点创建一个矩形,这两点被称为最小和最大向量。在2D的程序里,你可以认为一个实体的左下角是最小向量,右上角是最大向量。
有了这些点,就可以检查两个AABB的碰撞了。

boolean intersects(AABB first, AABB second) {
    if (first.max.x < second.min.x)
        return false;

    if (first.max.y < second.min.y)
        return false;

    if (first.min.x > second.max.x)
        return false;

    if (first.min.y > second.max.y)
        return false;

    // All tests failed, we have a intersectionreturn true;
}

另一个使用AABB的方法就是定义一个中心点变量,然后用矩形的半宽。

boolean intersects(AABB first, AABB second) {
    if (Math.abs(first.center.x - second.center.x) > first.halfWidth.x + second.halfWidth.x)
        return false;

    if (Math.abs(first.center.y - second.center.y) > first.halfWidth.y + second.halfWidth.y)
        return false;

    // All tests failed, we have a intersectionreturn true;
}

哪个适合你的程序就用哪个。当然你也需要根据新的位置坐标来更新你的AABB。
检测碰撞后,需要调整实体位置。假设你有一个原点在左下角的实体,可以用以下伪代码调整位置。

if (entity.collided(otherEntity) == COLLISION_TOP_SIDE)
    entity.position.y = otherEntity.y + otherEntity.height;

if (entity.collided(otherEntity) == COLLISION_BOTTOM_SIDE)
    entity.position.y = otherEntity.y - entity.height;

if (entity.collided(otherEntity) == COLLISION_LEFT_SIDE)
    entity.position.x = otherEntity.x - entity.width;

if (entity.collided(otherEntity) == COLLISION_RIGHT_SIDE)
    entity.position.x = otherEntity.x + otherEntity.width;

如果不这样做,在下一个循环中还会再有碰撞,实体将一直缓缓地从另一个实体身上穿过去。

既然这已经是最后一篇教程了,那么接下来就看你了。如果你想做游戏,不妨先试着做些简单的游戏,比如俄罗斯方块或者太空入侵者。
如果想学更多LWJGL3的东西,你应该看看DEMO(这个DEMO其实是一个PONG游戏)。
你可能也想要用像libGDX或者jMonkeyEngine之类的类库来做游戏,它们将帮你完成样板代码。
关于碰撞检测,如果你不想手动实现你自己的物理引擎,你也可以看看JBox2DJBullet
但是当然,你也可以从零开始去搞自己的小游戏。
想要怎么做,随你,祝你开心,感谢阅读本教程。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值