游戏出自《Cocos2d-X by Example Beginner's Guide》第5章。
这游戏的玩法:
首先点在火箭上,再拖动任意位置,就画成一条直线,火箭就会绕着旋转。
要吃发光的黄色星星就会得分,火箭碰到行星或者彗星都会爆炸,右边的橙色进度条掉完也会爆炸。
点评:
这游戏非常难,我还不会玩,黄色的星星出现在上面,要控制火箭以圆形方式过去非常难。
如果不深入了解粒子系统的话,就单单使用是非常简单的。粒子给游戏增色不少。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);
这游戏建了一个线条类,继承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 )); }
这可能是游戏中的一个难点。主要要用到一些数学知识。还要理解火箭的每次旋转度数是目标度数减去已经旋转的度数。因为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); }
火箭要吃的黄色星星出现的位置不能与已存在的行星重叠。又要随机。这游戏做的非常有趣,把屏幕分成大小一样的格子,如果当前格子不与行星重叠,那么就把这格子位置加入到数组中,在游戏的开始处,会对这数组进行洗牌。黄色星星位置就是这数组中的值,索引每次自增1,用完了再从0开始。这种方式比吃掉一个黄色星星,游戏重新进行查找合法位置要快很多。赞一个。
http://www.waitingfy.com/?attachment_id=665
文章源地址:
http://www.waitingfy.com/?p=669