cocos2dx 4.0物理引擎

試著忘記壹切 提交于 2020-01-26 10:35:43

第一步在创建场景的时候

该方法一般是在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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!