【麦可网】Cocos2d-X跨平台游戏开发---学习笔记
第二十六课:Cocos2D-X物理引擎之Box2D11-12
=======================================================================================================================================================================
课程目标:
- 学习chipmunk
课程重点:
- chipmuk概念
- chipmuk与BOX2D
- chipmunk常用操作
考核目标:
- 能够使用chipmuk常用操作,完成游戏需求
=======================================================================================================================================================================
一、chipmuk与BOX2D对比
语音方面:
chipmunk用C语言写的
BOX2D用C++写的
功能上:
BOX2D更丰富
删除对象的方式:
chipmunk:调用函数cpSpaceAddPostStepCallback
BOX2D:设置标记
二、实例
HelloChipmunk.h
--------------------------------------------
#pragma once
#include "cocos2d.h"
#include "cocos-ext.h"
#include "chipmunk.h"
using namespace cocos2d::extension;
using namespace cocos2d;
class HelloChipmunk : public cocos2d::CCLayer
{
public:
HelloChipmunk();
~HelloChipmunk();
// 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 menuCallback(CCObject* pSender);
// implement the "static node()" method manually
CREATE_FUNC(HelloChipmunk);
void onEnter();
void initPhysics();
void addNewSpriteAtPosition(CCPoint p);
void update(float dt);
virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
private:
CCTexture2D* m_pSpriteTexture; //精灵贴图
CCPhysicsDebugNode* m_pDebugLayer; //物理引擎DEBUG
cpSpace* m_pSpace; //物理空间
cpShape* m_pWalls[4]; //形状数组(四边)
};
HelloChipmunk.cpp
--------------------------------
#include "HelloChipmunk.h"
USING_NS_CC;
enum{
kTagParentNode = 1,
};
enum{
Z_PHYSICS_DEBUG = 100,
};
CCScene* HelloChipmunk::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
HelloChipmunk *layer = HelloChipmunk::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
HelloChipmunk::HelloChipmunk()
{
}
HelloChipmunk::~HelloChipmunk()
{
for (int i=0; i<4; i++)
{
cpShapeFree(m_pWalls[i]);
}
cpSpaceFree( m_pSpace );
}
bool HelloChipmunk::init()
{
//
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
//使能触摸
setTouchEnabled(true);
setAccelerometerEnabled(true);
//初始化物理引擎
initPhysics();
CCSpriteBatchNode* parent = CCSpriteBatchNode::create("blocks.png");
m_pSpriteTexture = parent->getTexture();
addChild(parent, 0, kTagParentNode);
//添加新精灵
addNewSpriteAtPosition(ccp(200, 200));
//更新
scheduleUpdate();
return true;
}
void HelloChipmunk::menuCallback(CCObject* pSender)
{
}
static void postStepRemove(cpSpace* space, cpShape *shape, void* unused)
{
int* spriteType = (int*)shape->data;
if (*spriteType == 1)
{
//delete
}
}
static int begin(cpArbiter* arb, cpSpace* space, void* unused)
{
cpShape* a;
cpShape* b;
cpArbiterGetShapes(arb, &a, &b);
cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, a, NULL);
return 1; //return 0,不发生碰撞
}
void HelloChipmunk::initPhysics()
{
cpInitChipmunk();
m_pSpace = cpSpaceNew();
m_pSpace->gravity = cpv(0, -100);
m_pWalls[0] = cpSegmentShapeNew( m_pSpace->staticBody,//静态对象
cpv(0, 0),
cpv(480, 0),
0.0f);
m_pWalls[1] = cpSegmentShapeNew( m_pSpace->staticBody,//静态对象
cpv(0, 320),
cpv(480, 320),
0.0f);
m_pWalls[2] = cpSegmentShapeNew( m_pSpace->staticBody,//静态对象
cpv(0, 320),
cpv(0, 0),
0.0f);
m_pWalls[3] = cpSegmentShapeNew( m_pSpace->staticBody,//静态对象
cpv(480, 320),
cpv(480, 0),
0.0f);
for (int i=0; i<4; i++)
{
m_pWalls[i]->e = 1.0f; //摩擦系数等属性
m_pWalls[i]->u = 1.0f;
cpSpaceAddStaticShape(m_pSpace, m_pWalls[i]);
}
//创建debuglayer
m_pDebugLayer = CCPhysicsDebugNode::create(m_pSpace);
this->addChild(m_pDebugLayer, Z_PHYSICS_DEBUG);
//碰撞检测参数2和3指定碰撞类型
cpSpaceAddCollisionHandler(m_pSpace, 1, 1, begin, NULL, NULL, NULL, NULL);
}
void HelloChipmunk::update(float delta)
{
//不使用传进来的参数,因为传进来的参数会根据运行时间而变动
//采用固定每帧计算2次
int steps = 2;
float dt = CCDirector::sharedDirector()->getAnimationInterval()/(float)steps;
for (int i=0; i<steps; i++)
{
cpSpaceStep(m_pSpace, dt);
}
}
void HelloChipmunk::addNewSpriteAtPosition(CCPoint p)
{
int posx, posy;
CCNode* parent = getChildByTag(kTagParentNode);
posx = CCRANDOM_0_1() * 64.0f;
posy = CCRANDOM_0_1() * 64.0f;
posx = (posx % 2) * 32;
posy = (posy % 2) * 32;
int num = 4;
cpVect verts[] = {
cpv(-16,-16),
cpv(-16, 16),
cpv( 16, 16),
cpv( 16,-16),
};
//创建刚体
cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero));
body->p = cpv(p.x, p.y);
cpSpaceAddBody(m_pSpace, body);
//创建形状
cpShape* shape = cpPolyShapeNew(body, num, verts, cpvzero);
shape->e =0.5f; shape->u = 0.5f;
int* tmp = new int;
*tmp = 1;
shape->data = tmp;
shape->collision_type = 1;
cpSpaceAddShape(m_pSpace, shape);
CCPhysicsSprite* sprite = CCPhysicsSprite::createWithTexture(m_pSpriteTexture, CCRectMake(posx, posy, 32, 32));
parent->addChild(sprite);
sprite->setCPBody(body);
sprite->setPosition(p);
}
void HelloChipmunk::onEnter()
{
CCLayer::onEnter();
}
void HelloChipmunk::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
CCSetIterator it;
CCTouch* touch;
for (it=pTouches->begin(); it!=pTouches->end (); it++)
{
touch = (CCTouch*)(*it);
if (!touch)
{
break;
}
CCPoint location = touch->getLocation();
addNewSpriteAtPosition( location );
}
}
===================================================================
总结:
总算把初级教程学习完了,接下来做个简单的游戏。
开心一刻:
毕业后七年,总算接了个大工程,造一根三十米烟囱,工期两个月,造价三十万,不过要垫资。总算在去年年底搞完了。今天人家去验收,被人骂得要死,还没有钱拿!图纸看反了,人家是要挖一口井!
【麦可网】Cocos2d-X跨平台游戏开发---教程下载:http://pan.baidu.com/s/1kTio1Av
【麦可网】Cocos2d-X跨平台游戏开发---笔记系列:http://blog.youkuaiyun.com/qiulanzhu