梦开始的地方

您所在的位置:网站首页 fc游戏是用什么编程的 梦开始的地方

梦开始的地方

2024-07-15 20:56| 来源: 网络整理| 查看: 265

(本系列是一个回归电子游戏原点的特别系列,作者 @goodorc_gamedev)

上期链接:https://www.bilibili.com/read/cv13814284

一眨眼,本系列已经来到了最终章。

本章讨论最后一个技术问题——碰撞检测难题,之后就是对本系列的总结。

1、为什么碰撞检测是一个难题

在玩FC游戏的过程中,每一帧都可能发生各种碰撞。具体有:

角色与场景的碰撞。

主角与敌人的碰撞。

敌人被主角技能、子弹击中。

主角被敌方技能、子弹击中。

这些碰撞都需要被检测出来。根据游戏类型来说,碰撞分为两类:

1、超级玛丽类,一个主角,场景中有很多碰撞区。

2、《1942》类,主角有很多子弹,敌人也有很多。每个子弹都会和每一个敌人发生碰撞。

以1942、1943等打飞机游戏为例,如果玩家同时能发射6颗子弹,同屏会出现20个敌人。那么如果采用常规碰撞检测法,也就是判断每个子弹和每个敌人的距离,需要用双重循环做20*6=120次判断。

120次很多吗?对FC孱弱的CPU来说,真多,太多了,根本跑不动。

让我最佩服的是《魂斗罗》等游戏,不仅敌人多、场景复杂,甚至还能发射超多子弹,不愧是FC中期到后期的3A大作,优化真是绝了。

《魂斗罗》程序复杂度约等于超级玛丽+1943

2、位遮罩(BitMask)碰撞检测技术

不平凡的问题需要不平凡的解决方案。

对FC来说,CPU很弱,但全屏Tile数量不算太多,一屏只有32 * 30 = 960个tile。

那么容易想到一种量身定做的解决方案:BitMask 位遮罩检测技术。

这种思路本质比较朴实——将屏幕按照tile划分为32列 * 30行的网格,每个区域用一个bit表示能否被碰撞。没有碰撞体填0,有碰撞体填1。

这样,当主角的位置是(100, 100)时,因为100/8 = 12,所以他位于第(12, 12)格,只要判断col_map[12][12]是1还是0,就可以判断它能否碰撞了。

借用油管上的一张图:NES Assembly: Ep7 - BitMask Collision Detection

画个示意图比较明显:

上图所有可以跳上去的碰撞体,我都用红点标出来了,最小单位为8像素,也就是一个tile。

射击游戏的精度可以更低,对《1942》来说,哪怕是16x16的格子也是够用的。

顺带一说,在游戏引擎开发中,你经常会看到这种把屏幕划分成格子的优化算法,连胡渊鸣大神写的物理模拟算法也有相似的思路:

3、编程难点:用u8类型的数组模拟二维bit数组

众所周知,C语言并没有bit二维数组这种东西。所以咱们只能用u8数组+位运算来模拟。

这写起来就有点头疼了,摘抄我写的局部代码:

不瞒你们说,这段检测代码我写了三遍以上,修改了N次(FC开发不好调试)。最后还是有一点小BUG,所以以上代码仅供参考。

碰撞检测的方法先简单介绍到这里,如果想深入了解,建议参考我的spitfire游戏源码。地址:http://fogota.ys168.com/ 里面的访客上传03文件夹,spitfire压缩包。

终:连接遥远的过去与未来

FC游戏开发,是维京的梦,是我的梦,也是所有经历过那个时代的玩家共同的梦想。

FC为我们这一大群人打开了电子游戏的大门,相信其中的每一个人不仅曾经热爱过,也很好奇FC游戏开发的原理,想知道如何才能做一款FC游戏。就算没有能力去做,也想多了解一点,知道个大概。

于是我才写出了这9篇文章,从硬件到软件,由浅入深,逐步介绍我现阶段的研究成果。通过这9篇文章,大家对用C语言开发FC游戏应该已经建立了粗浅而完整的认识。

由于个人能力有限,只能简单介绍到这里为止。最可惜的是,除了“spitfire”演示项目外,我也还没能做出像样的FC游戏作品。也许这个遗憾能够在未来得到弥补。

这是系列的完结,也是新的开始。感谢所有FC爱好者的捧场,期待再次相会~~

(本文作者 @goodorc_gamedev。欢迎加入游戏开发群欢乐搅基:1082025059

对游戏开发感兴趣的童鞋可戳这里进一步了解:http://www.levelpp.com/)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3