cocos2dx+box2d实现物体爆裂效果
1.说明
整个实现参考了网上的flash代码,代码也还没有做优化
爆炸点是按照受理点随即角度裂开的,在下面例子中就是用的鼠标click点。
对于易做图后的碎块如果太小,则直接丢弃。
切分是用的box2d的raycast来实现的,切分完毕后在创建ccsprite
为了绘制纹理,修改了CCSprite类,使之可以画一个纹理的某个区域,当然也可以从其继承一个类实现。
由于自己工程的需要,原始的被切分body不能放在这儿释放,故做了下特殊处理。
如果要实现爆炸效果,需要在切分完毕后给box2d对象一个冲量,目前设置为{1,1},可根据实际情况修改
zArray为自己的用的array类,可以用类似的类或者直接用数组实现
接口函数为BodyExplosion,此处可以将易做图次数作为参数传入
[cpp]
/*
world: b2world对象
pos:受力点
body:被切分的box2d对象
csx:被切分的cocos2dx对象
*/
void BodyExplosion(b2World *world, b2Vec2 &pos, b2Body* body, CCSprite* csx)
效果
2.易做图代码
2.1 头文件
[cpp]
#ifndef __BodyExplosion_h__
#define __BodyExplosion_h__
#include <Box2D/Box2D.h>
#include "jb2d.h"
#include "cocos2d.h"
#include "zarray.h"
class JoySplitRayCastCallback:public b2RayCastCallback
{
public:
JoySplitRayCastCallback(b2World* pworld, b2Body* body=NULL);
void FloatCompareAccuracy()
{
m_minx-=0.5;
m_miny-=0.5;
m_maxx+=0.5;
m_maxy+=0.5;
}
virtual float32 ReportFixture( b2Fixture* fixture, const b2Vec2& point,
const b2Vec2& normal, float32 fraction);
public:
void splitObj(b2Body* sliceBody, b2Vec2& A, b2Vec2& B);
void resetCB();
void addPoint(b2Body* body, const b2Vec2& p);
void removePoint(b2Body* body);
void CreateBody( b2Body* sliceBody, zArrayT<b2Vec2> &vecs);
bool PointInBody(const b2Vec2& point);
bool CheckClockwise(zArrayT<b2Vec2> &vecs);
public:
b2World* world;
b2Body* clickBody;
bool destroyed;
float m_minx;
float m_miny;
float m_maxx;
float m_maxy;
zArrayT<b2Body*> explodingBodies;
zArrayT<b2Vec2> enterPointsVec;
zArrayT<b2Body*> enterPointsVecBody;
zArrayT<b2Body*> slicedBodies;
};
#endif
2.2 源文件
[cpp]
#define PI 3.141295f
[cpp] view plaincopy
float32 JoySplitRayCastCallback::ReportFixture( b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction )
{
b2Body* body=fixture->GetBody();
if (explodingBodies.find(body) == -1)
{
return 1;
}
int idx=enterPointsVecBody.find(body);
if (idx==-1)
{
addPoint(body, point);
}
else
{
splitObj(fixture->GetBody(), enterPointsVec[idx], (b2Vec2&)point);
}
return 1;
}
float det(float x1, float y1, float x2, float y2, float x3, float y3) {
// This is a function which finds the determinant of a 3x3 matrix.
// If you studied matrices, you'd know that it returns a positive number if three given points are in clockwise order, negative if they are in anti-clockwise order and zero if they lie on the same line.
// Another useful thing about determinants is that their absolute value is two times the face of the 易做图, formed by the three given points.
return x1*y2+x2*y3+x3*y1-y1*x2-y2*x3-y3*x1;
}
int comp1(const void* a1,const void* b1)
{
b2Vec2& a=*(b2Vec2*)a1;
b2Vec2& b=*(b2Vec2*)b1;
// This is a compare function, used in the arrangeClockwise() method - a fast way to arrange the points in ascending order, according to their x-coordinate.
if (a.x*10000>b.x*10000) {
return 1;
}
else if (a.x*10000<b.x*10000) {
return -1;
}
return 0;
}
void arrangeClockwise(zArrayT<b2Vec2>& vec) {
// The algorithm is 易做图:
// First, it arranges all given points in ascending order, according to their x-coordinate.
// Secondly, it takes the leftmost and rightmost points (lets call them C and D), and creates tempVec, where the points arranged in clockwise order will be stored.
// Then, it iterates over the vertices vector, and uses the det() method I talked about earlier. It starts putting the points above CD from the beginning of the vector, and the points below CD from the end of the vector.
// That was it!
int n=vec.count();
float d;
int i1=1,i2=n-1;
zArrayT<b2Vec2> tempVec;
b2Vec2 C;
b2Vec2 D;
qsort(vec.getDataPtr(), vec.count(), sizeof(b2Vec2), comp1);
tempVec.setSize(n);
tempVec[0]=vec[0];
C=vec[0];
D=vec[n-1];
for (int i=1; i<n-1; i++)
{
d=det(C.x,C.y,D.x,D.y,vec[i].x,vec[i].y);
if (d<0) {
tempVec[i1++]=vec[i];
}
else {
tempVec[i2--]=vec[i];
}
}
tempVec[i1]=vec[n-1];
for (int i=0; i<n;
补充:综合编程 , 其他综合 ,