如何用Box2D Library制作2D物理游戏_2
- 时间:
- 浏览:0
如何用Box2D Library制作2D物理游戏
如何用Box2D Library制作2D物理游戏的今日更新是一个不断变化的过程,它涉及到许多方面。今天,我将与大家分享关于如何用Box2D Library制作2D物理游戏的最新动态,希望我的介绍能为有需要的朋友提供一些帮助。
文章目录列表:
如何用Box2D Library制作2D物理游戏
2.帝国时代:罗马复兴的游戏秘籍
作者:Juan Felipe Belon Perez
从最热门游戏排行榜和flash游戏网站上,你能看到什么?许多2D游戏都有非常出色的物理学和美术设计。现在我们要学习那些游戏使用了什么物理学以及如何用Box2D制作它们。
除了知道是“什么”,更重要的是知道“如何做”,首先,我想问读者一个问题:如果你想复制物理游戏的机制或行为,你需要什么技术和方法?
一年以前,我问了自己同样的问题,《6 Dimensi 》就是问题的答案。这款游戏是一个创意的盒子,每一面都包含一组使用Box2D物理学再加上视觉美学技术制作的不同的游戏机制。在此,我将与大家分享这款游戏。我做这款游戏是为了改进游戏引擎Codea(是由Crabitron开发的),而我写了这篇教程是为了向大家介绍写实物理学、美术和游戏设计……共同提高我们的游戏开发水平。
在我的游戏中,我设计了6个面,借同样的思路,我将给大家介绍我运用了哪些从其他游戏中复制而来的物理、机制和美术技术。
1、形状
《Thomas was alone》、《愤怒的小鸟》、《蜡笔物理学》
crayon physics(from gamasutra)
在《蜡笔物理学》中,你可以在屏幕上用手指或鼠标作画,比如画圆、三角形、矩形等,当你松开鼠标/拿开手指,线条就会变成立体物理对象(在虚拟 中)。
这是怎么做的?
事实上相当简单,你要把鼠标/手指从开始到结束的绘画路径的各个坐标点保存起来,当释放事件发生,你就调用Box2D的一个根据这些点生成多边形的功能:
local body=physics.body(POLYGON, unpack( points ) )
你得先认识一下Box2D中的有什么形状:
POLYGON(多边形):
用于封闭形状如基本几何图形(非圆形),它使用一系列按各个API 的顺序排列的顶点(x,y)
CIRCLE(圆):
可以做球、水珠、星体,等等。
EDGE(边):
用于制作墙、地面、只有起点和终点的线段。
CHAIN(链):
与边相同,但你可以闭合它(像多边形但不是凸多边形)或不闭合它(像边但点超过2)
知道了刚体形状(body shape)后,你还要了解它们的不同行为,或叫作刚体类型(body types):
STATIC(静态):如名称所示,这种刚体会在 的x,y(地面、墙、柱基或绳基,等等)上保持静止不动。
DYNAMIC(动态):它与其他对象碰撞并移动
KINEMATIC(运动):碰撞但不随着动态对象移动,你只能通过改变它的x,y或者赋给它一个线性速度或对它施加力来使它移动。
真正的含义要在API的执行中理解,在本文中我使用这个是因为它是我能找到的最简单的代码了。但改变成任何语言的代码都非常简单,Box2D有几乎所有的语言版本(Flash as3、c++、objc、java、javascript、java+processing,等等)。
你得保存那个功能的结果为自定义变量如body.position(位置)、body.radius(半径)、body.linearVelocity(线性速度)、body.angularVelocity(角速度)、body.mass(质量),等等。
当刚体制作出来时,你可能想给它定义一些属性如restitution(恢复)、gravityScale(重力大小)和damping(衰减)等,这些属性可以赋给物理对象弹跳或漂浮状态。
Box2D的复杂度当然不止这些,具有这种物理游戏机制的其他游戏(《Magic Pen》)也比较复。在《Magic Pen》中,你可以画一些东西看起来像“node(节点)”的东西,但开发者叫它们“joint(关节)”,它们是用于连接刚体的,有若干种,取决于你想要的机制;还可以用于制作连接着的刚体之间的行为:
physics.joint(REVOLUTE,bodyA, bodyB,)
刚体围绕着一个固定点(anchor)旋转
例如:小车的车轮、《蜡笔物理学》和《Magic Pen》中的红色节点
physics.joint( PRISMATIC, bodyA, bodyB, anchorA, direction )
在刚体各自的固定点之间保持固定距离。两个joint之间的初始距离取决于虚拟空间中的这两个固定点之间的初始距离。给joint设置frequency率和damping率可以使它产生软弹簧的行为。
physics.joint(DISTANCE, bodyA, bodyB, anchorA, anchorB )
旋转joint迫使两个刚体沿着某两个固定点之间的轴作运动。允许伸缩运动,但限制两个刚体之间的相对旋转。
physics.joint( WELD, bodyA, bodyB, anchor )
接合joint限制两个刚体之间的运动和相对旋转,实际上使它们变成一个刚体。因为求解器的迭代性质,当置于压力之下时接合joint可能会变形;当承受的力太大或几个接合joint被链接成一个更大的对象时,接合joint可能会完全失效。
physics.joint( ROPE, bodyA, bodyB, anchorA, anchorB, maxLength )
绳子joint限制两个刚体之间的最大距离
例如:《割绳子》中的绳子
概述:
1)创建:带有触点刚体或盒子或任何其他多边形几何体(一组2D点:x,y),给它设置我们需要的物理属性(如《Thomas was alone》中的不同行为),比如,如果刚体是static类型,那么就可以设置它的质量、密度、重力大小,等等。
2)可选属性:依附(attach)到另一个刚体上,比如说,你可以把一个刚体依附到另一个被设置为传感器的static刚体(不影响游戏 的物理,但有碰撞事件),然后激活REVOLUTE joint的enableMotor(能动)属性,这还需要motorSpeed(速度)、maxMotorTorque(转矩)和maxMotorForce(力量),才能确定这个对象的旋转情况。
3)美术(Visual Art):有了刚体后,如果你想绘制它,不是作为形状绘制出来,而是具有颜色或纹理的实体,你就要把这些点三角化生成多边形网格模型(mesh)并给它设置颜色和贴材质。
例子:
Box2D_POLYG (from gamasutra)
thomas Was Alone Boxes(from gamasutra)
对于《Thomas Was Alone》中的盒子的行为,你可以设置一个简单的“juice”系统动画(从“中间帧”演化来的),这样,当你选择方块并按下跳跃键(或它与其他不同的物理刚体发生碰撞),它就会触发“juice command=animation”命令——产生挤压、摇晃等动画效果,各个动作都有自己的动画参数,比如质量、线性速度和衰减等物理属性。
box Examples(from gamasutra)
对于《愤怒的小鸟》,你可以通过给盒子定义不同的属性来制作一个关卡,绘制不同的子画面或制作不同材质的mesh,这样,在碰撞事件中,盒子刚体就会更加生动,通过改变盒子的纹理使之与当前状态更加协调(断掉的木头、快碎的玻璃,等)。
你可以用简单的刚体 lyForce(vec2(x,y)) 函数做出小鸟的发射。各种小鸟也都有自己的质量、衰减等属性……
2、水体
《Where is my water?》、《Sprinkle Ilsands》……
当你问网上的代码达人,如何制作上述游戏那样的水体物理时,他们会跟你谈Metaball(变形球):
Metaball_contact_sheet(from gamasutra)
但在游戏中使用Metaball技术既麻烦也不容易,而且要进行大量计算,除非你发现一些技巧和给它贴上一些美术材质。
那就是为什么运用水体物理学的游戏并不多见。几个月前我谈到这个问题,多亏了许多人的帮助,我得到了一个很棒的水体物理模型。在那个模型中,我用Box2D lib中的CIRCLE刚体做出动态球。
模型的代码很容易理解,球就是物理刚体,这些刚体具有使它产生水滴行为的参数如estitution(复原)、friction(摩擦)、damping(衰减)、linear elocity(线性速度),然后,我们用着色器(GLSL)的技术和材质绘制这些球,需要一个mesh,就像波纹fx或使用材质的其他GLSL着色器样本,我们把这个mesh的宽和高设为整个屏幕,从中间开始:
mesh:addRect(WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT)
这样,我们可以使用各个球的位置(x,y)在虚拟空间中绘制它们,各个球都有渐变的纹理效果。
for k,b in ipairs(balls) do
sprite(ballTexture, b.x, b.y)
end
然后,你得使用额外的扭曲模式,给这些着色的球添加材质,并与背景混合。
例子:
Box2D_water Physics(from gamasutra)
正如我所说的,各个球都有纹理(程序生成的渐变),可以与其他使用低级过滤器的球材质相融合。
where is my water(from gamasutra)
《Where is my water?》
你可以对各种行为使用不同的层,或者把所有液体或所有动态地形做成同一层来做出相同的水体fx,然后在着色器中改变过滤值和颜色(水体、岩浆,等等)。
举一个碰撞的例子,当两个刚体发生碰撞时,你必须查看碰撞的bodyA和bodyB是什么类型的刚体,如果一个是气体(gravityScale/mass/density值实际上是0,所以它会飘浮)而另一个是“冰”,那么你就把这个球变成水……
再举一个例子,如果bodyA是岩浆,那么bodyB就变成气体……就像改变球的属性一样简单,所以它会改变在box2d中响应,你要重新绘制游戏状态。
地形的例子:
静态地形可以是一个POLYGON刚体,它是用一个读取整个地形图象和建立一系列非透明像素的x,y (vec2)的函数制作的,然后返回给box2d函数。
动态地形可以只是一个mesh,当你碰它时,你会移除座标x,y上的触点,你必须用新的mesh重制这个物理刚体。
例如,当一个水滴(物理刚体CIRCLE)溅到一只 (具有激活的传感器的物体刚体),你必须删除那个水滴,并改变 的动画,使新状态呈现,直到它完全被水充满,然后删除 并记录结果。
水滴有很小的痕迹,这些是用linearVelocity和angularVelocity属性绘制的,你可以得到方向和速度,这样你就可以计算痕迹的角度和距离。
事实上,你想要什么行为都有。
sprinkle_islands_boss(from gamasutra)
在《Sprinkle Ilsands》中,水体着色器跟我们所学习的那个是不同的,它除了使用粒子fx,还多了linearVelocity属性。但行为可能还是一样的,当水球(刚体CIRCLE)击中火传感器,那么火就会熄灭,海里的水mesh也一样。至于岩石,你可以添加一些细节如颗粒效果等。
在这一面,我们找不到任何joint,那就是为什么它可能不必要,在《Sprinkle Ilsands》,软管就是绳子,这是我们在下一面中要分析的。
3、橡皮筋
《Contre Jour》、《割绳子》、《水果忍者》
我花了一个月时间才做出上述游戏的绳子原型,但我做完绳子后,我就觉得软刚体很容易做了,因为我更加理解接头了。
要制作一个逼真的绳子,你得创建一组刚体(CIRCLE或者POLYGON都行),把它们都依附在作为基座的STATIC刚体上。用于结合这些绳子刚体的joint有两种,DISTANCE或者REVOLUTE,但处于最末端(DYNAMIC)的连接基座(STATIC)的joint只能是制作弹力绳的ROPE joint。通过restitution 和frequency属性来调整resp e(反应)/damping(衰减)/elasticity(弹性)。
例子:
Box2D_ElasticRopes(from gamasutra)
为了制作一个软刚体,你得围绕另一个中心刚体(可以是STATIC或DYNAMIC)制作一系列CIRCLE刚体,它当然会影响其他刚体,如果你改变joint的类型,你会发现这个刚体会自动变形,你必须用mesh绘制整组刚体。
Contre-Jour(from gamasutra)
《Contre Jour》
在这款游戏中,你可以找到软刚体:可变形的地形;两种类型的绳子:弹性绳和固定绳。这些固定绳使用的技术比弹性绳的更高级。
snotDiagram(from gamasutra)
js Rope Segmented(from gamasutra)
《割绳子》
cut-the-rope(from gamasutra)
这是Box2d物理做绳子的最佳案例。游戏中的绳子也是动态的,你可以看到沿着基座到球的mesh,球的一端是连着糖果的。
你可以像上一个例子一样做出这种绳子,设置球(糖果)的物理属性—-mass、density、gravityScale,可以做出泡泡效果。你可以用多层混合模式绘制出泡泡。另一种方法是把刚体变成传感器,并且你自己的重力算法移动它,但我们到第五面时才学习这种技术。
如果泡泡-刚体-球与青蛙或蜘蛛碰撞,或者玩家触击到泡泡,泡泡就会爆炸,为此你要给泡泡添加爆炸动画并再次改变糖果的物理属性……
案例代码:
if (vec2:distance( bFrog_Mouth, bCandy ) < maxDistance) then
– 把青蛙的动画从“空闲”改为“吃”
– 暂停输入
– 补间并触发游戏结束动画
end
4、重力
在这一面,我们可以发现许多使用力来对抗重力的游戏,但这是一种游戏玩法。例如,你可以根据box2d的正弦函数生成简单的地形,它会返回链或边形状的STATIC刚体。
tiny wings 2(from gamasutra)
你可以用Box2d做出你自己的《Tiny Wings》。基本原理就是,球(CIRCLE刚体)在重力的作用下下落,你可以通过触击屏幕增加下落的linearVelocity(线性速度),当触击在山丘合适的部分(你可以查看你的正弦函数的高度)释放时,下落速度会增加……另一种方法是只使用力。
例子:
Box2D_JumpRun(from gamasutra)
为了绘制循环,给拾取、发热状态等添加颗粒效果。材质可以用程序成生随机颜 像做出来,用高斯噪声添加细节、边界,等等……
Jetpack-Joyride(from gamasutra)
《Jetpack Joyride》
你可以看出这款游戏的特征吗?如果你已经读过前面的例子了,那么你应该知道角色刚体球有相同的行为,你一定是用力对抗重力、各个飞行器的不同物理属性、导弹和各种交通工具,等等。
《Madcoaster》、《Rocket Chicken》、《Whale Trail》等游戏都是一样的。
但这个面还有其他机制,如行星物理、引力。
你可以使用简单的公式来模拟零重力physics.gravity(0,0),行量的吸引力如下图所示:
Box2D_Forces_Gravity(from gamasutra)
function Planet:attract(m)
– Direction of the force
local force=self.body.position – m.body.position
local d=force:len() —=m.body.position:dist(self.body.position)
force=force:normalize()
local dir=ec2(self.mass/m.body.mass, self.mass/m.body.mass)
– Magnitude of the force
local strength=(GRAVITY * self.mass * m.body.mass)/(d*d)
force=force * strength
m.body: lyForce(force)
stroke((1+math.floor(force.y))*110, (1+math.floor(force.x))*110, 10, 255)
– draw line between attractor/mover
line(m.body.x+force.x, m.body.y+force.y, (self.body.x), (self.body.y))
end
这个函数会使角色球绕着行星转。
5、线面
《拯救种子》、《蜡笔物理学》……
只有线:通过绘制线条,你可以做出形状类CHAIN的刚体和刚体类STATIC或DYNAMIC。
对于关卡设计,障碍物也是STATIC,可以是EDGE或POLYGON……
saving-seeds-hd-doodle-physics-screenshot(from gamasutra)
用那种结构,你可以复制出一款像《拯救种子》一样的游戏。
Box2D_Lines(from gamasutra)
代码和 面的是一样的,但你必须改变游戏的规则,你要从暂停的物理引擎开始,然后绘制和生成CHAIN静止形状,当玩家按下开始键时,游戏必须生成玩家的球(以及恢复、重力、质量等参数),重新开启物理引擎,只要一个指令(physics.pause() and physics.resume())就能完成了。
它只留在游戏循环中,用于确认碰撞和线性速率、改变游戏状态……
你可以通过打开或关闭重力,来改变整个游戏的现实,就像《Thomas was alone》或《ibb and obb》那样。
6、交通工具
《小轮车冒险》、《登山 》
如果你已经看到这里了,那么做一款关于疯狂交通工具的游戏吧。
做交通工作,只要把接头和轮子想成CIRCLE刚体,用锚点正确的旋转接头把POLYGON(小车、自行车等的形状)和它们连接起来。
用带纹理的mesh绘制自行车/小车的主要刚体、车轮的子画面,除非你使用软刚体做这些,否则添加痕迹、颗粒fx等。
代码生成的例子:
Box2D_BezierRampage(from gamasutra)
对于道路,使用一些噪点或正弦,可以是STATIC或DYNAMIC,你可以使用Bezier曲线。
code example(from gamasutra)
《小轮车冒险》
我会知道这款游戏和它的物理,多亏看了某人的一篇文章。
但文章作者没有提到任何有关Box2D的东西,但我猜这款游戏就是使用了Cocos2d(和Corona SDK)。无论如何,你现在知道怎么制作交通工具和横冲直撞的效果了。
在《Canvas Rider》中,有两种自行车模型,你可以在游戏中改变,你会发现自行车的刚体是一个允许一定damping的接头结构,当你改变自行车时,这个动态刚体就被破坏了,然后游戏就生成新的自行车类型。
另外,你在游戏中的自行车可以触到的线是静态CHAIN,当你设计道路时,鼠标触击的是x,y……像我们之前做的那样。
以上。希望你能用Box2D做出一些成果。
当然,使用Box2D,通过不同的方法制作的游戏还有很多,但它们可能综合使用了上述几种,例如,《时空幻境》、《超级食肉男孩》等,用可以用合适的刚体、机制和着色器制作出来。
帝国时代:罗马复兴的游戏秘籍
游戏中按下Enter键后,输入下列密码可以达到相应的效果:
STORMBILLY=机械兽会发射雷射 CONVERT THIS!=会降天谴的僧侣 BIG MOMMA=得到一辆白色车子,有火箭发射系统 POW=婴儿骑著三轮车会发射炮弹 KING ARTHUR=飞鸟变成飞龙 GRANTLINKSPENCE=动物变得很强 DIEDIEDIE=杀死所有对手 E=MC2 TROOPER=超级装甲兵 RESIGN=放弃 REVEAL MAP=显示所有地图 PEPPERONI PIZZA=食物1000 COINAGE=金1000 WOODSTOCK=木头1000 QUARRY=石头1000 PHOTON MAN=太空时代的人,手持雷射 GAIA=控制动物 HARI KARI=FLYING DUTCHMEN=投石船可在路上行走 NO FOG=地图迷雾效果关闭 STEROIDS=快速建筑 BIG DADDY=飞弹发射车 KILLX=杀死编号(#=1-8)的敌人 HOMERUN=胜利 BIG BERTHA=投石车变强 ICBM=弩车的攻击距离增为100 HOYOHOYO=教士变强 DARK RAIN=弓箭手变成树木 BLACK RIDER=骑士变成黑骑士 big bertha 投石车力量变强 photonman 可以得到一个手持激光武器的人 big daddy 得到 diediedie 敌全灭 flying dutchman 得战舰可上陆地 gaia 魔法师力量变强 home run 过关 medusa 农民被杀后变骑士,再被杀变投石车 no fog 雾效果取消 reveal map 全地图 steroids 加速 pepperoni pizza 得到1000食物 coinage 得到1000金
quarry 得到1000石头
woodstock 得到1000木头
STORMBILLY=机械兽会发射雷射
CONVERT THIS!=会降天谴的僧侣
BIG MOMMA=得到一辆白色车子,有火箭发射系统
POW=婴儿骑著三轮车会发射炮弹
KING ARTHUR=飞鸟变成飞龙
GRANTLINKSPENCE=动物变得很强
DIEDIEDIE=杀死所有对手
E=MC2 TROOPER=超级装甲兵
RESIGN=放弃
REVEAL MAP=显示所有地图
PEPERONI PIZZA=食物1000
COINAGE=金1000
WOODSTOCK=木头1000
QUARRY=石头1000
PHOTON MAN=太空时代的人,手持雷射
GAIA=控制动物(你的手下会失控)
HARI KARI=
FLYING DUTCHMEN=投石船可在路上行走
NO FOG=地图迷雾效果关闭
STEROIDS=快速建筑
BIG DADDY=飞弹发射车
KILLX=杀死编号(#=1-8)的敌人
HOMERUN=胜利
BIG BERTHA=投石车变强
ICBM=弩车的攻击距离增为100
HOYOHOYO=教士变强
DARK RAIN=弓箭手变成树木
BLACK RIDER=骑士变成黑骑士
big bertha 投石车力量变强
photonman 可以得到一个手持激光武器的人
big daddy 得到
diediedie 敌全灭
flying dutchman 得战舰可上陆地
gaia 魔法师力量变强
home run 过关
medusa 农民被杀后变骑士,再被杀变投石车 字串3
no fog 雾效果取消
reveal map 全地图
steroids 加速
pepperoni pizza 得到1000食物
coinage 得到1000金
quarry 得到1000石头
woodstock 得到1000木头
波斯,打猎速度快30%,象类兵移动速度快30%
巴比伦,僧侣回复信仰速度快33%,采石速度快15%
好了,今天关于“如何用Box2D Library制作2D物理游戏”的话题就讲到这里了。希望大家能够对“如何用Box2D Library制作2D物理游戏”有更深入的认识,并且从我的回答中得到一些帮助。