转载:http://blog.youkuaiyun.com/qq_17749439/article/details/38046633
转载:http://blog.youkuaiyun.com/u012945598/article/details/17787243
Box2dHandler.h
- #include "cocos2d.h"
- #include "Box2D.h"
- #include "GLES-Render.h"
- USING_NS_CC;
- #define PTM_RATIO 32
- class B2Sprite :public CCSprite
- {
- public:
- // static B2Sprite *spriteWithSpriteFrameName(const char*file);
- // bool initWithSpriteFrameName(const char *pszSpriteFrameName);
- // 物理世界的“物体”
- CC_SYNTHESIZE(b2Body*, m_b2Body, B2Body);
- // 是否死去
- // IsDead为true,表示彻底从屏幕上消失
- CC_SYNTHESIZE(bool, m_isDead, IsDead);
- // 是否存活
- // IsAlive为true,则物体存活,代表仍然存在碰撞体积,需要考虑碰撞
- CC_SYNTHESIZE(bool, m_isAlive, IsAlive);
- };
- class Box2dHandler:public CCNode,public b2ContactListener
- {
- public:
- // 用于调试绘图
- GLESDebugDraw *m_debugDraw;
- // 物理世界
- b2World *m_world;
- // 用于保存死亡对象对容器
- // typedef pair<b2Fixture *, b2Fixture *> MyContact;
- // set<MyContact> m_contacts;
- // 初始化物理世界
- bool initBox2D();
- // 设置物体 密度为10
- void addBodyForSprite(B2Sprite *sprite,double density=10.0);
- // 设置夹具 密度为10
- void addFixtureForSprite(B2Sprite *sprite,double density=10.0);
- //此方法用于销毁死亡对象,因为物体不可以则碰撞检测方法中直接销毁,可以中updata函数最后执行
- void dealCollisions();
- // 碰撞检测方法 开始重叠
- virtual void BeginContact(b2Contact *contact);
- // 结束重叠
- virtual void EndContact(b2Contact *contact);
- // 对应碰撞处理对前后时间点
- // virtual void ProSolve(b2Contact *contact,const b2Manifold *oldManifold);
- // virtual void PostSolve(b2Contact *contact,const b2ContactImpulse *impulse);
- static Box2dHandler* handler();
- bool init();
- void draw();
- void update(float dt);
- // void removeSprite(B2Sprite *node);
- // CC_SYNTHESIZE(Box2dHandlerDe, , )
- };
Box2dHandler.cpp
- #include "Box2dHandler.h"
- //把Box2dHandler设置成单例
- Box2dHandler* Box2dHandler::handler()
- {
- static Box2dHandler *handler=NULL;
- if(handler==NULL)
- {
- handler=new Box2dHandler();
- handler->init();
- return handler;
- }
- else
- return handler;
- }
- //Box2dHandler初始化
- bool Box2dHandler::init()
- {
- this->initBox2D();
- this->scheduleUpdate();
- // GLESDebugDraw m_debugDraw(PTM_RATIO);
- // 调试绘图
- m_debugDraw=new GLESDebugDraw(PTM_RATIO);
- uint32 flags=0;
- flags+=b2Draw::e_shapeBit;
- m_debugDraw->SetFlags(flags);
- m_world->SetDebugDraw(m_debugDraw);
- return true;
- }
- //初始化物理引擎
- bool Box2dHandler::initBox2D()
- {
- CCSize s=CCDirector::sharedDirector()->getWinSize();
- // 设置物理世界中的重力xy。
- b2Vec2 gravity;
- gravity.Set(0.0f, -1.0f);
- m_world=new b2World(gravity);
- // 允许睡眠,可以提高物体的处理效率,只有中受到物理效果影响时才会唤醒对象
- m_world->SetAllowSleeping(true);
- // 开启连续物理测试
- // 连续物理测试会使物理模拟时间间隔缩短,提高模拟精度,避免速度较快的两个物体直接穿透
- // 但该方法同样会降低引擎但运行性能
- m_world->SetContinuousPhysics(true);
- // 设置碰撞事件的监听器
- m_world->SetContactListener(this);
- // 定义一个边界范围,存在碰撞效果
- b2BodyDef groundBodyDef;
- groundBodyDef.position.Set(0, 0);
- b2Body *groundBody=m_world->CreateBody(&groundBodyDef);
- // 定义边缘形状
- b2EdgeShape groundBox;
- // 底部
- groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0));
- groundBody->CreateFixture(&groundBox,0);
- // 顶部
- groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));
- groundBody->CreateFixture(&groundBox,0);
- // 左侧
- groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));
- groundBody->CreateFixture(&groundBox,0);
- // 右侧
- groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0));
- groundBody->CreateFixture(&groundBox,0);
- return true;
- }
- //为物理世界但精灵添加夹具
- void Box2dHandler::addFixtureForSprite(B2Sprite *sprite,double density)
- {
- // 定义形状,多边形
- b2PolygonShape spriteShape;
- // 得到精灵的大小
- CCSize size =sprite->getContentSize();
- spriteShape.SetAsBox(size.width/PTM_RATIO/2, size.height/PTM_RATIO/2);
- // 创建一个夹具的对象
- b2FixtureDef spriteShapeDef;
- // 设置夹具的形状
- spriteShapeDef.shape=&spriteShape;
- // 设置夹具的密度
- spriteShapeDef.density=density;
- // 设置精灵物理世界的“物体”的夹具
- b2Body *spriteBody=sprite->getB2Body();
- spriteBody->CreateFixture(&spriteShapeDef);
- }
- //为物理世界的精灵创建Box2D物体
- void Box2dHandler::addBodyForSprite(B2Sprite *sprite,double density)
- {
- // 创建一个物体对象
- b2BodyDef spriteBodyDef;
- // 物体对象--b2Body
- // 静态物体(b2_staticBody)。质量为 0,不可以移动,通常模拟我们游戏的物理边
- // 界:大地、墙壁等。
- // 平台物体(b2_kinematicBody)。按照固定路线运动的物体,比如说电梯,运动的
- // 滚梯,运行的火车等等。
- // 动态物体(b2_dynamicBody)。我们最常见的精灵对象对应的物体。
- // 物体类型为动态物体
- spriteBodyDef.type=b2_dynamicBody;
- spriteBodyDef.position.Set((sprite->getPosition().x)/PTM_RATIO, (sprite->getPosition().y)/PTM_RATIO);
- // 设置用户数据,允许存放一个任意类型的指针向我们自定义的数据
- // 用于将物体与游戏程序关联起来,所有物体的用完数据应指向相同的数据类型
- spriteBodyDef.userData=sprite;
- // 在物理世界中创建物体
- b2Body *spriteBody=m_world->CreateBody(&spriteBodyDef);
- // 为精灵添加物体
- sprite->setB2Body(spriteBody);
- // 为精灵添加夹具
- this->addFixtureForSprite(sprite,density);
- }
- // 更新状态
- void Box2dHandler::update(float dt)
- {
- // 遍历物理世界中的物体
- for(b2Body *b=m_world->GetBodyList();b;b=b->GetNext())
- {
- // 是否没有精灵数据
- if(b->GetUserData()!=NULL)
- {
- B2Sprite *sprite =static_cast<B2Sprite*>(b->GetUserData());
- // b2Vec2 pos=b->GetPosition();
- // b2Vec2 bPosition=b2Vec2(pos.x+sprite->getPosition().x/PTM_RATIO,pos.y+sprite->getPosition().y/PTM_RATIO);
- // sprite->setPosition(ccp(pos.x*PTM_RATIO+sprite->getPosition().x,pos.y*PTM_RATIO+sprite->getPosition().y));
- // float32 bAngle=-CC_DEGREES_TO_RADIANS(sprite->getRotation());
- // b->SetTransform(bPosition, bAngle);
- // // sprite->setRotation(-b->GetAngle()/0.01745329252f);
- sprite->setPosition(ccp(b->GetPosition().x*PTM_RATIO,b->GetPosition().y*PTM_RATIO));
- sprite->setRotation(-CC_RADIANS_TO_DEGREES(b->GetAngle()));
- }
- }
- // Box世界的刷新接口,第一个参数为更新引擎的间隔时间,第二个参数为计算速度,第三个参数为位置时迭代的次数
- m_world->Step(dt, 8, 8);
- //this->dealCollisions();
- }
- //使调试绘图显示到屏幕上
- void Box2dHandler::draw()
- {
- CCNode::draw();
- // 保存opengl绘图状态
- ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position);
- // 用kmGLPushMatrix函数来保存状态
- kmGLPushMatrix();
- // 绘制调试图案
- m_world->DrawDebugData();
- // 用kmGLPopMatrix函数来恢复状态
- kmGLPopMatrix();
- }
- void Box2dHandler::BeginContact(b2Contact *contact)
- {
- printf("开始碰撞");
- }
- void Box2dHandler::EndContact(b2Contact *contact)
- {
- printf("结束碰撞");
- }
- // 获取可视区域大小
- CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
- // 获取可视区域左下角坐标
- CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
- // 创建物理世界
- Box2dHandler *handler =Box2dHandler::handler();
- this->addChild(handler);
- B2Sprite* pSprite =new B2Sprite();
- pSprite->initWithFile("CloseNormal.png");
- pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/1.1 + origin.y));
- handler->addBodyForSprite(pSprite);
- B2Sprite* pSprite2 =new B2Sprite();
- pSprite2->initWithFile("CloseNormal.png");
- pSprite2->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/6 + origin.y));
- handler->addBodyForSprite(pSprite2);
- this->addChild(pSprite);
- this->addChild(pSprite2);
917

被折叠的 条评论
为什么被折叠?



