三行代码做一辆Q弹物理自行车,骑上它去海边兜风吧!
夏天到了,約上三五好友,騎上自行車,在灑滿陽(yáng)光的海岸上飛馳,咔噠咔噠的鏈條聲,伴隨著空氣中薄荷的清香,這也許就是夏天的味道吧。
今天給大家分享如何用三行代碼創(chuàng)建一輛物理自行車。在分享之前,先來(lái)體驗(yàn)一下最終效果 ,三、二、一,上鏈接:夏日單車🚴?♀?:https://ibear.net/summer-bike
物理引擎
首先,我們要實(shí)現(xiàn)的是一輛帶有物理表現(xiàn)效果的自行車,所以需要基于2D物理引擎來(lái)進(jìn)行開(kāi)發(fā),目前主流Web2D物理引擎有P2.js、Matter.js、Box2D等,其中Box2D是最具代表性的一款2D物理引擎。
傳統(tǒng)的Web開(kāi)發(fā)方式,使用Box2D開(kāi)發(fā)較為繁瑣,比如我們要?jiǎng)?chuàng)建一個(gè)帶有重力的正方體
var?gravity?=?newb2Vec2(0,9.8);?//定義重力向量,x軸0?y軸向下,加速度是9.8.? var?world?=?newb2World(gravity,true);?//new?一個(gè)?名字叫?world?的世界變量 var?bodydef?=?newb2BodyDef();?//new?一個(gè)剛體對(duì)象? bodydef.type?=?b2Body.b2_dynamicBody;?//定義剛體對(duì)象為?動(dòng)態(tài)對(duì)象.?會(huì)受到外力的作用. varfixDef?=?newb2FixtureDef();?//創(chuàng)建一個(gè)?b2FixtureDef?對(duì)象.? fixDef.density=1.0;?//?desity?密度,如果密度為0或者null,該物體則為一個(gè)靜止對(duì)象?fixDef.friction=0.9;?//摩擦力(0~1)? fixDef.restitution=1.0;?//?彈性(0~1) fixDef.shape?=?newb2CircleShape();?//?定義圓的半徑是?50px?window.PTM_RATIO?是米轉(zhuǎn)換像素的因子.? fixDef.shape.SetRadius(50?/?window.PTM_RATIO); ... 復(fù)制代碼可以看到,傳統(tǒng)的web開(kāi)發(fā)方式,僅僅是創(chuàng)建一個(gè)矩形,需要寫(xiě)一堆的API,創(chuàng)建剛體、創(chuàng)建形狀 、創(chuàng)建材質(zhì)、設(shè)置各種屬性,相當(dāng)繁瑣。
所以我們選擇使用Cocos Creator游戲引擎來(lái)進(jìn)行開(kāi)發(fā)。Cocos Creator對(duì)Box2D進(jìn)行了封裝,讓開(kāi)發(fā)者可以以可視化操作的方式創(chuàng)建物理對(duì)象,無(wú)需編寫(xiě)任何代碼。
游戲引擎
CocosCreator是一款十分容易上手的優(yōu)秀國(guó)產(chǎn)游戲引擎,支持JS/TS,編輯器界面也十分簡(jiǎn)潔:
image.png使用CocosCreator創(chuàng)建一個(gè)具有物理屬性的對(duì)象,只需要在節(jié)點(diǎn)樹(shù)中創(chuàng)建一個(gè)普通對(duì)象,在對(duì)象的屬性檢查器中創(chuàng)建物理碰撞組件即可:
與物理相關(guān)的所有屬性配置,對(duì)象綁定,關(guān)節(jié)綁定等都可以通過(guò)可視化的方式進(jìn)行配置。
開(kāi)始造車
1. 結(jié)構(gòu)拆解
接下來(lái)我們開(kāi)始使用CococsCreator創(chuàng)建一輛自行車,先來(lái)看看自行車的結(jié)構(gòu):
image.png2.創(chuàng)建車輪
把車輪圖片拖到場(chǎng)景樹(shù)中,添加CircleCollider圓形碰撞體:
3.創(chuàng)建車架
車架是一個(gè)不規(guī)則圖形,這里我們添加一個(gè)多邊形碰撞體,選擇編輯模式,手動(dòng)調(diào)整多邊形形狀:
4.建立關(guān)節(jié)綁定
有了車架和兩個(gè)輪子,接下來(lái)我們要把輪子固定在車架上,并且可以自由旋轉(zhuǎn),這就涉及到物理引擎中的一個(gè)重要組件:關(guān)節(jié)。
先來(lái)認(rèn)識(shí)一下物理引擎中常用的幾個(gè)關(guān)節(jié)的定義和表現(xiàn):
image.png旋轉(zhuǎn)關(guān)節(jié):圍繞一個(gè)固定點(diǎn)自由旋轉(zhuǎn)(無(wú)法產(chǎn)生位移),可開(kāi)啟Motor屬性,模擬輪子驅(qū)動(dòng)效果。
焊接關(guān)節(jié):收到力的作用后,圍繞一個(gè)固定點(diǎn)旋轉(zhuǎn)(無(wú)法產(chǎn)生位移),當(dāng)失去里的作用后恢復(fù)原狀,過(guò)程中的表現(xiàn)具有彈力效果。
距離關(guān)節(jié):當(dāng)剛體受力后受距離關(guān)節(jié)影響被拉回初始位置,并具有彈力效果。
棱柱關(guān)節(jié):約束剛體運(yùn)動(dòng)的方向,通常可以跟距離關(guān)節(jié)組合使用。
繩子關(guān)節(jié):與距離關(guān)節(jié)相似,不具有彈力屬性。
馬達(dá)關(guān)節(jié):受力產(chǎn)生位移和旋轉(zhuǎn)后回到初始的位置與初始旋轉(zhuǎn)角度,并具有彈力屬性。
下面用一個(gè)DEMO來(lái)演示下每種關(guān)節(jié)的不同表現(xiàn):
了解完不同關(guān)節(jié)的用法,接下來(lái)我們選擇用旋轉(zhuǎn)關(guān)節(jié)將輪子與車架進(jìn)行連接:
由于旋轉(zhuǎn)關(guān)節(jié)是繞著一個(gè)固定的點(diǎn)旋轉(zhuǎn),不具有彈力效果,所以騎上這臺(tái)車,落地的時(shí)候可能有點(diǎn)蛋疼。我們可以借助一個(gè)中間看不見(jiàn)的空節(jié)點(diǎn)“零件”,來(lái)模擬一個(gè)避震的效果:
實(shí)現(xiàn)原理:將中間零件B與車架交接處建立一個(gè)距離關(guān)節(jié)(DistanceJoint),將距離設(shè)置為0,彈力(Frenquency)設(shè)置成一個(gè)合適的彈力值,B跟C就產(chǎn)生了彈力連接的效果,再加上一個(gè)棱柱關(guān)節(jié)(PrismaticJoint),限制距離關(guān)節(jié)運(yùn)動(dòng)的方向僅在Y軸方向運(yùn)動(dòng),最后車輪A跟零件B建立一個(gè)自由旋轉(zhuǎn)關(guān)節(jié)(RevoluteJoint),讓輪胎掛在零件B上進(jìn)行旋轉(zhuǎn),這樣我們就完成一個(gè)山地車的車輪避震效果。
按照相同原理將前輪、后輪與車架完成關(guān)節(jié)綁定后,我們來(lái)看看效果:
有了前后懸掛,小車車一下就DUANG起來(lái)了,騎上它腰也不酸,🥚也不疼了。
最后,添加腳踏板,與車架建立一個(gè)旋轉(zhuǎn)關(guān)節(jié),自行車就完成了:
5.創(chuàng)建騎手
首先我們要找到人體的根骨骼,也是人體質(zhì)量占比最高的身體部位-上半身與盆骨,將其與車架進(jìn)行連接,四肢與頭部再與身體部位建立關(guān)節(jié)綁定:
11.gif我們希望在自行車發(fā)生碰撞時(shí),身體能隨車輛自然著晃動(dòng)搖擺,所以我們要選擇一個(gè)具備彈力屬性的關(guān)節(jié)進(jìn)行連接,距離關(guān)節(jié)(DistanceJoint)、焊接關(guān)節(jié)(WeldJoint)、摩托關(guān)節(jié)(MotorJoint)都具備彈力屬性,三種關(guān)節(jié)綁定方式都有不同的表現(xiàn),這里我使用了焊接關(guān)節(jié)。
在身體節(jié)點(diǎn)上加上WeldJoint組件,拖動(dòng)車架節(jié)點(diǎn)到ConnectedBody中完成綁定,設(shè)置關(guān)節(jié)的松緊與阻尼大小,將身體節(jié)點(diǎn)的關(guān)節(jié)錨點(diǎn)拖動(dòng)到身體外部,與車架錨點(diǎn)重合,完成關(guān)節(jié)綁定:
12.gif由于我們需要給上肢和下肢足夠的活動(dòng)空間,所以身體擺動(dòng)和位移的幅度不宜過(guò)大,如果使用距離或摩托關(guān)節(jié),受到較大撞擊時(shí)產(chǎn)生的位移可能導(dǎo)致四肢斷裂或者擠壓過(guò)度的情況,經(jīng)過(guò)測(cè)試這里使用WeldJoint效果最佳。
6.創(chuàng)建四肢
在創(chuàng)建各個(gè)身體部位時(shí),有一個(gè)細(xì)節(jié)需要注意:每個(gè)身體部位的質(zhì)量大小應(yīng)該符合正常人體部位質(zhì)量比例,最終創(chuàng)建的布娃娃物理表現(xiàn)會(huì)更接近真實(shí)效果:
image.png接下來(lái)我們用自由旋轉(zhuǎn)關(guān)節(jié)給四肢創(chuàng)建關(guān)節(jié)綁定,用焊接關(guān)節(jié)給頭部創(chuàng)建關(guān)節(jié)綁定:
13.gif將前臂末端與車把手建立旋轉(zhuǎn)關(guān)節(jié)綁定:
14.gif7.腳踏齒輪驅(qū)動(dòng)
按照符合現(xiàn)實(shí)規(guī)律的常規(guī)思路,我們?nèi)绻胪ㄟ^(guò)對(duì)雙腳施加外力來(lái)驅(qū)動(dòng)腳踏齒輪旋轉(zhuǎn),實(shí)現(xiàn)方案可能比較復(fù)雜,這里我們進(jìn)行一波反向操作:將兩根小腿的末端與齒輪兩端連接,通過(guò)齒輪旋轉(zhuǎn)來(lái)反向驅(qū)動(dòng)雙腳運(yùn)動(dòng),也就是動(dòng)力學(xué)中的一個(gè)重要方法:反向動(dòng)力學(xué)(IK - Inverse kinematics)
反向動(dòng)力學(xué)(Inverse kinematics)是一種通過(guò)先確定子骨骼的位置,然后反求推導(dǎo)出其所在骨骼鏈上n級(jí)父骨骼位置,從而確定整條骨骼鏈的方法。
完成綁定后,我們看看最終效果:
至此我們就完成了一輛Q彈自行車的全部創(chuàng)建工作。
不對(duì)?說(shuō)好的三行代碼造一輛自行車?怎么一行代碼都沒(méi)有?上代碼:
Game.js onLoad?()?{//?在入口函數(shù)中開(kāi)啟物理模擬,默認(rèn)是關(guān)閉的,并設(shè)置重力方向與大小。let?physicsManager?=?cc.director.getPhysicsManager();physicsManager.enabled?=?true;physicsManager.gravity?=?cc.v2(0,?-640); } 復(fù)制代碼最后
在開(kāi)始嘗試讓自行車跑起來(lái)后發(fā)現(xiàn)了一些問(wèn)題:由于人體重心與車輛結(jié)構(gòu)重心均靠后,導(dǎo)致自行車在行駛過(guò)程或在空中姿態(tài)中容易失去平衡向后翻倒,所以我在車架上加入一個(gè)質(zhì)量遠(yuǎn)大于車身質(zhì)量的隱形無(wú)重力擺錘(類似大樓振蕩器原理),來(lái)抵消減小車輛失去平衡產(chǎn)生的扭力,同時(shí)施加不同方向的恒力,動(dòng)態(tài)調(diào)整車身姿態(tài)。
寫(xiě)一個(gè)物理游戲,跟寫(xiě)好一個(gè)物理游戲,差異往往都在細(xì)節(jié)當(dāng)中,對(duì)于不同物理組件的靈活運(yùn)用,每個(gè)物理參數(shù)配置的細(xì)微差異,都影響著整體游戲的表現(xiàn)與體驗(yàn)。
最后,騎上它去海邊兜風(fēng)吧!HAVE FUN!
體驗(yàn)連接::夏日單車🚴?♀?:https://ibear.net/summer-bike
關(guān)于本文
來(lái)自:Guowc
https://juejin.cn/post/7105973605451694087
往期干貨:26個(gè)經(jīng)典微信小程序+35套微信小程序源碼+微信小程序合集源碼下載(免費(fèi))?干貨~~~2021最新前端學(xué)習(xí)視頻~~速度領(lǐng)取前端書(shū)籍-前端290本高清pdf電子書(shū)打包下載 點(diǎn)贊和在看就是最大的支持??總結(jié)
以上是生活随笔為你收集整理的三行代码做一辆Q弹物理自行车,骑上它去海边兜风吧!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: matlab给定振形用图表示,基于 MA
- 下一篇: java计算机毕业设计英语学习网站设计与