实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D

实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D,第1张

概述我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用Box2D物理引擎的开发过程,熟悉这些API的使用。这个实例运行后的场景如图所示,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触摸点生成一个新的精灵,精灵的运行自由落体运动。    HelloBox2D实例 使用Box2D引擎进行开发过程,如图12-15所示。下面我们就按照这个步骤介绍一下代码部分。首先看一下看HelloWor 我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用Box2D物理引擎的开发过程,熟悉这些API的使用。这个实例运行后的场景如图所示,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触摸点生成一个新的精灵,精灵的运行自由落体运动。




HelloBox2D实例 使用Box2D引擎进行开发过程,如图12-15所示。下面我们就按照这个步骤介绍一下代码部分。首先看一下看HelloWorldScene.h文件,它的代码如下:
#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"#include "Box2D/Box2D.h"												①#define PTM_RATIO 32													②class HelloWorld : public cocos2d::Layer{	b2World* world;														③public:    static cocos2d::Scene* createScene();    virtual bool init();  	virtual voID update(float dt);												④	virtual bool ontouchBegan(cocos2d::touch* touch,cocos2d::Event* event); 			⑤    CREATE_FUNC(HelloWorld);		voID initPhysics();														⑥	voID addNewSpriteAtposition(cocos2d::Vec2 p);								⑦};#endif // __HELLOWORLD_SCENE_H__


上述第①行代码#include "Box2D/Box2D.h"是引入使用Box2D引擎需要头文件。第②行代码#define PTM_RATIO 32是定义宏PTM_RATIO,PTM_RATIO是屏幕上多少像素为1米,32表示屏幕上32像素表示1米,在Box2D中单位使用MKS公制系统,即:长度单位采用米,质量单位采用千克,时间单位采用秒。
代码第③行world是声明物理世界b2World成员变量。第④行代码是游戏循环函数。第⑤行代码是触摸点击响应函数。第⑥行代码是声明初始化物理引擎函数initPhysics。第⑦行是声明addNewSpriteAtposition函数,是在触摸点创建一个精灵对象。
HelloWorldScene.cpp中HelloWorld::init()函数代码如下:
bool HelloWorld::init(){	if ( !Layer::init() )	{		return false;	}	Size visibleSize = Director::getInstance()->getVisibleSize();	Vec2 origin = Director::getInstance()->getVisibleOrigin();	// 初始化物理引擎	this->initPhysics();													①	settouchEnabled(true);													//设置为单点触摸	settouchMode(touch::dispatchMode::ONE_BY_ONE);								//开始游戏循环	scheduleUpdate();													②	return true;}


上述代码第①行调用initPhysics()函数初始化物理引擎。第②行代码scheduleUpdate()是开始游戏循环,一旦开启游戏循环就会回调HelloWorld::update(float dt)函数。
HelloWorldScene.cpp中初始化物理引擎HelloWorld::initPhysics()函数代码如下:
voID HelloWorld::initPhysics(){	Size s = Director::getInstance()->getVisibleSize();		//重力参数	b2Vec2 gravity; 														①	gravity.Set(0.0f,-10.0f); 												②	//创建世界	world = new b2World(gravity); 											③	// 允许物体是否休眠	world->SetAllowSleePing(true);											④	// 开启连续物理测试	world->SetContinuousPhysics(true);										⑤		//地面物体定义	b2BodyDef groundBodyDef;											⑥	//左下角	groundBodyDef.position.Set(0,0);										⑦	//创建地面物体	b2Body* groundBody = world->CreateBody(&groundBodyDef);						⑧	//定义一个有边的形状	b2EdgeShape groundBox;												⑨	// 底部	groundBox.Set(b2Vec2(0,0),b2Vec2(s.wIDth/PTM_RATIO,0));						⑩	//使用夹具固定形状到物体上	groundBody->CreateFixture(&groundBox,0);									⑪	// 顶部	groundBox.Set(b2Vec2(0,s.height/PTM_RATIO),s.height/PTM_RATIO));						groundBody->CreateFixture(&groundBox,0);										// 左边	groundBox.Set(b2Vec2(0,b2Vec2(0,0));							groundBody->CreateFixture(&groundBox,0);										// 右边	groundBox.Set(b2Vec2(s.wIDth/PTM_RATIO,0)); 									groundBody->CreateFixture(&groundBox,0);									}


代码第①行b2Vec2 gravity是声明重力变量,b2Vec2是一个二维矢量,它的两个属性为浮点数x和y,表示在x轴和y轴方向的矢量。第②行代码gravity.Set(0.0f,-10.0f)是设置矢量值,其中(0.0f,-10.0f)表示只有重力作用物体,-10.0f表示沿着y轴向下。
第③行代码world = new b2World(gravity)是创建物理世界b2World对象,这里采用了new创建物理世界对象,在C++中new关键字分配内存,释放内存是delete关键字。World是成员变量,需要自己释放成员变量一般是在析构函数中释放,代码如下:
HelloWorld::~HelloWorld()
{
CC_SAFE_DELETE(world);
}
其中CC_SAFE_DELETE(world)是安全释放world变量,CC_SAFE_DELETE宏代表安全释放内存。
第④行代码world->SetAllowSleePing(true)是允许物体睡眠与否,如果允许休眠,可以提高物理世界中物体的处理效率,只有在发生碰撞时才唤醒该对象。
第⑤行代码world->SetContinuousPhysics(true)是开启连续物理测试[ 开启连续物理测试,这是因为计算机只能把一段连续的时间分成许多离散的时间点,再对每个时间点之间的行为进行演算,如果时间点的分割不够细致,速度较快的两个物体碰撞时就可能会产生“穿透”现象,开启连续物理将启用特殊的算法来避免该现象。]。
第⑥行代码是声明形状定义(b2BodyDef)变量。第⑦行代码groundBodyDef.position.Set(0,0)是设置形状的位置。第⑧行代码b2Body* groundBody = world->CreateBody(&groundBodyDef)是通过形状定义变量groundBodyDef创建地面物体。
第⑨行代码是声明一个有边形状定义b2EdgeShape变量,第⑩行代码groundBox.Set(b2Vec2(0,0))是设置有边形状的开始位置(0,0)和结束位置(s.wIDth/PTM_RATIO,0),s.wIDth/PTM_RATIO是将像素换算成米。第⑪行代码是使用夹具固定形状到物体上。用类似的函数定义顶部、左边和右边的物体。
HelloWorldScene.cpp中创建精灵HelloWorld::addNewSpriteAtposition函数代码如下:
voID HelloWorld::addNewSpriteAtposition(Vec2 p){    	log("Add sprite %0.2f x %02.f",p.x,p.y);	//创建物理引擎精灵对象	auto sprite = Sprite::create("BoxA2.png");									①	sprite->setposition( Vec2( p.x,p.y) );	this->addChild(sprite);	//物体定义	b2BodyDef bodyDef;													②	bodyDef.type = b2_dynamicBody;											③	bodyDef.position.Set(p.x/PTM_RATIO,p.y/PTM_RATIO);							④	b2Body *body = world->CreateBody(&bodyDef);								⑤	body->SetUserData(sprite);												⑥	// 定义2米见方的盒子形状	b2polygonShape dynamicBox;											⑦	dynamicBox.SetAsBox(1,1);											⑧	// 夹具定义	b2FixtureDef fixtureDef;												⑨	//设置夹具的形状	fixtureDef.shape = &dynamicBox;											⑩	//设置密度	fixtureDef.density = 1.0f;												⑪	//设置摩擦系数	fixtureDef.friction = 0.3f;												⑫	//使用夹具固定形状到物体上		body->CreateFixture(&fixtureDef);										⑬}


上述代码第①行是创建精灵(Sprite)对象,精灵(Sprite)对象与物理引擎物体是没有关系,我们需要在游戏循环函数中更新。
代码第②行是声明动态物体定义变量,代码第③行bodyDef.type = b2_dynamicBody是设置物体类型为动态物体,物体分为静态和动态物体。第④行代码是设置物体的位置,它的单位是米。第⑤行代码b2Body *body = world->CreateBody(&bodyDef)是创建物体对象。第⑥行代码body->SetUserData(sprite)是将精灵放置到物体的UserData属性中,这样便于我们从物体中获取相关联的物体。
第⑦行代码b2polygonShape dynamicBox是声明多边形形状定义变量。第⑧行代码dynamicBox.SetAsBox(1,1)是设置多边形为矩形盒子形状,由于坐标原点在盒子的左下角,SetAsBox是设置盒子的中心为(1,1),那么这个盒子的就是2米见方的大小。
第⑨行代码是b2FixtureDef fixtureDef是声明夹具定义变量。第⑩行代码是设置夹具的形状。第⑪行代码fixtureDef.density = 1.0f是设置形状的密度。第⑫行代码fixtureDef.friction = 0.3f是设置摩擦系数,范围是0.0~1.0之间。第⑬行代码body->CreateFixture(&fixtureDef) 是使用夹具固定形状到物体上,这样物体就有了形状。
HelloWorldScene.cpp中游戏循环函数HelloWorld::update代码如下:
voID HelloWorld::update(float dt){	float timestep = 0.03f; 	int32 veLocityIterations = 8;		int32 positionIterations = 1;		world->Step(timestep,veLocityIterations,positionIterations);	for (b2Body* b = world->GetbodyList(); b; b = b->GetNext())						①	{		if (b->GetUserData() != nullptr) {												Sprite* sprite = (Sprite*)b->GetUserData();				sprite->setposition( Vec2( b->Getposition().x * 				PTM_RATIO,b->Getposition().y * PTM_RATIO) );				sprite->setRotation( -1 * CC_radians_TO_degrees(b->GetAngle()) );		}	}																			②}


其中代码①~②这段代码可以同步物理引擎中的物体与精灵位置和状态。



更多内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》 本书交流讨论网站: http://www.cocoagame.net
更多精彩视频课程请关注智捷课堂Cocos课程: http://v.51work6.com
欢迎加入Cocos2d-x技术讨论群:257760386


《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:

京东:http://item.jd.com/11584534.html

亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

当当:http://product.dangdang.com/23606265.html

互动出版网:http://product.china-pub.com/3770734

《Cocos2d-x实战 C++卷》源码及样章下载地址:

源码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1

样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1

欢迎关注智捷iOS课堂微信公共平台 总结

以上是内存溢出为你收集整理的实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D全部内容,希望文章能够帮你解决实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1001681.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存