2D平台游戏物理学

16

这是一个漫长的假日周末,所以我又开始写代码了:

Mario http://gfilter.net/junk/tileengine.jpg

我写了一个基本的块引擎,但由于之前从未尝试过,我在处理精灵碰撞检测和实现重力方面遇到了很大的困难。

对于其他的游戏爱好者,你能给我指一些最好的方法吗?

更新:

我想分享一下进展:

http://www.youtube.com/watch?v=-RKNQ2UiiLY <-- 游戏演示

它仍然存在很多漏洞,但碰撞检测大部分都可以工作,我已经开始着手开发其他功能(例如弹出块(注意缺陷)并与敌人互动)。

马里奥仍然像在月球上行走,我正在使用这些常量,请问有没有调整建议使其更加真实?

    const float AirDrag = 1.00f;
    const float GroundFriction = .97f;
    const float Gravity = 0.8f;

8
视频关了! - Gabriel
9个回答

5

3

重力很简单:

const gravity = ... ; // pixels per timestep (eg. video frame) squared
// while in freefall, each timestep:
y_velocity += gravity;
y_pos += y_velocity;

请注意,我玩过的大多数2D平台游戏并没有真实的重力。只要做任何让游戏有趣的事情!

4
从技术角度来看,我认为你应该首先更新位置(因此它使用前一个时间步长的速度),然后再更新速度。 - gnovice
@gnovice 更加技术性地说,可以看一下Verlet算法。 - user2039981

2

jnrdev 可能会有所帮助,它涵盖了瓷砖碰撞/响应和斜坡。虽然这不是我见过的最好的代码,但它可以完成任务。


谢谢你提供的链接。我也想推荐它,但是多年来它已经在我的书签中丢失了 :) - grepsedawk

2

http://www.metanetsoftware.com/technique/tutorialA.htmlhttp://www.metanetsoftware.com/technique/tutorialB.html有几个非常有用的2D平台游戏教程。我认为其他地方的一些人已经提到过它们。它们涵盖了碰撞检测和响应、射线投射、各种优化技术等,并为那些(像我一样)数学不太好的人提供了很好的理论解释。虽然它没有涉及刚体动力学之类的东西,但我认为你不需要为你正在编写的游戏添加这种类型的内容(当然如果你能添加这种内容会很酷...)。


从外表看,我建议的教程涵盖了Zack Mulgrew提到的jnrdev类似的内容。我还没有仔细阅读jnrdev(只是初步浏览),所以无法进行比较。 - bm212

1

这可能是一个绕路,但是尝试一下XNA 3.0的平台游戏入门套件,其中包含物理和基本碰撞检测等内容。你需要更改一些东西才能使其在XNA之外工作,但这并不是什么难事。

XNAGS 3.0下载


0

我不知道你在使用什么物理模型,但最近在另一个SO问题中讨论了使用流体阻力的物理模型。我不会重复我在答案中给出的所有东西,我只会链接到它

总之,问题的OP想要将对象从静止加速到最大速度。我通过几个导出推导了两种不同类型的阻力模型下速度随时间变化的函数建模方法。你的情况可能会略有不同,因此使用的积分可能具有不同的形式或需要使用不同的初始条件来解决,但希望我的答案能为你指出一些信息方向。


0

关于多个方块被撞的问题,您可以通过只撞最接近玩家精灵或偏移最小的方块来解决。请确保不仅限制在一个方向上。在马里奥游戏中,方块实际上可以从任何方向被撞击。(通过在同一游戏中进行地面猛击或钻头旋转)(通过使用贝壳在侧面)


0
    UIGraphicsBeginImageContext(images.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIColor *color = [UIColor whiteColor];
    [color setFill];

    CGContextTranslateCTM(context, 1, images.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextSetBlendMode(context, kCGBlendModeDestinationOver);
    CGRect rect = CGRectMake(0.0, 0.0, images.size.width, images.size.height);
    CGContextDrawImage(context, rect, images.CGImage);
    CGContextClipToMask(context, rect, images.CGImage);
    CGContextAddRect(context, rect);
    CGContextDrawPath(context, kCGPathFill);
    images = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

-6

7
那会让这件事变得没意思了。 - FlySwat
如果你想用困难的方式度过一生,那就随你的便吧。 - wjhplano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接