Cocos2d-x学习笔记(十二)—— Box2d物理引擎(未完)

Cocos2d-x学习笔记(十二)—— Box2d物理引擎(未完),第1张

概述这里讲两个Box2d物理引擎的例子,一个新的cocos2d3.x版本,另一个是旧的2.x版。 关于box2d的基础知识,这里不再详述,详细参考:http://www.voidcn.com/article/p-xtkktxxp-gy.html 新版本: HelloNewBox2d.h: #ifndef __HELLONEWBOX2D_H__#define __HELLONEWBOX2D_H__

这里讲两个Box2d物理引擎的例子,一个新的cocos2d3.x版本,另一个是旧的2.x版。

关于Box2d的基础知识,这里不再详述,详细参考:http://www.jb51.cc/article/p-xtkktxxp-gy.html

新版本:

HelloNewBox2d.h:

#ifndef __HELLONEWBox2D_H__#define __HELLONEWBox2D_H__#include "cocos2d.h"#include "Box2D\Box2D.h"using namespace cocos2d;class HelloNewBox2d : public Layer{private:	CCTexture2D* _spriteTexture;public:	HelloNewBox2d();	~HelloNewBox2d();	// there's no 'ID' in cpp,so we recommend returning the class instance pointer	static Scene* createNewBox2dScene();	// Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'ID' in cocos2d-iphone	virtual bool init();	// implement the "static create()" method manually	CREATE_FUNC(HelloNewBox2d);	// 初始化物理引擎设置	voID initSprite();	virtual bool ontouchBegan(cocos2d::touch* touch,cocos2d::Event* event);	voID onacceleration(acceleration* acc,Event* event);	// 在指定位置添加精灵	voID addNewSpriteAtposition(Vec2 p);};#endif // __HELLOWORLD_SCENE_H__


HelloNewBox2d.cpp:

#include "HelloNewBox2d.h"USING_NS_CC;#define SCENERATIO 480/1024Scene* HelloNewBox2d::createNewBox2dScene(){	auto Box2dScene = Scene::create();	// 初始化物理引擎	Box2dScene->initWithPhysics(); 	auto Box2dLayer = HelloNewBox2d::create();	Box2dScene->addChild(Box2dLayer);	return Box2dScene;}HelloNewBox2d::HelloNewBox2d() :_spriteTexture(NulL){}HelloNewBox2d::~HelloNewBox2d(){	// 关闭重力感应	Device::setAccelerometerEnabled(false);}bool HelloNewBox2d::init(){	if (!Layer::init())	{		return false;	}	// 初始化物理引擎  	this->initSprite();	settouchEnabled(true);	return true;}voID HelloNewBox2d::initSprite(){	// 获取精灵纹理缓存	_spriteTexture = Sprite::create("blocks.png")->getTexture();	// 设置添加多点触控监听	auto touchListener = EventListenertouchOneByOne::create();	touchListener->ontouchBegan = CC_CALLBACK_2(HelloNewBox2d::ontouchBegan,this);	_eventdispatcher->addEventListenerWithSceneGraPHPriority(touchListener,this);	// 打开设备重力感应	Device::setAccelerometerEnabled(true);	// 设置重力感应监听	auto accListener = EventListeneracceleration::create(		CC_CALLBACK_2(HelloNewBox2d::onacceleration,this));	_eventdispatcher->addEventListenerWithSceneGraPHPriority(accListener,this);	// 获得OpenGL可见区域的矩形(一般大小为窗口屏幕的大小)	Rect s_visibleRect = Director::getInstance()->getopenGLVIEw()->getVisibleRect();	// 可见区域的中心点(窗口屏幕中心点)	Vec2 vec = Vec2(s_visibleRect.origin.x + s_visibleRect.size.wIDth / 2,s_visibleRect.origin.y + s_visibleRect.size.height / 2);	// 创建节点	auto node = Node::create();	// 设置刚体,且为边框属性	node->setPhysicsBody(PhysicsBody::createEdgeBox(s_visibleRect.size));	node->setposition(vec);	this->addChild(node);}voID HelloNewBox2d::addNewSpriteAtposition(Vec2 p){	// 产生0和1的随机数	int IDx = CCRANDOM_0_1() > .5f ? 0 : 1;	int IDy = CCRANDOM_0_1() > .5f ? 0 : 1;	// 从缓存中获取精灵,并设置添加刚体(考虑屏幕适应性问题)	auto sp = Sprite::createWithTexture(_spriteTexture,Rect(IDx*32.0f*SCENERATIO,IDy*32.0f*SCENERATIO,32.0f*SCENERATIO,32.0f*SCENERATIO));	sp->setPhysicsBody(PhysicsBody::createBox(Size(32.0f*SCENERATIO,32.0f*SCENERATIO)));	this->addChild(sp);	sp->setposition(p);}bool HelloNewBox2d::ontouchBegan(touch* touch,Event* event){	auto location = touch->getLocation();	// 添加新的精灵	addNewSpriteAtposition(location);	return true;}voID HelloNewBox2d::onacceleration(acceleration* acc,Event* event){	static float prevX = 0,prevY = 0;#define kFilterFactor 0.05f	float accelX = (float)acc->x * kFilterFactor + (1 - kFilterFactor)*prevX;	float accelY = (float)acc->y * kFilterFactor + (1 - kFilterFactor)*prevY;	prevX = accelX;	prevY = accelY;	auto v = Vec2(accelX,accelY);	v = v * 200;	// 设置物理世界的重力	this->getScene()->getPhysicsWorld()->setGravity(v);}



旧版本:

HelloBox2d.h:

#ifndef __HELLOBox2D_H__#define __HELLOBox2D_H__#include "cocos2d.h"#include "Box2D\Box2D.h"using namespace cocos2d;class HelloBox2d : public Layer{private:	// 世界,可看做游戏世界	b2World* _world;	CCTexture2D* _spriteTexture;public:	HelloBox2d();	~HelloBox2d();	// there's no 'ID' in cpp,so we recommend returning the class instance pointer	static Scene* createBox2dScene();	// Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'ID' in cocos2d-iphone	virtual bool init();	// implement the "static create()" method manually	CREATE_FUNC(HelloBox2d);	voID setSpriteTexture();	// 初始化物理引擎设置	voID initPhysics();	// 根据传入的数值进行更新	virtual voID update(float dt);	virtual bool ontouchBegan(cocos2d::touch* touch,cocos2d::Event* event);	// 在指定位置添加精灵	voID addNewSpriteAtposition(cocos2d::Vec2 p);};#endif // __HELLOWORLD_SCENE_H__

HelloBox2d.cpp:

#include "HelloBox2d.h"USING_NS_CC;#define PTM_RATIO 32Scene* HelloBox2d::createBox2dScene(){	auto Box2dScene = Scene::create();	auto Box2dLayer = HelloBox2d::create();	Box2dScene->addChild(Box2dLayer);	return Box2dScene;}HelloBox2d::HelloBox2d():_world(NulL){}HelloBox2d::~HelloBox2d(){	CC_SAFE_DELETE(_world);}bool HelloBox2d::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;}voID HelloBox2d::initPhysics(){	Size s = Director::getInstance()->getVisibleSize();	// 重力参数,参数:1、水平方向,正值,重力向左;1、竖直方向,正值,重力向上	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);}voID HelloBox2d::addNewSpriteAtposition(Vec2 p){	// 创建物理引擎精灵对象	auto sprite = Sprite::create("blocks.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(.5f,.5f);	// 夹具定义	b2FixtureDef fixtureDef;	//设置夹具的形状	fixtureDef.shape = &dynamicBox;	//设置密度	fixtureDef.density = 1.0f;	//设置摩擦系数	fixtureDef.friction = 0.3f;	//使用夹具固定形状到物体上		body->CreateFixture(&fixtureDef);}voID HelloBox2d::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()));		}	}}bool HelloBox2d::ontouchBegan(cocos2d::touch* touch,cocos2d::Event* event){	auto loc = touch->getLocation();	addNewSpriteAtposition(loc);	return true;}

效果图:



这里是源代码,由于文件过于庞大,只上传代码部分,复制覆盖项目即可,运行时,在AppDelegate.cpp文件中修改运用的场景即可,两个例子实现的功能一致。

auto Box2dscene = HelloBox2d::createBox2dScene();auto newBox2dscene = HelloNewBox2d::createNewBox2dScene();// rundirector->runWithScene(newBox2dscene);
下载地址:http://download.csdn.net/detail/u013707014/9016823



HelloBox2d.cpp: 总结

以上是内存溢出为你收集整理的Cocos2d-x学习笔记(十二)—— Box2d物理引擎(未完)全部内容,希望文章能够帮你解决Cocos2d-x学习笔记(十二)—— Box2d物理引擎(未完)所遇到的程序开发问题。

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

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存