#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "cocos-ext.h" #include "Box2D/Box2D.h" USING_NS_CC; USING_NS_CC_EXT; using namespace std; class HelloWorld : public cocos2d::CCLayer,public b2ContactListener { public: HelloWorld(); ~HelloWorld(); virtual bool init(); static cocos2d::CCScene* scene(); // 重写生命周期函数 virtual void onEnter(); virtual void onEnterTransitionDidFinish(); virtual void onExit(); // 重写CCTargetTouchDelegate virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent); virtual void ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent); // 重写update回调函数 virtual void update(float delta); // 重写Bos2D监听函数 virtual void BeginContact(b2Contact* contact); CREATE_FUNC(HelloWorld); private: b2World *world; b2Body* groundBody; private: void initPhysics(); void addNewSpriteAtPosition(CCPoint &pt); }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" #include "Layer.h" #define PTM_RATIO 30 USING_NS_CC; HelloWorld::HelloWorld() { } HelloWorld::~HelloWorld() { CC_SAFE_DELETE(world); } CCScene* HelloWorld::scene() { CCScene *scene = CCScene::create(); HelloWorld *layer = HelloWorld::create(); scene->addChild(layer); return scene; } bool HelloWorld::init() { if (!CCLayer::init()) { return false; } CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCSprite *sprite = CCSprite::create("HelloWorld.png"); sprite->setPosition(ccp(winSize.width/2.0,winSize.height/2.0)); this->addChild(sprite); // 初始化物理引擎 this->initPhysics(); //开始游戏循环 this->scheduleUpdate(); return true; } void HelloWorld::initPhysics() { CCSize winSize = CCDirector::sharedDirector()->getVisibleSize(); //重力参数 b2Vec2 gravity; gravity.Set(0.0f,-10.0f); //创建世界 world = new b2World(gravity); // 允许物体是否休眠 world->SetAllowSleeping(true); // 开启连续物理测试 world->SetContinuousPhysics(true); // 设置物理碰撞的监听代理 world->SetContactListener(this); //地面物体定义 b2BodyDef groundBodyDef; // 左下角 groundBodyDef.position.Set(winSize.width / 2.0 / PTM_RATIO,winSize.height / 2.0 / PTM_RATIO); // 设置为静态物体 groundBodyDef.type = b2_staticBody; // 创建地面物体 groundBody = world->CreateBody(&groundBodyDef); // 定义一个有边的形状 b2PolygonShape groundBox; // 底部 groundBox.SetAsBox(winSize.width / 2 / PTM_RATIO,b2Vec2(0,-winSize.height / 2 / PTM_RATIO),0); //使用夹具固定形状到物体上 groundBody->CreateFixture(&groundBox,0); // 顶部 groundBox.SetAsBox(winSize.width / 2 / PTM_RATIO,winSize.height / 2 / PTM_RATIO),0); groundBody->CreateFixture(&groundBox,0); // 左边 groundBox.SetAsBox(0,winSize.height / 2 / PTM_RATIO,b2Vec2(-winSize.width / 2 / PTM_RATIO,0),0); // 右边 groundBox.SetAsBox(0,b2Vec2(winSize.width / 2 / PTM_RATIO,0); } void HelloWorld::addNewSpriteAtPosition(CCPoint &pt) { CCLOG("Add sprite x:%0.2f y:%02.f",pt.x,pt.y); //创建物理引擎精灵对象 CCSprite *sprite = CCSprite::create("BoxA.png"); sprite->setPosition(pt); this->addChild(sprite); float sprWidth = sprite->getContentSize().width; float spriHeight = sprite->getContentSize().height; //物体定义 b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(pt.x / PTM_RATIO,pt.y / PTM_RATIO); bodyDef.userData = sprite; b2Body *body = world->CreateBody(&bodyDef); // 定义2米见方的盒子形状 b2PolygonShape dynamicBox; // 注意这里的宽度和高度都是精灵的一半再除以PTM_RATIO dynamicBox.SetAsBox(sprWidth / 2 / PTM_RATIO,spriHeight / 2 / PTM_RATIO); // 夹具定义 b2FixtureDef fixtureDef; //设置夹具的形状 fixtureDef.shape = &dynamicBox; //设置密度 fixtureDef.density = 1.0f; //设置摩擦系数 fixtureDef.friction = 0.3f; //设置弹力系数 fixtureDef.restitution = 0.5f; //使用夹具固定形状到物体上 body->CreateFixture(&fixtureDef); } void HelloWorld::update(float delta) { world->Step(delta,8,3); for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) { if (b->GetType() == b2_dynamicBody) { if (b->GetUserData() != NULL) { CCSprite* sprite = (CCSprite*)b->GetUserData(); sprite->setPosition(ccp(b->GetPosition().x * PTM_RATIO,b->GetPosition().y * PTM_RATIO)); sprite->setRotation(-1 * CC_RADIANS_TO_DEGREES(b->GetAngle())); } } } } void HelloWorld::BeginContact(b2Contact* contact) { if (contact->GetFixtureA()->GetBody() == groundBody || contact->GetFixtureB()->GetBody() == groundBody) { CCLOG("检测到物理碰撞"); } } void HelloWorld::onEnter() { CCLOG("HelloWorld::onEnter"); CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-128,false); CCLayer::onEnter(); } void HelloWorld::onEnterTransitionDidFinish() { CCLOG("HelloWorld::onEnterTransitionDidFinish"); CCLayer::onEnterTransitionDidFinish(); } void HelloWorld::onExit() { CCLOG("HelloWorld::onExit"); CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); CCLayer::onExit(); } bool HelloWorld::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent) { CCPoint pt = pTouch->getLocation(); this->addNewSpriteAtPosition(pt); return true; } void HelloWorld::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent) { } void HelloWorld::ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent) { } void HelloWorld::ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent) { }原文链接:https://www.f2er.com/cocos2dx/343610.html