游戏出自《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