Cocos2d-x   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Cocos2d-x学习笔记(十二)—— Box2d物理引擎(未完)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

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

关于box2d的基础知识,这里不再详述,详细参http://www.voidcn.com/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/1024

Scene* 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 32

Scene* 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();

// run
director->runWithScene(newBox2dscenE);
下载地址:http://download.csdn.net/detail/u013707014/9016823



HelloBox2d.cpp:

大佬总结

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

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。