第一步在創建場景的時候
該方法一般是在createScene創建cocos2dx模板的這裏
auto scene = Scene::createWithPhysics();
//顯示物理世界調試狀態, 顯示紅色的框, 方便調試
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
//創建顯示場景
auto layer = TestScene::create();
//加入場景
scene->addChild(layer);
return scene;
有了上面的步驟我們就可以在sprite中指定剛體來形成碰撞
普通形狀的剛體
//創建精靈
auto body = Sprite::create("Interface/login.png");
//創建物理引擎中所使用的形狀 這裏創建的是一個矩形
auto geo = PhysicsBody::createBox(body->getContentSize());
//設置精靈的物理形狀爲geo
body->setPhysicsBody(geo);
//添加進場景
scene->addChild(body, 1);
我們這裏創建的剛體是帶有普通物理屬性的剛體 會受到重力影響
當然上面的形狀不止是矩形相關的方法還有
createBox,createCircle,createPolygon具體可以查看cocos2dx官方apicocos2dx官方api
上訴的三個方法創建的形狀都會受到力的影響.
不受力影響的形狀
createEdgeBox 在名字中帶有edge創建的形狀都是不受力影響的
設置創建的剛體受不受力影響
通過調用形狀的方法setGravityEnable來進行設置
false 表示不受力影響否則受力影響
sprite->getPhysicsBody()->setGravityEnable(false);
設置剛體是否可以旋轉
通過方法setRotationEnable來調用
false 表示不能旋轉否則旋轉
sprite->getPhysicsBody()->setRotationEnable(false);
設置剛體的速度
參數是一個二分量的向量 參數一表示x軸速度 ,參數二表示y軸速度 兩個分量合起來表示一個帶方向的速度具體可以看看初中物理知識
sprite->getPhysicsBody()->setVelocity(Vec2(0, 30.0f));
通過圖片來自動生成剛體形狀
第一步要繼承cocos2dx的一個AutoPolygon對象
下面直接上代碼
AutoPolygonUser.h頭文件
#ifndef __AutoPolygonUser_SCENE_H__
#define __AutoPolygonUser_SCENE_H__
#include "cocos2d.h"
#include "ui/CocosGUI.h"
#include "AppDelegate.h"
class AutoPolygonUser :public cocos2d::AutoPolygon {
public:
AutoPolygonUser(const std::string &filename);
~AutoPolygonUser();
float getWidth();
float getHeight();
};
#endif
AutoPolygonUser.cpp源文件 爲原來的對象新增獲取寬度和獲取高度的方法
#include "AutoPolygonUser.h"
USING_NS_CC;
AutoPolygonUser::AutoPolygonUser(const std::string &filename):AutoPolygon(filename){
};
AutoPolygonUser::~AutoPolygonUser() {
}
float AutoPolygonUser::getWidth() {
return _width;
};
float AutoPolygonUser::getHeight() {
return _height;
};
第二步編寫創建形狀的方法
首先聲明該方法
//參數一 要創建精靈的圖片位置 參數二個人理解爲精度
cocos2d::Sprite * createSpritePolygon(const std::string &,float jd=2.0f);
方法實現
cocos2d::Sprite * createSpritePolygon(const std::string & s,float jd) {
//創建精靈
auto sprite1 = Sprite::create(s);
//創建自動獲取形狀的對象
auto pinfo2 = AutoPolygonUser(s);
//實則獲取形狀的矩形
Size size1 = Size(pinfo2.getWidth(), pinfo2.getHeight());
Rect realRect2 = Rect(0, 0, size1.width, size1.height);
//通過調用方法獲取形狀點
std::vector<Vec2> dd = pinfo2.trace(realRect2, jd);
//篩選過濾點
dd = pinfo2.reduce(dd, realRect2, jd);
dd = pinfo2.expand(dd, realRect2, jd);
//創建物理形狀
PhysicsBody* geo;
geo = PhysicsBody::createPolygon(&dd[0], dd.size(), PHYSICSBODY_MATERIAL_DEFAULT, Vec2(-sprite1->getContentSize().width / 2, -sprite1->getContentSize().height / 2));
//設置形狀的偏移位置
geo->setPositionOffset(Vec2(0, 0));
//設置精靈物理屬性 並返回精靈
sprite1->setPhysicsBody(geo);
return sprite1;
};
最終達到的效果是這樣的
可以看到我們的飛機都有了一個基本的輪廓
物理引擎的事件碰撞事件的使用
第一步
必須指定剛體可以接受事件
sprite->getPhysicsBody()->setCategoryBitmask(0x01);
sprite->getPhysicsBody()->setContactTestBitmask(0x01);
sprite->getPhysicsBody()->setCollisionBitmask(0x01);
相關方法的詳細說明可以查看cocos2dx官方文檔
第二步創建事件器
auto dispatcher = Director::getInstance()->getEventDispatcher();
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(GameScene::onContactBegin2, this);
dispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
關於如何在事件中區分是哪一個數據我門可以通過下面的代碼思路
bool GameScene::onContactBegin2(cocos2d::PhysicsContact & contact) {
//獲取碰撞的兩個body剛體
auto bodyA = contact.getShapeA()->getBody();
auto bodyB = contact.getShapeB()->getBody();
//獲取剛體的id可以在創建剛體的時候自動生成一個靜態自增的id
long long a = bodyA->getTag();
long long b = bodyB->getTag();
//然後通過id去場景裏面拿到我們的sprite對象
auto bSprite = this->getChildByTag(b);
auto aSprite = this->getChildByTag(a);
if (aSprite&&bSprite) {
/*
*通過cocos2dx的方法獲取精靈對象的用戶數據
*這裏我定義的用戶數據是一個整數如果有一些用戶數據是需要特別大
*我們可以自己定義一個結構來進行數據的相互通訊
*/
int typeA = *(int *)aSprite->getUserData();
int typeB = *(int *)bSprite->getUserData();
//根據用戶數據做一些相關的事件處理
...
}
//返回false,cocos2dx不會進行默認的物理處理
return true;
}
最後希望大家可以加入遊戲交流羣:859055710