首页 > 代码库 > 2.Cocos2dx 3.2中的重力系统Box2D
2.Cocos2dx 3.2中的重力系统Box2D
1添加Box2D相关的库
步骤1:右击项目所在的解决方案à添加—>现有项目àE:\Installed\cocos2d-x-3.2\cocos2d-x-3.2\external\Box2D\proj.win32\Box2D.vcxproj
步骤2:右击项目à生成依赖项à项目依赖项à将关于libBox2D的复选框选中
步骤3:为项目添加libBox2D的库
方法:右击项目à属性à链接器à输入—>附加依赖项à编辑,添加上libBox2d.lib,à确定
案例说明:
1.编写T32.h |
#ifndef__T32_H__ #define__T32_H__
#include"cocos2d.h" USING_NS_CC;
#definewinSizeDirector::getInstance()->getWinSize() #defineCCLogcocos2d::log
#endif |
2.编写TBack.h |
#ifndef__TBack_H__ #define__TBack_H__
#include"T32.h"
classTBack :publicLayer { public: CREATE_FUNC(TBack);
boolinit(); };
#endif |
3编写TBack.cpp |
#include"TBack.h"
boolTBack::init() { Layer::init();
setLocalZOrder(100);
Menu*menu =Menu::create();
MenuItemImage*item =MenuItemImage::create("CloseNormal.png","CloseSelected.png", [](Ref*){ Director::getInstance()->popScene(); });
menu->addChild(item); item->setPosition(winSize.width / 2 - item->getBoundingBox().size.width / 2, item->getBoundingBox().size.height / 2 - winSize.height / 2);
addChild(menu);
returntrue; } |
4.编写T06Box2D.h |
#ifndef__T06Box2D_H__ #define__T06Box2D_H__ #include"T32.h" #include"Box2D/Box2D.h"
classT06Box2D :publicLayer { public: CREATE_FUNC(T06Box2D); boolinit();
b2World*_world; b2Body*_bat; voidupdate(float); };
#endif |
5编写:T06Box2D.cpp |
#include"T06Box2D.h"
#definePTM_RATIO 32.0f
boolT06Box2D::init() { Layer::init();
//创建世界,后面的-9.8表示向下的重力加速度为9.8 //b2Vec2 gravity(0,-9.8f); //这个表示没有重力加速度 b2Vec2gravity(0,0.0f); _world =newb2World(gravity);
{ b2BodyDefdef; //这里是一个动态的body,默认是静态的body def.type = b2_dynamicBody; //设置位置,要转换成重力场中的位置要除以PTM_RATIO def.position.Set(winSize.width / 2 / PTM_RATIO,winSize.height / 2 / PTM_RATIO);
b2Body*body =_world->CreateBody(&def);
//让body受力 body->SetLinearVelocity(b2Vec2(10,20));
//显示body的精灵 Sprite*sprite =Sprite::create("CloseNormal.png"); addChild(sprite); sprite->setPosition(body->GetPosition().x*PTM_RATIO,body->GetPosition().y*PTM_RATIO);
//设置body的形状,让它和sprite相一致,是圆形的 b2CircleShapeshape; //设置半径 shape.m_radius = sprite->getContentSize().width / 2 / PTM_RATIO; //后面的一个参数表示的是密度系数 b2Fixture*fixture =body->CreateFixture(&shape, 1.0f); //设置摩擦系统 fixture->SetFriction(0.0f); //弹性系数 fixture->SetRestitution(1.0f);
//关联body和精灵 body->SetUserData(sprite); }
//加个地板 { b2BodyDefdef; // def.position.Set(0, 0);
b2Body*body =_world->CreateBody(&def); //设置边界类型的形状 b2EdgeShapeshape; //设置地板的开始点和结束点 shape.Set(b2Vec2(0, 0), b2Vec2(winSize.width / PTM_RATIO, 0));
b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);
//设置摩擦系数 fixture->SetFriction(0.0f); //设置弹性系数 fixture->SetRestitution(1.0f); }
//加个天花板 { b2BodyDefdef; def.position.Set(0,winSize.height / PTM_RATIO);
b2Body*body =_world->CreateBody(&def); b2EdgeShapeshape; shape.Set(b2Vec2(0, 0), b2Vec2(winSize.width / PTM_RATIO, 0));
b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);
//摩擦系统 fixture->SetFriction(0.0f); //弹性系数 fixture->SetRestitution(1.0f); }
//左挡板 { b2BodyDefdef; //def.position.Set(0, winSize.height / PTM_RATIO);
b2Body*body =_world->CreateBody(&def); b2EdgeShapeshape; shape.Set(b2Vec2(0, 0), b2Vec2(0,winSize.height / PTM_RATIO));
b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);
fixture->SetFriction(0.0f);//摩擦系统 fixture->SetRestitution(1.0f);//弹性系数 }
//右挡板 { b2BodyDefdef; def.position.Set(winSize.width / PTM_RATIO, 0);
b2Body*body =_world->CreateBody(&def); b2EdgeShapeshape; shape.Set(b2Vec2(0, 0), b2Vec2(0,winSize.height / PTM_RATIO));
b2Fixture*fixture =body->CreateFixture(&shape, 1.0f); //摩擦系数 fixture->SetFriction(0.0f); //弹性系数 fixture->SetRestitution(1.0f); }
//球拍 { b2BodyDefdef; def.position.Set(winSize.width / 2 / PTM_RATIO,winSize.height / 4 / PTM_RATIO);
b2Body*body =_world->CreateBody(&def); _bat =body;
Sprite*sprite =Sprite::create("bat.png"); body->SetUserData(sprite); addChild(sprite); sprite->setPosition(body->GetPosition().x*PTM_RATIO,body->GetPosition().y*PTM_RATIO);
SizebatSize =Size(100,30); Sizecontent =sprite->getContentSize(); sprite->setScale(batSize.width / content.width,batSize.height / content.height);
b2PolygonShapeshape; shape.SetAsBox(batSize.width / 2 / PTM_RATIO,batSize.height / 2 / PTM_RATIO);
b2Fixture*fixture =body->CreateFixture(&shape, 1.0f); //摩擦系统 fixture->SetFriction(0.0f); //弹性系统 fixture->SetRestitution(1.0f);
//touch EventListenerTouchOneByOne*ev =EventListenerTouchOneByOne::create(); ev->onTouchBegan = [](Touch*,Event*){returntrue; }; ev->onTouchMoved = [&](Touch*touch,Event*){ floatdx =touch->getDelta().x / PTM_RATIO;
b2Vec2pos =_bat->GetPosition(); pos.x += dx;
//下面的函数等价于setPosition() _bat->SetTransform(pos, 0); };
_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,this); }
scheduleUpdate(); returntrue; }
voidT06Box2D::update(floatdt) { //时间在流逝 _world->Step(dt, 8, 1);
//遍历这个世界的body b2Body*body =_world->GetBodyList(); while (body) { //设置body相关的精灵的位置 Sprite*sprite = (Sprite*)body->GetUserData(); if (sprite) { sprite->setPosition(body->GetPosition().x*PTM_RATIO,body->GetPosition().y*PTM_RATIO); sprite->setRotation(body->GetAngle()*180.0 / M_PI); }
body =body->GetNext(); } }
|
6.编写TMenu.h |
#ifndef__TMenu_H__ #define__TMenu_H__
#include"T32.h"
classTMenu :publicLayer { public: CREATE_FUNC(TMenu);
boolinit();
boolTouchBegan(Touch*,Event*); };
#endif |
7.编写:TMenu.cpp |
#include"TMenu.h" #include"TBack.h" #include"T01CPP11.h" #include"T02Vector.h" #include"T03Map.h" #include"T04Label.h" #include"T06Box2D.h"
staticconstchar*title[] = { "T01CPP11", "T02Vector", "T03Map", "T04Label", "T06Box2D" };
boolTMenu::init() { Layer::init();
Menu*menu =Menu::create(); addChild(menu);
for (inti = 0;i <sizeof(title) / sizeof(*title); ++i) { MenuItemFont*item =MenuItemFont::create(title[i], [](Ref*sender){
MenuItem*item = (MenuItem*)sender; inti =item->getTag()-1000; Layer*l =NULL;
if (title[i] == "T01CPP11") l =T01CPP11::create(); if (title[i] == "T02Vector")l =T02Vector::create(); if (title[i] == "T03Map")l =T03Map::create(); if (title[i] == "T04Label")l =T04Label::create(); if (title[i] == "T06Box2D")l =T06Box2D::create();
if (l) { TBack*b =TBack::create(); Scene*s =Scene::create(); s->addChild(b); s->addChild(l); Director::getInstance()->pushScene(s); } }); menu->addChild(item); item->setTag(1000 + i); }
menu->alignItemsVertically();
//触摸 autoev =EventListenerTouchOneByOne::create(); #if 0 ev->onTouchBegan = [](Touch*,Event*){ returntrue; }; #endif
//ev->onTouchBegan = std::bind(&TMenu::TouchBegan, this, std::placeholders::_1, std::placeholders::_2);
ev->onTouchBegan = CC_CALLBACK_2(TMenu::TouchBegan,this);
ev->onTouchMoved = [&](Touch*touch,Event*){ setPositionY(getPositionY() + touch->getDelta().y); }; _eventDispatcher->addEventListenerWithSceneGraphPriority(ev,this);
returntrue; }
boolTMenu::TouchBegan(/*TMEnu* this, */Touch*,Event*) { returntrue; } |
8.编写AppDelegate.cpp |
#include"AppDelegate.h" #include"TMenu.h" #include"TBack.h" USING_NS_CC;
AppDelegate::AppDelegate() {
}
AppDelegate::~AppDelegate() { }
boolAppDelegate::applicationDidFinishLaunching() { // initialize director autodirector =Director::getInstance(); autoglview =director->getOpenGLView(); if(!glview) { glview =GLView::create("My Game"); glview->setFrameSize(480, 320); director->setOpenGLView(glview); }
glview->setDesignResolutionSize(480, 320, ResolutionPolicy::EXACT_FIT);
// turn on display FPS director->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don‘t call this director->setAnimationInterval(1.0 / 60);
// create a scene. it‘s an autorelease object autoscene =Scene::create(); scene->addChild(TMenu::create()); scene->addChild(TBack::create());
// run director->runWithScene(scene);
returntrue; }
// This function will be called when the app is inactive. When comes a phone call,it‘s be invoked too voidAppDelegate::applicationDidEnterBackground() { Director::getInstance()->stopAnimation();
// if you use SimpleAudioEngine, it must be pause // SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); }
// this function will be called when the app is active again voidAppDelegate::applicationWillEnterForeground() { Director::getInstance()->startAnimation();
// if you use SimpleAudioEngine, it must resume here // SimpleAudioEngine::getInstance()->resumeBackgroundMusic(); }
|
运行效果: |
2.Cocos2dx 3.2中的重力系统Box2D