cocos2d-x引擎版本是2.2.0
这篇博客其实不是给给人看的,只是给我自己看的,以便自己熟悉里面的代码
总共6个文件:
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "../../../../external/Box2D/Box2D.h" #include "MyContactListener.h" USING_NS_CC; class HelloWorld : public cocos2d::CCLayer { public: ~ HelloWorld(); // Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp,so we recommend returning the class instance pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); //每一帧的回调(象征时间的推移) void update(float delta); //触摸响应 bool ccTouchBegan(cocos2d::CCTouch* pTouch,cocos2d::CCEvent*pEvent); //触摸中 void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent); //触摸结束 void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent); //获取标签 int GetTagForBody(b2Body *body); //主要描述重力加速度的信息 b2World* _world; //物体球 b2Body * _ball; b2Body * _paddle; //精灵 CCSprite *_ballSprite; CCSprite *_paddleSprite; //鼠标关节 b2MouseJoint *_mouseJoint; //碰撞监听器 MyContactListener *_contackListener; //地面 b2Body *_groudBody; //得分 int _score; }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" #include "GameOverScene.h" USING_NS_CC; #define PTM_RAITO 26.0f //屏幕上的26个像素代表物理世界的1米 CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } void HelloWorld::menuCloseCallback(CCObject* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); #else CCDirector::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif #endif } // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } //获得屏幕大小 CCSize screenSize = CCDirector::sharedDirector()->getWinSize(); CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); //创建小球精灵 _ballSprite = CCSprite::create("ball.png"); _ballSprite->setPosition(ccp(320,200)); this->addChild(_ballSprite); //创建托盘精灵 _paddleSprite = CCSprite::create("button2.PNG"); _paddleSprite->setPosition(ccp(200,50)); this->addChild(_paddleSprite); //创建一个重力加速度是0的世界 _world = new b2World(b2Vec2(0,0)); //定义一个物体 b2BodyDef ballBodyDef; ballBodyDef.type = b2_dynamicBody; //是会运动的 ballBodyDef.position.Set(_ballSprite->getPositionX()/PTM_RAITO,_ballSprite->getPositionY()/PTM_RAITO); //设置位置 ballBodyDef.userData = _ballSprite; //和cocos2d中的精灵进行关联 _ball = _world->CreateBody(&ballBodyDef); //创建它 //设置物理属性 b2CircleShape circle; circle.m_radius = (_ballSprite->getContentSize().width/2)/PTM_RAITO; b2FixtureDef ballFixDef; ballFixDef.shape = &circle;//形状 ballFixDef.density = 10;//密度 ballFixDef.friction = 0;//摩察系数 ballFixDef.restitution = 1;//反弹系数 _ball->CreateFixture(&ballFixDef); //创建地面 b2BodyDef groudBodyDef; groudBodyDef.type = b2_staticBody; groudBodyDef.position.Set(0,0); _groudBody = _world->CreateBody(&groudBodyDef); b2EdgeShape groudShape; groudShape.Set(b2Vec2(0,0),b2Vec2(screenSize.width/PTM_RAITO,0)); b2FixtureDef groudFixDef; groudFixDef.shape = &groudShape; _groudBody->CreateFixture(&groudFixDef); //建立左边墙壁 b2BodyDef leftgroudBodyDef; leftgroudBodyDef.type = b2_staticBody; leftgroudBodyDef.position.Set(0,0); b2Body *leftgroudBody = _world->CreateBody(&leftgroudBodyDef); b2EdgeShape leftgroudShape; leftgroudShape.Set(b2Vec2(0,b2Vec2(0,screenSize.height/PTM_RAITO)); b2FixtureDef leftgroudFixDef; leftgroudFixDef.shape = &leftgroudShape; leftgroudBody->CreateFixture(&leftgroudFixDef); //建立右边墙壁 b2BodyDef rightgroudBodyDef; rightgroudBodyDef.type = b2_staticBody; rightgroudBodyDef.position.Set(0,0); b2Body *rightgroudBody = _world->CreateBody(&rightgroudBodyDef); b2EdgeShape rightgroudShape; rightgroudShape.Set(b2Vec2(screenSize.width/PTM_RAITO,screenSize.height/PTM_RAITO)); b2FixtureDef rightgroudFixDef; rightgroudFixDef.shape = &rightgroudShape; rightgroudBody->CreateFixture(&rightgroudFixDef); //建立上边墙壁 b2BodyDef topgroudBodyDef; topgroudBodyDef.type = b2_staticBody; topgroudBodyDef.position.Set(0,0); b2Body *topgroudBody = _world->CreateBody(&topgroudBodyDef); b2EdgeShape topgroudShape; topgroudShape.Set(b2Vec2(0,screenSize.height/PTM_RAITO),screenSize.height/PTM_RAITO)); b2FixtureDef topgroudFixDef; topgroudFixDef.shape = &topgroudShape; topgroudBody->CreateFixture(&topgroudFixDef); //定义一托盘个物体 b2BodyDef paddleBodyDef; paddleBodyDef.type = b2_dynamicBody; //是会运动的 paddleBodyDef.position.Set(_paddleSprite->getPositionX()/PTM_RAITO,_paddleSprite->getPositionY()/PTM_RAITO); //设置位置 paddleBodyDef.userData = _paddleSprite; //和cocos2d中的精灵进行关联 _paddle = _world->CreateBody(&paddleBodyDef); //创建它 //设置物理属性 b2PolygonShape BoxShape; BoxShape.SetAsBox(_paddleSprite->getContentSize().width/2/PTM_RAITO,_paddleSprite->getContentSize().height/2/PTM_RAITO); b2FixtureDef paddleFixDef; paddleFixDef.shape = &BoxShape;//形状 paddleFixDef.density = 20;//密度 paddleFixDef.friction = 0;//摩察系数 paddleFixDef.restitution = 0;//反弹系数 _paddle->CreateFixture(&paddleFixDef); //开启贞回调动画 this->scheduleUpdate(); //开启触屏 this->setTouchEnabled(true); CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,true); //小球初始冲量 _ball->ApplyLinearImpulse(_ball->GetMass() * b2Vec2(-15,-5),_ball->GetWorldCenter()); //初始化鼠标关节 _mouseJoint = NULL; //创建水平移动关节 b2PrismaticJointDef primaticJointDef; primaticJointDef.Initialize(_world->CreateBody(new b2BodyDef),_paddle,_paddle->GetWorldCenter(),b2Vec2(3.0,0)); _world->CreateJoint(&primaticJointDef); //添加目标 const int padding = 30; int offsetX = 150; for (int i=0; i<4; i++) { //添加经精灵 CCSprite* blockSprite = CCSprite::create("Meta_tiles.png"); blockSprite->setPosition(ccp(offsetX,400)); blockSprite->setTag(3); this->addChild(blockSprite); //创建对应的砖块物理实体 b2BodyDef blockBodyDef; blockBodyDef.type = b2_dynamicBody; //是会运动的 blockBodyDef.position.Set(blockSprite->getPositionX()/PTM_RAITO,blockSprite->getPositionY()/PTM_RAITO); //设置位置 blockBodyDef.userData = blockSprite; //和cocos2d中的精灵进行关联 b2Body* block = _world->CreateBody(&blockBodyDef); //创建它 //设置物理属性 b2PolygonShape blockShape; blockShape.SetAsBox(blockSprite->getContentSize().width/2/PTM_RAITO,blockSprite->getContentSize().height/2/PTM_RAITO); b2FixtureDef blockFixDef; blockFixDef.shape = &blockShape;//形状 blockFixDef.density = 20;//密度 blockFixDef.friction = 0;//摩察系数 blockFixDef.restitution = 0;//反弹系数 block->CreateFixture(&blockFixDef); //左右间隔 offsetX += (padding + blockSprite->getContentSize().width); } //添加碰撞监听器 _contackListener = new MyContactListener; _world->SetContactListener(_contackListener); //得分清零 _score = 0; return true; } //每一帧的回调(象征时间的推移) void HelloWorld::update(float delta) { //物理世界时间推移 _world->Step(delta,6,6); //物理世界的移动反映到cocos2d界面上 //遍历物理世界的物体 for (b2Body *b = _world->GetBodyList(); b; b= b->GetNext()) { if (b->GetUserData()) { //获取该精灵 CCSprite *sp = (CCSprite *)b->GetUserData(); //给小球限速 if (sp == _ballSprite) { b2Vec2 speed = b->GetLinearVelocity(); if (speed.LengthSquared() > 200) { b->SetLinearDamping(1-200/speed.LengthSquared()); } } //先得到物理世界的位置 b2Vec2 physicPos = b->GetPosition(); //设置位置 sp->setPosition(ccp(physicPos.x*PTM_RAITO,physicPos.y*PTM_RAITO)); } } //处理碰撞事件 b2Body *bodyNeedDestroy = NULL; for (vector<contactPeerFix>::iterator it=_contackListener->_contacts.begin(); it!=_contackListener->_contacts.end(); it++) { contactPeerFix curContact = *it; //获取两个碰撞的物体 b2Body* bodyA = curContact.fixA->GetBody(); b2Body* bodyB = curContact.fixB->GetBody(); //获取标签 int tagA = GetTagForBody(bodyA); int tagB = GetTagForBody(bodyB); //小球和地面碰撞 if (bodyA==_ball&&bodyB==_groudBody ||bodyB==_ball&&bodyA==_groudBody) { //游戏失败 CCLog("fail"); CCDirector::sharedDirector()->replaceScene(GameOverScene::sceneWithWin(false)); } else if (bodyA==_ball&&3==tagB ||bodyB==_ball&&3==tagA)//小球碰撞砖块 { CCLog("pengzhuandaozhuankuai"); //需要删除的砖块 bodyNeedDestroy = (bodyA==_ball ? bodyB : bodyA); _score ++; if (_score==4) { CCDirector::sharedDirector()->replaceScene(GameOverScene::sceneWithWin(true)); } } } //需要删除的砖块 if (bodyNeedDestroy != NULL) { //消除对应的方砖精灵 ((CCSprite*)bodyNeedDestroy->GetUserData())->removeFromParentAndCleanup(true); //从物理世界消除方砖 _world->DestroyBody(bodyNeedDestroy); } } //析构函数 HelloWorld::~HelloWorld() { } //触摸响应 bool HelloWorld::ccTouchBegan(CCTouch* pTouch,CCEvent*pEvent) { //触摸从而加速小球 // CCPoint touchPos = pTouch->getLocation(); // b2Vec2 touchPhysicsPos(touchPos.x/PTM_RAITO,touchPos.y/PTM_RAITO); // b2Vec2 ballPhysics = _ball->GetPosition(); // b2Vec2 impulse = touchPhysicsPos - ballPhysics; // // //冲量等于 = 质量 * 矢量 // impulse *= _ball->GetMass(); // //第二个参数表示作用在质心上 // _ball->ApplyLinearImpulse(impulse,_ball->GetWorldCenter()); //CCLog("ccTouchBegan"); //获取触摸点 CCPoint touchPos = pTouch->getLocation(); b2Vec2 touchPhysicsPos(touchPos.x/PTM_RAITO,touchPos.y/PTM_RAITO); //得到底座的形状信息 b2Fixture* paddleFix = _paddle->GetFixtureList(); if (paddleFix->TestPoint(touchPhysicsPos)) { //创建鼠标关节,引领托盘移动 b2MouseJointDef mouseJointDef; mouseJointDef.bodyA = _world->CreateBody(new b2BodyDef); mouseJointDef.bodyB = _paddle; mouseJointDef.maxForce = 1000.0 * _paddle->GetMass(); mouseJointDef.target = touchPhysicsPos;//设置物理目标位置 _mouseJoint = (b2MouseJoint *)_world->CreateJoint(&mouseJointDef); return true; } return false; } //触摸中 void HelloWorld::ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent) { //CCLog("ccTouchMoved"); if (_mouseJoint) { //获取触摸点 CCPoint touchPos = pTouch->getLocation(); b2Vec2 touchPhysicsPos(touchPos.x/PTM_RAITO,touchPos.y/PTM_RAITO); //设置目标位置 _mouseJoint->SetTarget(touchPhysicsPos); } } //触摸结束 void HelloWorld::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent) { //CCLog("ccTouchEnded"); if (_mouseJoint) { //销毁关节 _world->DestroyJoint(_mouseJoint); _mouseJoint = NULL; } } //获取标签 int HelloWorld::GetTagForBody(b2Body *body) { if (body->GetUserData()) { CCSprite *sp = (CCSprite *)body->GetUserData(); return sp->getTag(); } return -1; }
#pragma once #include "../../../../external/Box2D/Box2D.h" #include <vector> using namespace std; struct contactPeerFix { b2Fixture *fixA; b2Fixture *fixB; }; class MyContactListener : public b2ContactListener { public: MyContactListener(void); ~MyContactListener(void); //储存所有碰撞 vector<contactPeerFix> _contacts; void BeginContact(b2Contact* contact); void EndContact(b2Contact* contact); //void PreSolve(b2Contact* contact,const b2Manifold* oldManifold); //void PostSolve(b2Contact* contact,const b2ContactImpulse* impulse); };
#include "MyContactListener.h" MyContactListener::MyContactListener(void) : _contacts() { } MyContactListener::~MyContactListener(void) { } //开始撞击 void MyContactListener::BeginContact( b2Contact* contact ) { contactPeerFix contactFix = {contact->GetFixtureA(),contact->GetFixtureB()}; _contacts.push_back(contactFix); } //结束撞击 void MyContactListener::EndContact( b2Contact* contact ) { contactPeerFix peer = {contact->GetFixtureA(),contact->GetFixtureB()}; vector<contactPeerFix>::iterator pos,posFound; for (pos=_contacts.begin(); pos!=_contacts.end(); pos++) { contactPeerFix onePeer = *pos; if (onePeer.fixA==peer.fixA && onePeer.fixB==peer.fixB) { posFound = pos; _contacts.erase(posFound); return ; } } }
#pragma once #include "cocos2d.h" USING_NS_CC; class GameOverScene : public CCLayer { public: //初始化 bool initWithWin(bool isWin); //创建场景 static CCScene* sceneWithWin(bool isWin); };
#include "GameOverScene.h" //初始化 bool GameOverScene::initWithWin( bool isWin ) { //父类初始化 if (!CCLayer::init()) { return false; } //显示字符串 char words[64]; if (!isWin) { sprintf(words,"you xi shi bai!"); } else { sprintf(words,"you xi cheng gong!"); } CCLabelTTF *lable = CCLabelTTF::create(words,"Arial",30); lable->setPosition(ccp(320,300)); this->addChild(lable); return false; } //创建场景 CCScene* GameOverScene::sceneWithWin( bool isWin ) { CCScene* sc = CCScene::create(); GameOverScene *layer = new GameOverScene; layer->initWithWin(isWin); sc->addChild(layer); return sc; }