chipmunk 物理引擎的基本概念和基本用法
chipmunk是一個開源2D物理引擎,
項目主頁:http://code.google.com/p/chipmunk-physics/
工作需要研究了一下,這個引擎的資料還是不多,我閱讀了所有的文檔,7個demo,和一個教學(xué)程序,得出如下一些理解。
一,基本概念
space:發(fā)生物理模擬的空間,可容納body, shape,joint
body:剛體,可被賦予shape。剛體具有質(zhì)量,轉(zhuǎn)動慣量,位置,線性速度,加速度,角度,角速度,角加速度等屬性。剛體之間可通過joint連接
shape:決定剛體的碰撞外形。一個剛體上可覆蓋上多個shape,同屬于一個剛體的shape不會互相發(fā)生碰撞。shape同樣需要加到space中。有圓,線段,凸多邊形這三種shape類型。
joint: 用于連接剛體。有4種類型:
pin joint:相當(dāng)于一根棍子(質(zhì)量忽略)加兩個大頭針(錨點),兩個剛體如果用pin joint連接,他們之間的距離不會改變,他們各自可繞錨點轉(zhuǎn)動(如果有力矩的話)
slide joint:相當(dāng)于把pin joint的棍子換成了滑槽。這個滑槽有最大和最小長度。
pivot joint:即一個旋轉(zhuǎn)軸。兩個剛體都繞這個軸旋轉(zhuǎn)
groove joint:相當(dāng)于可滑動的pivot joint。將剛體2的旋轉(zhuǎn)軸掛到處于剛體1的一段滑槽上。
坐標(biāo)系:demo里都使用的是2d笛卡爾坐標(biāo)系。猜想對于2d游戲如果使用屏幕坐標(biāo)系應(yīng)該也可以(只是y反了)。或者在繪制2d sprite的時候自己轉(zhuǎn)換一下坐標(biāo)吧,應(yīng)該更清楚些。
單位:引擎沒有指定,最好使用國際單位制如kg,m,s,保持單位一致很重要
二,基本用法
0)初始化chipmunk引擎,調(diào)用cpInitChipmunk() -- 現(xiàn)在已經(jīng)不需要這個函數(shù)!!
1)構(gòu)建sapce,使用cpSpaceNew()
2)構(gòu)建一個static body,作為關(guān)卡的物理環(huán)境。這個body不需要加入到space中,否則會受重力作用。但這個body的shape需要加入到space中,用作碰撞檢測。
staticBody = cpBodyNew(INFINITY, INFINITY); //生成static body,一般一個場景有一個夠了
shape = cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f);//在static body上生成一個線段shape,也可以使用圓和多邊形
cpSpaceAddStaticShape(space, shape);//將這個shape加入到space中
3)生成剛體body,和static body類似,只是使用cpBodyNew,另外需要使用cpSpaceAddBody(space, body);將body加入到space中。例子:
cpVect verts[] = {
cpv(-15,-7),
cpv(-15, 7),
cpv( 15, 7),
cpv( 15,-7),
};
cpBody *body = cpBodyNew(1.0, cpMomentForPoly(1.0, num, verts, cpv(0,0)));//第二個參數(shù)是轉(zhuǎn)動慣量,一般用這個函數(shù)計算就可以了
body->p = cpv(x, y);//可設(shè)置body的位置
cpSpaceAddBody(space, body);//body要加入space中
cpShape *shape = cpPolyShapeNew(body, num, verts, cpv(0,0));
shape->e = 0.0; shape->u = 1.0;
cpSpaceAddShape(space, shape);//shape要加入space中
4) 加入joint:每個joint都是對于兩個body的。使用cpPivotJointNew之類的方法加入joint,然后還要使用cpSpaceAddJoint將joint加入到space中
5)進行物理模擬計算:
其 實只要調(diào)用cpSpaceStep(space, dt);就可以了。如果使用了外力,比如cpDampedSpring這樣的方法,就要先清除一下body上的力和力矩,使用 cpBodyResetForces,另外如果需要提高精度,可以將dt分為幾個step。例子:
void demo7_update(int ticks)
{
int steps = 3;
cpFloat dt = 1.0/60.0/(cpFloat)steps;
for(int i=0; i
cpBodyResetForces(chassis);
cpBodyResetForces(wheel1);
cpBodyResetForces(wheel2);
cpDampedSpring(chassis, wheel1, cpv(40, 15), cpvzero, 50.0f, 150.0f, 10.0f, dt);
cpDampedSpring(chassis, wheel2, cpv(-40, 15), cpvzero, 50.0f, 150.0f, 10.0f, dt);
cpSpaceStep(space, dt);
}
}
6)釋放對象
這樣就可以全部釋放:
cpSpaceFreeChildren(space); //釋放所有加入到space中的body, shape, joint
cpSpaceFree(space);
cpBodyFree(staticBody);//靜態(tài)body沒有加入space需要單獨釋放
三,碰撞回調(diào)
物理引擎本身會讓物體在碰撞后產(chǎn)生“正確”的反應(yīng)。但是你還是可以讓碰撞時調(diào)用自己的方法,甚至取消掉碰撞。
使用:cpSpaceAddCollisionPairFunc(space, 1, 0, &collFunc, &some_value);
static int
collFunc(cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, void *data)
{
int *some_ptr = (int *)data;
// Do various things with the contact information.
// Make particle effects, estimate the impact damage from the relative velocities, etc.
// for(int i=0; i
// printf("Collision at %s. (%d - %d) %d
", cpvstr(contacts[i].p), a->collision_type, b->collision_type, *some_ptr);
// Returning 0 will cause the collision to be discarded. This allows you to do conditional collisions.
return 1;
}
四,速度函數(shù)
body->velocity_func = apply_buoyancy;//設(shè)定了一個自定義的速度計算函數(shù)
這個函數(shù)給剛體加入了水面的浮力(demo6)。
// Apply an approximate bouyancy and drag force to an object.
static void
apply_buoyancy(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
int numx = 20;
int numy = 4;
float stepx = (float)WIDTH/(float)numx;
float stepy = (float)HEIGHT/(float)numy;
cpBodyResetForces(body);//先清除力和力矩
for(int x=0; x
for(int y=0; y
cpVect p_sample = cpv((x + 0.5)*stepx - WIDTH/2, (y + 0.5)*stepy - HEIGHT/2);
cpVect p = cpBodyLocal2World(body, p_sample);
cpVect r = cpvsub(p, body->p);
if(p.y < 0){
cpVect v = cpvadd(body->v, cpvmult(cpvperp(r), body->w));
cpVect f_damp = cpvmult(v, -0.0003*cpvlength(v));
cpVect f = cpvadd(cpv(0, 2.0), f_damp);//計算浮力
cpBodyApplyForce(body, f, r);//將力作用上
}
}
}
cpBodyUpdateVelocity(body, gravity, damping, dt);//默認(rèn)的應(yīng)該只有這句吧,作用上重力和阻力。
}
五,其他
可以加上沖量:
總結(jié)
以上是生活随笔為你收集整理的chipmunk 物理引擎的基本概念和基本用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ES系列十六、集群配置和维护管理
- 下一篇: upload通关手册