cocos2d-x中box2d的關節
// // HelloWorldScene.cpp // Box2dDemo // // Created by gaocong on 13-6-24. // Copyright __MyCompanyName__ 2013年. All rights reserved. // #include "HelloWorldScene.h" #include "SimpleAudioEngine.h" #include "GLES-Render.h" using namespace cocos2d; using namespace CocosDenshion; #define PTM_RATIO 32 enum { kTagParentNode = 1, }; PhysicsSprite::PhysicsSprite() : m_pBody(NULL) { } void PhysicsSprite::setPhysicsBody(b2Body * body) { m_pBody = body; } // this method will only get called if the sprite is batched. // return YES if the physics values (angles, position ) changed // If you return NO, then nodeToParentTransform won't be called. bool PhysicsSprite::isDirty(void) { return true; } //returns the transform matrix according the Chipmunk Body values //CCAffineTransform PhysicsSprite::nodeToParentTransform(void) //{ // b2Vec2 pos = m_pBody->GetPosition(); // // float x = pos.x * PTM_RATIO; // float y = pos.y * PTM_RATIO; // // if ( isIgnoreAnchorPointForPosition() ) { // x += m_tAnchorPointInPoints.x; // y += m_tAnchorPointInPoints.y; // } // // // Make matrix // float radians = m_pBody->GetAngle(); // float c = cosf(radians); // float s = sinf(radians); // // if( ! CCPoint::CCPointEqualToPoint(m_tAnchorPointInPoints, CCPointZero) ){ // x += c*-m_tAnchorPointInPoints.x + -s*-m_tAnchorPointInPoints.y; // y += s*-m_tAnchorPointInPoints.x + c*-m_tAnchorPointInPoints.y; // } // // // Rot, Translate Matrix // m_tTransform = CCAffineTransformMake( c, s, // -s, c, // x, y ); // // return m_tTransform; //} HelloWorld::HelloWorld() { setTouchEnabled( true ); setAccelerometerEnabled( true ); CCSize s = CCDirector::sharedDirector()->getWinSize(); // init physics this->initPhysics(); CCSpriteBatchNode *parent = CCSpriteBatchNode::create("blocks.png", 100); m_pSpriteTexture = parent->getTexture(); addChild(parent, 0, kTagParentNode); // addDynamicBody(ccp(s.width/2, s.height/2)); // addDistanceJoint(ccp(s.width/2, s.height/2)); // addRevoluteJoint(ccp(s.width/2, s.height/2)); // addPrismaticJoint(ccp(s.width/2, s.height/2)); // addPulleyJoint(ccp(s.width/2, s.height/2)); addGearJoint(ccp(s.width/2, s.height/2)); CCLabelTTF *label = CCLabelTTF::create("Tap screen", "Marker Felt", 32); addChild(label, 0); label->setColor(ccc3(0,0,255)); label->setPosition(ccp( s.width/2, s.height-50)); scheduleUpdate(); } HelloWorld::~HelloWorld() { delete world; world = NULL; //delete m_debugDraw; } void HelloWorld::initPhysics() { CCSize s = CCDirector::sharedDirector()->getWinSize(); b2Vec2 gravity; gravity.Set(0.0f, -10.0f); world = new b2World(gravity); // Do we want to let bodies sleep? world->SetAllowSleeping(true); world->SetContinuousPhysics(true); world->SetContactListener(this); GLESDebugDraw* m_debugDraw = new GLESDebugDraw( PTM_RATIO ); world->SetDebugDraw(m_debugDraw); uint32 flags = 0; flags += b2Draw::e_shapeBit; flags += b2Draw::e_jointBit; flags += b2Draw::e_aabbBit; flags += b2Draw::e_pairBit; flags += b2Draw::e_centerOfMassBit; m_debugDraw->SetFlags(flags); // Define the ground body. b2BodyDef groundBodyDef; groundBodyDef.position.Set(0, 0); // bottom-left corner // Call the body factory which allocates memory for the ground body // from a pool and creates the ground box shape (also from a pool). // The body is also added to the world. groundBody = world->CreateBody(&groundBodyDef); // Define the ground box shape. b2EdgeShape groundBox; // bottom groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0)); groundBody->CreateFixture(&groundBox,0); // top groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO)); groundBody->CreateFixture(&groundBox,0); // left groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0)); groundBody->CreateFixture(&groundBox,0); // right groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0)); groundBody->CreateFixture(&groundBox,0); } void HelloWorld::draw() { // // IMPORTANT: // This is only for debug purposes // It is recommend to disable it // CCLayer::draw(); ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); kmGLPushMatrix(); world->DrawDebugData(); kmGLPopMatrix(); } b2Body * HelloWorld::addNewSpriteAtPositionAndType(CCPoint p, b2BodyType type) { b2BodyDef bodyDef; bodyDef.type = type; bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO); b2Body *body = world->CreateBody(&bodyDef); // Define another box shape for our dynamic body. b2PolygonShape dynamicBox; dynamicBox.SetAsBox(.5f, .5f);//These are mid points for our 1m box // Define the dynamic body fixture. b2FixtureDef fixtureDef; fixtureDef.shape = &dynamicBox; fixtureDef.density = 1.0f; fixtureDef.friction = 0.3f; body->CreateFixture(&fixtureDef); bodyAddSprite(body); return body; } //在body上新增精靈 void HelloWorld::bodyAddSprite(b2Body * body) { CCNode* parent = getChildByTag(kTagParentNode); //We have a 64x64 sprite sheet with 4 different 32x32 images. The following code is //just randomly picking one of the images int idx = (CCRANDOM_0_1() > .5 ? 0:1); int idy = (CCRANDOM_0_1() > .5 ? 0:1); PhysicsSprite *sprite = new PhysicsSprite(); sprite->initWithTexture(m_pSpriteTexture, CCRectMake(PTM_RATIO * idx,PTM_RATIO * idy,PTM_RATIO,PTM_RATIO)); sprite->autorelease(); parent->addChild(sprite); sprite->setPosition( CCPointMake( body->GetPosition().x, body->GetPosition().y) ); sprite->setPhysicsBody(body); body->SetUserData(sprite); } //距離關節 void HelloWorld::addDistanceJoint(CCPoint p) { b2Body *body = addNewSpriteAtPositionAndType(p, b2_staticBody); b2Body *body2 = addNewSpriteAtPositionAndType(ccpAdd(p, ccp(PTM_RATIO, PTM_RATIO)), b2_dynamicBody); b2DistanceJointDef jointDef; //方法一 jointDef.Initialize(body, body2, body->GetWorldCenter(), body2->GetWorldCenter()); //方法二 // jointDef.bodyA = body; // jointDef.bodyB = body2; // jointDef.length = 2; world->CreateJoint(&jointDef); } //旋轉關節 void HelloWorld::addRevoluteJoint(CCPoint p) { b2Body *body = addNewSpriteAtPositionAndType(p, b2_staticBody); b2Body *body2 = addNewSpriteAtPositionAndType(ccpAdd(p, ccp(PTM_RATIO, PTM_RATIO)), b2_dynamicBody); b2RevoluteJointDef jointDef; jointDef.Initialize(body, body2, body2->GetWorldCenter()); jointDef.lowerAngle = -0.25f * b2_pi; // -45 degrees jointDef.upperAngle = 0.5f * b2_pi; // 90 degrees jointDef.enableLimit = true; jointDef.maxMotorTorque = 10.0f; jointDef.motorSpeed = 1.0f; jointDef.enableMotor = true; world->CreateJoint(&jointDef); } //移動關節 void HelloWorld::addPrismaticJoint(CCPoint p) { b2Body *body = addNewSpriteAtPositionAndType(p, b2_staticBody); b2Body *body2 = addNewSpriteAtPositionAndType(ccpAdd(p, ccp(PTM_RATIO, -PTM_RATIO)), b2_dynamicBody); b2PrismaticJointDef jointDef; b2Vec2 worldAxis(1.0f, -1.0f);//可以移動的方向 jointDef.Initialize(body, body2, body2->GetWorldCenter(), worldAxis); jointDef.lowerTranslation = -2.0f; jointDef.upperTranslation = 4.0f; jointDef.enableLimit = true; jointDef.motorSpeed = 0.0f; jointDef.enableMotor = true; world->CreateJoint(&jointDef); } //滑輪關節 void HelloWorld::addPulleyJoint(CCPoint p) { b2Body *body = addNewSpriteAtPositionAndType(p, b2_dynamicBody); b2Body *body2 = addNewSpriteAtPositionAndType(ccpAdd(p, ccp(PTM_RATIO, -PTM_RATIO)), b2_dynamicBody); b2Vec2 anchor1 = body->GetWorldCenter(); b2Vec2 anchor2 = body2->GetWorldCenter(); b2Vec2 groundAnchor1(anchor1.x, anchor1.y + 2.0f);//滑輪的位置 b2Vec2 groundAnchor2(anchor2.x, anchor2.y + 4.0f); float32 ratio = 0.5f;//比率 b2PulleyJointDef jointDef; jointDef.Initialize(body, body2, groundAnchor1, groundAnchor2, anchor1, anchor2, ratio); world->CreateJoint(&jointDef); } //齒輪關節 void HelloWorld::addGearJoint(CCPoint p) { b2Body *body = addNewSpriteAtPositionAndType(p, b2_dynamicBody); b2Body *body2 = addNewSpriteAtPositionAndType(ccpAdd(p, ccp(PTM_RATIO, 0)), b2_dynamicBody); //通過地面生成一個旋轉關節 b2RevoluteJointDef jd1; jd1.bodyA = groundBody; jd1.bodyB = body; jd1.localAnchorA = groundBody->GetLocalPoint(body->GetPosition()); jd1.localAnchorB = body->GetLocalPoint(body->GetPosition()); jd1.referenceAngle = body->GetAngle() - groundBody->GetAngle(); b2RevoluteJoint* joint1 = (b2RevoluteJoint*)world->CreateJoint(&jd1); //通過地面生成一個移動關節 b2PrismaticJointDef jd3; jd3.Initialize(groundBody, body2, body2->GetPosition(), b2Vec2(0.0f, 1.0f)); jd3.lowerTranslation = -5.0f; jd3.upperTranslation = 5.0f; jd3.enableLimit = true; b2PrismaticJoint *joint2 = (b2PrismaticJoint*)world->CreateJoint(&jd3); //通過旋轉關節和移動關節生成一個齒輪關節 b2GearJointDef jointDef3; jointDef3.bodyA = body; jointDef3.bodyB = body2; jointDef3.joint1 = joint1; jointDef3.joint2 = joint2; jointDef3.ratio = 4.0f;//比率 world->CreateJoint(&jointDef3); } void HelloWorld::BeginContact(b2Contact* contact) { CCSprite * sp1 = (CCSprite *)contact->GetFixtureA()->GetBody()->GetUserData(); CCSprite * sp2 = (CCSprite *)contact->GetFixtureB()->GetBody()->GetUserData(); if (sp1 != NULL && sp2 != NULL) { sp1->setColor(ccRED); sp2->setColor(ccRED); } } void HelloWorld::update(float dt) { //It is recommended that a fixed time step is used with Box2D for stability //of the simulation, however, we are using a variable time step here. //You need to make an informed choice, the following URL is useful //http://gafferongames.com/game-physics/fix-your-timestep/ int velocityIterations = 8; int positionIterations = 1; // Instruct the world to perform a single step of simulation. It is // generally best to keep the time step and iterations fixed. world->Step(dt, velocityIterations, positionIterations); //Iterate over the bodies in the physics world for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) { if (b->GetUserData() != NULL) { //Synchronize the AtlasSprites position and rotation with the corresponding body CCSprite* myActor = (CCSprite*)b->GetUserData(); myActor->setPosition( CCPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO) ); myActor->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) ); } } } //滑鼠關節 void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) { CCTouch * touch = (CCTouch*)pTouches->anyObject(); //判斷滑鼠是否點在了剛體上。 CCPoint mousePt = touch->getLocation(); b2Body *pBody = world->GetBodyList();//獲得所有剛體 for(; pBody != NULL; pBody = pBody->GetNext()) { b2Fixture *pFixture = pBody->GetFixtureList();//獲的每個剛體的所有Fixture,因為類似於ground就有好幾個Fixture for(;pFixture != NULL;pFixture = pFixture->GetNext()) { b2Vec2 mouseVec; mouseVec.Set(mousePt.x/PTM_RATIO, mousePt.y/PTM_RATIO); if(pFixture->TestPoint(mouseVec))//判斷滑鼠點是否在這個剛體上 { //建立滑鼠關節. b2MouseJointDef md; md.bodyA=groundBody;//一般為世界邊界 md.bodyB=pBody;//需要拖動的物體 md.target=mouseVec;//指定拖動的座標 md.collideConnected=true; //是否進行碰撞檢測 md.maxForce=1000.0f*pBody->GetMass(); //給一個拖動的力 mouseJoint=(b2MouseJoint*)world->CreateJoint(&md);//建立 pBody->SetAwake(true);//將剛體喚醒,原來可能睡眠了,會少一幀 return ; } } } } void HelloWorld::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) { if(mouseJoint == NULL ) return; CCTouch * touch = (CCTouch*)pTouches->anyObject(); b2Vec2 vecMouse; vecMouse.Set((touch->getLocation().x)/PTM_RATIO, (touch->getLocation().y)/PTM_RATIO); //控制滑鼠關節,改變關節位置. mouseJoint->SetTarget(vecMouse); } void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event) { //銷燬關節. if(mouseJoint != NULL) { world->DestroyJoint(mouseJoint); mouseJoint = NULL; } // //Add a new body/atlas sprite at the touched location // CCSetIterator it; // CCTouch* touch; // // for( it = touches->begin(); it != touches->end(); it++) // { // touch = (CCTouch*)(*it); // // if(!touch) // break; // // CCPoint location = touch->getLocationInView(); // // location = CCDirector::sharedDirector()->convertToGL(location); // // addNewSpriteAtPositionAndType( location, b2_dynamicBody ); // } } CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // add layer as a child to scene CCLayer* layer = new HelloWorld(); scene->addChild(layer); layer->release(); return scene; }
相關推薦
cocos2d-x中box2d的關節
// // HelloWorldScene.cpp // Box2dDemo // // Created by gaocong on 13-6-24. // Copyright __MyCompanyName__ 2013年. All rights reserved
實例介紹Cocos2d-x中Box2D物理引擎:碰撞檢測
函數實現 pda creates pty blank oid rtu and 重構 在Box2D中碰撞事件通過實現b2ContactListener類函數實現,b2ContactListener是Box2D提供的抽象類,它的抽象函數:virtual void BeginC
實例介紹Cocos2d-x中Box2D物理引擎:HelloBox2D
pre all align 討論 響應 算法 站點 virtual origin 我們通過一個實例介紹一下。在Cocos2d-x 3.x中使用Box2D物理引擎的開發過程,熟悉這些API的使用。這個實例執行後的場景如圖所看到的,當場景啟動後,玩家能夠觸摸點擊屏幕,每次觸
例項介紹Cocos2d-x中Box2D物理引擎:碰撞檢測
在Box2D中碰撞事件通過實現b2ContactListener類函式實現,b2ContactListener是Box2D提供的抽象類,它的抽象函式:virtual void BeginContact(b2Contact* contact)。兩個物體開始接觸時會響應,但只調用
Cocos2d-x中Vector<T>容器以及實例介紹
top 宋體 hello 操作符 模板類 log ins bsp main Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容納的是Ref及子類所創建的對象指針,其中的T是模板,表示能夠放入到容器中的類型,在Cocos2d-x 3.x
cocos2d-x 中XML解析與數據存儲
lba false 網上 unsigned failed popu new ccm cfile 一不小心就玩了一周的遊戲了。哎。玩的時候時間過得總是這麽快。。。 於是今天決定看一下之前不怎麽非常熟悉的XML;(之前做遊戲時數據的儲存用到過XML,但這塊是還有一個同事在做
linux下開發,解決cocos2d-x中編譯出現的一個小問題, undefined reference to symbol 'pthread_create@@GLIBC_2.2.5'
water span x86 code bject data- ace 技術分享 inux 解決cocos2d-x中編譯出現的一個小問題 對於cocos2d-x 2.×中編譯中,若頭文件裏引入了#include "cocos-ext.h",在進行C++編譯的時候會遇到例
Cocos2d-X中Menu的綜合運用
cond edi ros log 程序 cal coo 項目 綜合 今天將曾經寫的代碼和項目集成到了一個菜單中,能夠通過菜單切換到曾經做的項目 程序的project文件夾 主要代碼分析: LessonMenu.h中實現創建菜單,遍歷菜單通過菜單切換
Cocos2d-X中的聲音和音效
循環 volume tid ng- cocos2d pop sin 返回值 source 在玩遊戲時都會有各種遊戲音,如啟動遊戲時會有背景音,勝利或者失敗會有一些音效。在Cocos2d-X中能夠使用CocosDenshion實現各種聲音 在使用CocosDensh
cocos2d-x 中選單類
選單相關類包含:選單類和選單項類,選單類圖,從類圖可見Menu類繼承於Layer。 選單項類圖,從圖中可見所有的選單項都是從BaseMenuItem繼承而來的,BaseMenuItem是抽象類,具體使用時是使用它的6個子類。 說明如下: MenuItem 最基本的選單
Cocos2d-x中的4種佈局
Cocos2d-x中一共有4種佈局:ABSOLUTE(絕對佈局)、HORIZONTAL(水平佈局)、VERTICAL(垂直佈局)和RELATIVE(相對佈局)。 注意,只有在絕對佈局內部,元件使用setPosition()方法來指定其位置。另外三種佈局中的元件,setP
卡通渲染Cocos2d-x中的實現(描邊與對物體表面顏色的色階化)
卡通渲染Cocos2d-x中的實現 在一些型別的遊戲中,使用卡通渲染能夠將原有模型的一些細節剝離,使原本比較寫實的模型變得卡通化。在這裡,我向大家介紹簡單介紹一下如何在Cocos2d-x中實現卡通渲染。 事實上,卡通渲染具體來說,可以分為兩個部分:描邊與對物體表面顏色的
cocos2d-x中解決點選事件上層響應,下層不響應
解決方案是重寫一個Layer,加在上下層中間,即可只響應上層事件,阻斷了下層的事件,設定優先順序,程式碼如下 #ifndef _TouchBlockLayer_H_ #define _TouchBlockLayer_H_ class TouchBlockLayer:
Cocos2d-x 中的Sleep 和USleep
Cocos2d-x跨平臺,但是這個Sleep延時需要區分平臺 (不知道是不是我自己沒有找到),還是
Cocos2d-x中Vector容器以及例項介紹
Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容納的是Ref及子類所建立的物件指標,其中的T是模板,表示能夠放入到容器中的型別,在Cocos2d-x 3.x中T表
Cocos2d-x中替換動畫(Armature)中的節點與粒子
Cocos2d-x遊戲開發中常用到骨骼動畫Armature,Armature不僅佔用資源不大(相對於幀動畫來說),而且還能新增幀事件,它還自帶有動畫的播放、停止、迴圈事件等。 廢話少說,直入主題。拿到一個骨骼動畫的時候,我們往往會有這樣的需求:在情況A
Cocos2d-x 中載入骨骼動畫資源
Cocos Studio是一套基於Cocos2d-x的免費遊戲開發工具集,它能幫助開發者快速建立遊戲資源,將大部分繁瑣的遊戲開發工作使用編輯器來快速製作,進一步幫助遊戲開發者減短開發週期、提高開發效率。 Cocos Studio本身不光只是針對骨骼動畫的編輯而設計的,它還提供了UI、場景和資料等資訊的編
cocos2d-x中的動作分析
在cocos2d-x中動作的執行排程是受cocos2d-x的全域性定時器控制的,當初始完導演後便已經啟動用於管理動作的update定時器。 bool CCDirector::init(void) { ... m_pActionManager = new CCAct
談一談Cocos2d-x中的某些“大小”
這裡說的“大小”,包括了以下一些內容: (1).視窗的大小 (2).解析度的大小 (3).影幕的大小 (4).視口的大小 (5).裁剪區域的大小 我們先來看(1),視窗的大小 視窗的大小,即是Windows窗體大小。我們以HelloCpp為例,開啟main.cpp,。找到
cocos2d-x中場景間的引數保持和傳遞(方法整理)
有時為了在場景間傳遞引數,象一些狀態資訊比如音樂的AudioID等,整理一下場景間引數傳遞的方式 方式一、使用全域性變數 利用全域性變數的方式對變數進行場景間的傳遞,簡單且粗暴。可以定義一個類專門來存放需要傳遞的引數,在各場景類中只需要include一下就可以直接對全域性變