如何用Box2D库制作2D实体游戏

作者:胡安·费利佩·贝隆·佩雷斯

从最热游戏排行榜和flash游戏网站可以看出什么?许多2D游戏有出色的物理和艺术设计。现在我们要学习那些游戏用的是什么物理,如何用Box2D制作。

除了知道是什么,更重要的是知道怎么做。首先想问读者一个问题:如果要复制实体游戏的机制或行为,需要哪些技术和方法?

一年前,我问过自己同样的问题,答案是6维。这个游戏是一个创意盒子,每一面都包含一套由Box2D物理和视觉美学技术制作的不同游戏机制。在这里,我将与你分享这个游戏。我做这个游戏是为了改进游戏引擎Codea(由Crabitron开发),我写这个教程是为了介绍现实的物理、艺术和游戏设计…共同提高我们的游戏开发水平。

在我的游戏里,我设计了六张脸。抱着同样的想法,我给大家介绍一下我从其他游戏中抄袭了哪些物理,机制,美术手法。

1,形状

托马斯一个人,愤怒的小鸟,蜡笔物理。

蜡笔物理学(来自gamasutra)

蜡笔物理,可以用手指或鼠标在屏幕上画,比如圆形、三角形、矩形等。当你松开鼠标/移开手指时,线条会变成三维的物理对象(在虚拟世界中)。

这是怎么做到的?

其实挺简单的。你需要保存鼠标/手指绘制路径从开始到结束的坐标点。当释放事件发生时,可以调用Box2D的一个函数根据这些点生成多边形:

local body = physics.body(多边形,解包(点) )

你得先知道Box2D里有什么形状:

多边形(POLYGON):

用于封闭基本几何图形(非圆形)等形状,它使用一系列顶点(x,y)按照每个API指定的顺序排列。

圆形(圆形):

你可以做球、水滴、星星等等。

边缘:

用于制作只有起点和终点的墙壁、地板和线段。

链条(链条):

与边相同,但可以闭合(像多边形但不是凸多边形)或不闭合(像边但有2个以上的点)。

知道了刚体的形状(body shape),还需要了解它们不同的行为,或者叫做体型:

静态:顾名思义,这个刚体会在指定的x,y(地面、墙壁、柱基础或绳基础等)上保持静止。).

动态:它与其他物体碰撞并移动。

运动学:碰撞不随动态对象移动。你只能通过改变它的x,y,给它一个线速度或者对它施加力来让它移动。

真正的意义要在API的执行中去理解。我在本文中使用它,因为它是我能找到的最简单的代码。但是把代码改成任何语言都很简单。Box2D几乎拥有所有语言版本(Flash as3、c++、objc、java、javascript、Java+处理等。).

您必须将该函数的结果保存为用户定义的变量,如body.position(位置)、body.radius(半径)、body.linearVelocity(线速度)、body.angularVelocity(角速度)、body.mass(质量)等。

当创建一个刚体时,你可能想要为它定义一些属性,例如恢复,重力比例,阻尼等。这些属性可以赋予处于弹跳或浮动状态的物理对象。

当然,Box2D的复杂程度不止于此,其他采用这种物理游戏机制的游戏(魔笔)也更加复杂。在魔笔里,你可以画出看起来像“节点”的东西,但开发者称之为“关节”。它们用于连接刚体。有好几种,看你想要的机制。它还可以用于在连接的刚体之间产生行为:

物理.关节(旋转,身体a,身体b)

刚体绕锚旋转。

比如:汽车的轮子,蜡笔物理和魔笔里的红色节点。

物理连接(棱形、主体a、主体b、锚固、方向)

在刚体的各个固定点之间保持固定的距离。两个关节之间的初始距离取决于虚拟空间中两个固定点之间的初始距离。为关节设置频率率和阻尼率可以使其产生软弹簧行为。

物理.关节(距离、身体a、身体b、锚a、锚b)

旋转关节迫使两个刚体在两个固定点之间沿轴移动。允许伸缩运动,但两个刚体之间的相对转动是有限的。

物理连接(焊缝、车身a、车身b、锚固)

接合关节限制了两个刚体之间的运动和相对旋转,实际上使它们成为一个刚体。由于求解器的迭代性质,当置于压力下时,关节可能变形;当力太大或几个关节连接成一个更大的物体时,关节可能会完全失效。

物理连接(绳子,身体a,身体b,锚a,锚b,最大长度)

绳索接头限制了两个刚体之间的最大距离。

例如,《割断绳子》中的绳子。

概述:

1)创建一个有触点或任何其他多边形几何形状(一组2D点:x,y)的刚体或盒子,并设置我们需要的物理属性(如托马斯独自一人时的不同行为)。比如刚体是静态的,我们可以设置它的质量,密度,重力等等。

2)可选属性:附加到另一个刚体。比如可以将一个刚体附加到另一个设置为传感器的静态刚体上(不影响游戏世界的物理,但是有碰撞事件),然后激活REVOLUTE关节的enableMotor属性,同样需要motorSpeed、maxmotorque和maxMotorForce。

3)视觉艺术:当你有了一个刚体之后,如果你想把它画出来,不是作为一个形状,而是作为一个有颜色或纹理的实体,你要把这些点三角化,生成一个多边形的网格模型,并为它设置颜色和粘贴材质。

示例:

Box2D _多边形(来自gamasutra)

托马斯是一个人盒子(来自gamasutra)

对于《Thomas Was Alone》中盒子的行为,可以设置一个简单的“果汁”系统动画(由“中间帧”演化而来),这样当你选中盒子并按下跳转键(或者它与其他不同的物理刚体发生碰撞)时,就会触发“果汁命令=动画”命令——产生挤压、晃动等动画效果,以及每一个动作。

方框示例(来自gamasutra)

对于愤怒的小鸟,可以通过定义盒子的不同属性来做关卡,绘制不同的子图或者用不同的材质做网格,这样在发生碰撞的时候,盒子的刚体会更加生动,通过改变盒子的纹理(碎木头,碎玻璃等)来和当前的状态更加和谐。).

可以使用简单的刚体applyForce(vec2(x,y))函数发射一只鸟。各种鸟也有自己的质量,衰减等属性...

2.水体

《我的水在哪里?》、《洒金沙》……

当你问网上的编码员如何让水物理像上面的游戏一样,他们会和你聊Metaball:

Metaball_contact_sheet(来自gamasutra)

但是在游戏中使用Metaball技术比较麻烦,也不容易,而且需要大量的计算,除非你找到一些技巧,在上面附上一些艺术素材。

这也是为什么使用水物理的游戏很少的原因。几个月前我谈到了这个问题,由于很多人的帮助,我得到了一个非常棒的水的物理模型。在那个模型中,我用Box2D lib中的圆形刚体做了一个动态球。

模型的代码很容易理解。球是物理刚体,这些刚体具有使它们的行为像水滴一样的参数,例如估计、摩擦、阻尼和线速度。然后,我们使用着色器(GLSL)的技术和材料来绘制这些球,这需要一个网格,就像ripple fx或其他使用材料的GLSL着色器样本一样。

网格:addRect(宽度/ 2,高度/ 2,宽度,高度)

这样我们就可以用每个球的位置(x,y)在虚拟空间里把它们画出来,每个球都有渐变的纹理效果。

对于k,b在ipairs(balls)中做

精灵(球纹理,b.x,b.y)

结束

然后,你必须使用额外的扭曲模式来添加材料到这些彩色球中,并将其与背景混合。

示例:

Box2D _水物理学(来自gamasutra)

正如我所说的,每个球都有一个纹理(由程序生成的渐变),可以使用低级过滤器与其他球材质混合。

我的水在哪里

《我的水在哪里?》

你可以对各种行为使用不同的图层,或者把所有的液体或者所有的动态地形都放到同一个图层里做同样的水fx,然后改变滤镜值和颜色(水,岩浆等。)在着色器中。

比如两个刚体碰撞,你必须检查bodyA和bodyB是什么样的刚体。如果一个是气体(gravityScale/mass/density值其实是0,所以会浮起来),一个是“冰”,那么你可以把这个球变成水...

再比如,如果bodyA是岩浆,那么bodyB就变成气体了...就像改变球的属性一样简单,所以它会改变box2d中的响应,你要重画游戏状态。

地形示例:

静态地形可以是多边形刚体,由读取整个地形图像并建立一系列不透明像素的x,y (vec2)的函数制成,然后返回给box2d函数。

动态地形可以只是一个网格。当你触摸它时,你将移除坐标X和Y上的触点,并且你必须用新的网格再现物理刚体。

例如,当水滴(物理刚性圆)溅到鸭子(带有激活传感器的物体刚体)上时,您必须删除水滴,更改鸭子的动画,使新的状态出现,直到它完全充满水,然后删除鸭子并记录结果。

水滴有细小的痕迹,这些痕迹是用线速度和角速度特性画出来的。你可以得到方向和速度,这样你就可以计算出痕迹的角度和距离。

其实你想做什么都可以。

spruce _ islands _ boss(来自gamasutra)

在spruce Ilsands中,水着色器与我们研究的不同。除了使用粒子特效,它还具有线性速度的属性。但是行为可能还是一样的。当水球(刚性圈)碰到火灾感应器,火就会熄灭,海中的水网也会熄灭。至于岩石,你可以添加一些细节如纹理效果。

在这一边,我们找不到任何关节,这就是为什么它可能是不必要的。在spruce Ilsands中,软管是一根绳子,这是我们将在下一面分析的内容。

3.橡皮筋

战斗日,割断绳子,水果忍者

我花了一个月的时间做了上面这个游戏的绳子原型,但是做完绳子之后,我觉得柔软的刚体很好做,因为我更了解关节。

要制作一个真实的绳子,你必须创建一组刚体(圆形或多边形)并将它们附加到静态刚体上作为基础。用于组合这些绳索的接头有两种,距离式或回转式,但动态连接的静态端的接头只能是制作弹性绳索的绳索接头。通过休止符和频率属性调整响应/阻尼/弹性。

示例:

Box2D _ ElasticRopes(来自gamasutra)

为了做一个软刚体,你要在另一个中心刚体(可以是静态的,也可以是动态的)周围做一系列的圆形刚体,这当然会影响到其他刚体。如果改变关节类型,会发现这个刚体会自动变形,必须用网格画出整组刚体。

Contre-Jour(来自gamasutra)

《对抗日》

在这个游戏中,你可以找到柔软的刚体:可变形的地形;两种类型的绳子:弹性绳和固定绳。这些固定绳使用了比弹性绳更先进的技术。

snotDiagram(来自gamasutra)

js绳索分段(来自gamasutra)

割断绳子

割断绳子(来自gamasutra)

这是Box2d物理做绳子最好的案例。游戏中的绳子也是动态的。你可以看到沿着底座到球的网格,球的一端连接着糖果。

你可以像上一个例子一样做这个绳子,设置球(糖果)的物理属性——质量、密度、重力刻度,可以做出泡泡效果。你可以在多层混合模式下绘制气泡。还有一种方法是把一个刚体变成传感器,靠你自己的引力算法来移动,但是这个技术我们是第五面才学会的。

如果泡泡-刚体-球与青蛙或蜘蛛相撞,或者玩家触摸到泡泡,泡泡就会爆炸。出于这个原因,您应该将爆炸动画添加到气泡中,并再次更改糖果的物理属性...

案例代码:

if (vec2:distance( bFrog_Mouth,bCandy)& lt;最大距离)

把青蛙动画从“闲”改成“吃”

–暂停输入

-补间并触发游戏结束动画

结束

4.重力

在这方面,我们可以找到很多用武力对抗重力的游戏,但这是一种玩法。例如,您可以基于box2d的正弦函数生成一个简单的地形,它将返回一个链或边形状的静态刚体。

小翅膀2(来自gamasutra)

你可以用Box2d制作你自己的小翅膀。基本原理是球(圆形刚体)在重力作用下下落,你可以通过触摸屏幕来增加下落的线速度。当在山坡的适当位置释放触摸时(您可以检查正弦函数的高度),下落速度将会增加...另一种方法是只使用武力。

示例:

Box2D_JumpRun(来自gamasutra)

为了画一个循环,给拾音器,加热状态等添加一个粒子效果。材质可以用程序生成随机的彩色图像,用高斯噪声添加细节和边界等等...

Jetpack-Joyride(来自gamasutra)

《喷气背包之旅》

你能看出这个游戏的特点吗?如果你看过前面的例子,那么你应该知道角色刚性球也有同样的行为,你必须对抗重力,各种飞行器,导弹,各种交通工具的不同物理属性等等。

《疯狂海岸》、《火箭鸡》、《鲸迹》等游戏都是如此。

但是这个平面上还有其他机制,比如行星物理和引力。

可以用一个简单的公式来模拟零重力physics.gravity(0,0),线量的引力如下图所示:

Box2D_Forces_Gravity(来自gamasutra)

功能星球:吸引(m)

–力的方向

局部力= self . body . position–m . body . position

local d = force:len()—= m . body . position:dist(self . body . position)

force = force:normalize()

局部方向= vec2(自身质量/身体质量,self.mass/m.body.mass)

–力的大小

局部强度=(重力*自身质量* m.body.mass)/(d*d)

力=力*强度

m.body:应用力(力)

笔画((1+math . floor(force . y))* 110,(1+math . floor(force . x))* 110,10,255)

–在吸引器/移动器之间画线

line(m.body.x+force.x,m.body.y+force.y,(self.body.x),(self.body.y))

结束

这个功能会让角色球围绕星球旋转。

5.线和面

保存种子,蜡笔物理...

只有线:通过绘制线,你可以使刚体的形状类链和刚体类静态或动态。

对于关卡设计,障碍也是静态的,可以是边或多边形……...

保存-种子-高清-涂鸦-物理-截图(来自gamasutra)

有了这种结构,你就可以复制一个像保存种子这样的游戏。

Box2D_Lines(来自gamasutra)

代码和第一个一样,但是你必须改变游戏规则。你应该从悬挂的物理引擎开始,然后绘制并生成链的静态形状。当玩家按下开始键,游戏必须生成玩家的球(以及恢复、重力、质量等参数),重启物理引擎,只需要一个指令(物理)就可以完成。暂停()和物理。resume())。

它只停留在游戏循环中,用于确认碰撞和线性速率,改变游戏状态...

你可以通过打开或关闭重力来改变整个游戏的现实,就像托马斯独自一人或ibb和obb一样。

6.交通设施

小轮车冒险,登山比赛

如果你看到了这个,那就做一个关于疯狂运输的游戏吧。

做交通工作,只要把关节和车轮想象成一个圆形刚体,把多边形(汽车、自行车等的形状)连接起来。)通过用正确的定位点旋转关节。

用纹理网格绘制自行车/汽车的主刚体和车轮的子图。除非你用软刚体来做到这一点,添加痕迹,粒子fx等。

代码生成的示例:

Box2D_BezierRampage(来自gamasutra)

对于道路,使用一些噪声或正弦,可以是静态的或动态的。可以用贝塞尔曲线。

代码示例(来自gamasutra)

小轮车大冒险

我会知道这个游戏和它的物理原理,这要感谢看了某人的一篇文章。

但是作者并没有提到任何关于Box2D的东西,不过我猜这款游戏只是用了Cocos2d(和Corona SDK)。总之,现在你知道如何制作车辆和横冲直撞的效果。

在Canvas Rider中,有两种自行车模型,你可以在游戏中改变它们。你会发现自行车的刚体是允许一定阻尼的关节结构。当你换自行车时,动态刚体被破坏,然后游戏生成一个新的自行车类型。

另外,你的自行车在游戏中能碰到的线是静态链。当你设计道路时,鼠标接触X,Y …就像我们之前做的那样。

以上。希望你能用Box2D做出点成绩。

当然,使用Box2D的不同方法制作的游戏还是很多的,不过可能会综合使用上面提到的,比如《时空幻境》、《超级食肉男孩》等。,并且它们可以由合适的刚体、机构和着色器制成。