当前位置:编程学习 > 网站相关 >>

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 triangle, 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 simple: 
    // 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;

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,