cocos2d-x 粒子系统例子 Rocket Through

游戏出自《Cocos2d-X by Example Beginner's Guide》第5章。


效果图:



这游戏的玩法:

首先点在火箭上,再拖动任意位置,就画成一条直线,火箭就会绕着旋转。

要吃发光的黄色星星就会得分,火箭碰到行星或者彗星都会爆炸,右边的橙色进度条掉完也会爆炸。

点评:

这游戏非常难,我还不会玩,黄色的星星出现在上面,要控制火箭以圆形方式过去非常难。


1.cocos2d-x中的粒子系统


如果不深入了解粒子系统的话,就单单使用是非常简单的。粒子给游戏增色不少。cocos2d-x中的粒子一般用"ParticleDesigner"这软件创建,是Mac系统的,暂时没用过。



如何在游戏中使用呢?非常简单,看下面的代码。


//创建
	CCParticleSystem *_comet = CCParticleSystemQuad::create("comet.plist");
	//创建时先不显示
	_comet->stopSystem();
	//位置,像Sprite一样
	_comet->setPosition(ccp(0,_screenSize.height * 0.6f));
	_comet->setVisible(false);
	this->addChild(_comet,kForeground);

2.cocos2d-x中画线条


这游戏建了一个线条类,继承CCNode,重写draw方法就行了。在draw方法中简单地调用ccDrawColor4F函数来设置颜色,ccDrawLine来画线条,非常容易,cocos2d-x这些函数封装了opengles中的原始函数,使用非常简单。


void LineContainer::draw(){
	switch(_lineType){
	case LINE_NONE:
		break;
	case LINE_TEMP:
		//设置颜色
		ccDrawColor4F(1.0,1.0,1.0,1.0);
		//画线条
		ccDrawLine(_tip,_pivot);
		//画圆
		ccDrawCircle(_pivot,10,CC_DEGREES_TO_RADIANS(360),10,false);
		break;
	case LINE_DASHED:
		ccDrawColor4F(1.0,1.0,1.0,1.0);
		ccDrawCircle(_pivot,10,M_PI,10,false);
		int segments = _lineLength / (_dash + _dashSpace);
		float t = 0.0f;
		float x_;
		float y_;

		for (int i = 0; i < segments + 1; ++i) {

			x_ = _pivot.x + t * (_tip.x - _pivot.x);
			y_ = _pivot.y + t * (_tip.y - _pivot.y);

			ccDrawCircle(ccp ( x_, y_ ), 4, M_PI, 6, false);

			t += (float) 1 / segments;
		}
		break;
	}

	//draw energy bar
	ccDrawColor4F(0.0, 0.0, 0.0, 1.0);
	ccDrawLine(ccp(_energyLineX, _screenSize.height * 0.1f),
		ccp(_energyLineX, _screenSize.height * 0.9f));
	ccDrawColor4F(1.0, 0.5, 0.0, 1.0);
	ccDrawLine(ccp(_energyLineX, _screenSize.height * 0.1f),
		ccp(_energyLineX, _screenSize.height * 0.1f + _energy * _energyHeight ));
}


3.火箭的旋转飞行


这可能是游戏中的一个难点。主要要用到一些数学知识。还要理解火箭的每次旋转度数是目标度数减去已经旋转的度数。因为update方法每时每刻调用的。

还好cocos2d-x中提供了像ccpRotateByAngle,和ccpRPerp函数,让程序更加简单。


void Rocket::update(float dt){
	CCPoint position = this->getPosition();

	//CCLog("_rotationOrientation:%d",_rotationOrientation);

	if (_rotationOrientation == ROTATE_NONE) {
		//默认情况下直行运行
		position.x += _vector.x * dt;
		position.y += _vector.y * dt;

	} else {

		//rotate point around a pivot by a certain amount (rotation angle)
		CCPoint rotatedPoint = ccpRotateByAngle(position, _pivot, _angularSpeed * dt);

		//当火箭旋转时,它的位置通过函数ccpRotateByAngle计算出来
		position.x = rotatedPoint.x;
		position.y = rotatedPoint.y;

		float rotatedAngle; 

		//得到圆的切线
		CCPoint clockwise = ccpRPerp( ccpSub(position, _pivot) );

		if (_rotationOrientation == ROTATE_COUNTER) {
			rotatedAngle = atan2 (-1 * clockwise.y, -1 * clockwise.x);
		} else {
			rotatedAngle = atan2 (clockwise.y, clockwise.x);
		}

		//update rocket vector
		//更新向量这样断掉线的时候,火箭就往它头朝的方向直行运行
		_vector.x = _speed * cos (rotatedAngle);
		_vector.y = _speed * sin (rotatedAngle);

		//设置火箭将要旋转的度数
		this->setRotationFromVector();
	}

	//CCLog("getRotation():%f",this->getRotation());
	//wrap rotation values to 0-360 degrees
	if (this->getRotation() > 0) {
		this->setRotation( fmodf(this->getRotation(), 360.0f) );
	} else {
		this->setRotation( fmodf(this->getRotation(), -360.0f) );
	}


	if (_targetRotation > this->getRotation() + 180) {
		_targetRotation -= 360;
	}
	if (_targetRotation < this->getRotation() - 180) {
		_targetRotation += 360;
	}

	this->setPosition(position);

	//当火箭绕着圆旋转的时候每次旋转的度数=目标度数-当前已经旋转的度数
	_dr = _targetRotation - this->getRotation();
	_ar = _dr * _rotationSpring;
	_vr += _ar ;
	_vr *= _rotationDamping;
	//m_fRotationX += _vr ;
	setRotationX(getRotationX() + _vr);
    
}


4.星星的位置


火箭要吃的黄色星星出现的位置不能与已存在的行星重叠。又要随机。这游戏做的非常有趣,把屏幕分成大小一样的格子,如果当前格子不与行星重叠,那么就把这格子位置加入到数组中,在游戏的开始处,会对这数组进行洗牌。黄色星星位置就是这数组中的值,索引每次自增1,用完了再从0开始。这种方式比吃掉一个黄色星星,游戏重新进行查找合法位置要快很多。赞一个。



项目下载:

http://www.waitingfy.com/?attachment_id=665

文章源地址:

http://www.waitingfy.com/?p=669


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瓦力冫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值