Cocos2d-x   发布时间:2022-05-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Bullet(cocos2dx)学习制作桌球游戏之前期准备大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

使用cocos2dx结合bullet设计一款简陋的桌球游戏,就是为了回顾前期学过的bullet

首先要把桌球游戏需要的基本资源准备好,15个球,1个白球,1张台球桌,球杆可有可无

先看看目前实现的效果



至于这张台球桌的模型,我是随便设计一下


当然这个模型只是为了加载raw文件(静态网格数据),为了使模型的贴图显示出来,

我使用Blender直接创建了一个Plane,然后将台球桌的贴图贴在Plane上,于是就能以假乱真的

实现一个台球桌


在游戏开始前,初始化物理环境,加载一张台球桌,设置相应的物理属性,按规则摆放好台球。

1.设置重力为(0.f,-9.8f,0.f),以模拟真实的物理环境。

_world = PhysicsWorld3D::createWithDebug(this,btVector3(0.f,0.f));

2.加载台球桌

首先将台球桌的贴图模型加载进游戏,设置相应的位置,

然后加载台球桌的物理网格,还记得PhysicisMesh3D吗,并调整好位置,

当然比较不好设置的就是台球桌的物理属性,什么摩擦系数啊,弹性系数啊,滚动摩擦系数啊

void HelloWorld::initTable()
{
	auto tableSprite = Sprite3D::create("ball/table.c3b");
	this->addChild(tableSpritE);
	tableSprite->setPosition3D(Vec3(0.f,-0.57f,0.f));
	tableSprite->setCameraMask(2);

	_tableMesh = PhysicsMesh3D::constuct("table.raw");
	_world->addTriangleMesh(_tableMesh,btVector3(0,0),Physicsmaterial3D(0.f,0.5f,0.2f,0.2f));
}

3.摆放台球

对于15球来说摆放的顺序是这样的,在网上找的规则



黑8放在第三行的中间位置,白色的为全色球,黑色的为花色球。

可以这样设想,只要定义一个数组存放每个位置的球号就行了,

@H_674_107@@H_674_107@BALLS_numbER[0]=1;@H_674_107@

@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[1]=2;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[2]=9;@H_674_107@

@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[3]=10;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[4]=8;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[5]=3;@H_674_107@

@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[6]=4;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[7]=11;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[8]=5;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[9]=12;@H_674_107@

@H_674_107@@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[10]=13;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[11]=6;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[12]=14;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[13]=15;@H_674_107@

@H_674_107@@H_674_107@BALLS_numbER[14]=7;@H_674_107@

@H_674_107@

球号是我自己按照规则随便放的。

下面就是如果将这些球放好,

假设每个球半径为0.57f,球都在Y坐标为0的位置,那么关键就是如何确定每个球的

X,Z.台球摆放好无论多少行都是个等边三角形,以3行为例


先放置第一个球,以后每一行的第一个球都是按照蓝色箭头的方向放置,假设上为Z,右为X

那么第二行第一个球就是(ball[1].posx+ball.radius,ball[1].posZ+3*ball.radius)

设方向向量为dir(ball.radius,3*ball.radius);

ball[2].pos=ball[1].pos+dir

第三行就是ball[3].pos=ball[1].pos+dir*2;

一次类推ball[n].pos=ball[1].pos+dir*(n-1);

对于同一行的第k个球就是同一行的第一个球.pos.x-2*radius;

Sprite3D* ballSprite;
	btrigidBody* ballBody;

	int curnumber = -1;
	float offsetZ = -7.f;
	Vec3 ballPos;
	const Vec3 dir = Vec3(-0.57f,0.f,-0.987269f);

	for (int i=0; i<5; ++i)
	{
		ballPos = dir * i;
		ballPos.x += -1.14f;
		ballPos.z += offsetZ;
		for (int j=0; j<=i; ++j)
		{
			curnumber++;		// 第几个球
			ballPos.x += 1.14f;  // 每行第k个都是上一个球的X+ 2 * radius

			ballSprite = Sprite3D::create("ball/ball.c3b",StringUtils::format("ball/ball_%d.png",BALLS_numbER[curnumber]));
			this->addChild(ballSpritE);
			ballSprite->setPosition3D(ballPos);
			ballSprite->setCameraMask(2);

			ballBody = _world->addSphere(0.57f,btVector3(ballPos.x,ballPos.y,ballPos.z),Physicsmaterial3D(4.2f,0.9f,0.15f));
			ballBody->setUserPointer(ballSpritE);

			_balls.push_BACk(ballBody);
		}
	}

@H_674_107@看上面代码@H_674_107@

Sprite3D::create("ball/ball.c3b",BALLS_numbER[curnumber]));

@H_674_107@根据提前的设计加载相应的球号。@H_674_107@

@H_674_107@

@H_674_107@ballPos=dir*i;@H_674_107@

@H_674_107@ballPos.x+=-1.14f;@H_674_107@

@H_674_107@ballPos.z+=offsetZ;@H_674_107@

@H_674_107@设置每行第一个球的位置@H_674_107@

@H_674_107@

@H_674_107@最后就是加载白球,白球要特别独立出来@H_674_107@

// white ball
	ballSprite = Sprite3D::create("ball/ball.c3b","ball/ball_white.png");
	this->addChild(ballSpritE);
	ballSprite->setPosition3D(Vec3(0.f,5.f));
	ballSprite->setCameraMask(2);
	_whiteBallBody = _world->addSphere(0.57f,5.f),0.15f));
	_whiteBallBody->setUserPointer(ballSpritE);

4.更新物理世界

_world->update(delta);

	float m[16];
	for (auto ballBody : _balls)
	{
		ballBody->getWorldTransform().getOpenGLMatrix(m);
		static_cast<Sprite3D*>(ballBody->getUserPointer())->setNodeToParentTransform(Mat4(m));
	}

	_whiteBallBody->getWorldTransform().getOpenGLMatrix(m);
	static_cast<Sprite3D*>(_whiteBallBody->getUserPointer())->setNodeToParentTransform(Mat4(m));

每一帧都去更新实际上是很浪费资源的,当所有的球都不动时,其实没必要更新,但是只有不到20个球,

性能不会影响,当游戏中出现大量的物体时,就要重载btMotionState,这个以后讨论。

5.测试一下

当点击屏幕是给白球施加一个冲量,记住一定要先唤醒物体,不然不会有效果的

_whiteBallBody->setActivationState(ACTIVE_TAG);

_whiteBallBody->applyCentralImpulse(btVector3(0.f,-60.5f));

总结:

不是美工,模型什么的设计很费劲,贴图都是网上找的。

台球桌,台球的物理属性,调整麻烦,目前调整的还不好

对于添加的Sprite3D一定要设置CameraMask不然是不会被看到的。

添加光照,使物体具有立体感

// light
	auto light = SpotLight::create(Vec3(0,-1.f,0.f),Vec3(0.f,Color3B::WHITE,1000.f);
	light->setPosition3D(Vec3(0.f,100.f,0.f));
	this->addChild(light);
	light->setCameraMask(2);

@L_450_0@

Bullet库的设置方法请参http://www.voidcn.com/article/p-nbqlamce-bkn.html

大佬总结

以上是大佬教程为你收集整理的Bullet(cocos2dx)学习制作桌球游戏之前期准备全部内容,希望文章能够帮你解决Bullet(cocos2dx)学习制作桌球游戏之前期准备所遇到的程序开发问题。

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

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