本文是学习cocos2d-x by Example Beginner's Guide 第5章 Rocket Through的副产物。
我们首先来看看本书的作者是怎么写Rocket::collideWithSides()的,代码如下:
bool Rocket::collidedWithSides() {
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
if (m_tPosition.x > screenSize.width - _radius) {
m_tPosition.x = screenSize.width - _radius;
_rotationOrientation = ROTATE_NONE;
_vector = ccp (this->getVector().x * -1, this->getVector().y);
this->setRotationFromVector();
return true;
}
if (m_tPosition.x < _radius) {
m_tPosition.x = _radius;
_rotationOrientation = ROTATE_NONE;
_vector = ccp (this->getVector().x * -1, this->getVector().y);
this->setRotationFromVector();
return true;
}
if (m_tPosition.y < _radius) {
m_tPosition.y = _radius;
_rotationOrientation = ROTATE_NONE;
_vector = ccp (this->getVector().x, this->getVector().y * -1);
this->setRotationFromVector();
return true;
}
if (m_tPosition.y > screenSize.height - _radius) {
m_tPosition.y = screenSize.height - _radius;
_rotationOrientation = ROTATE_NONE;
_vector = ccp (this->getVector().x, this->getVector().y * -1);
this->setRotationFromVector();
return true;
}
return false;
}
上面的 Rocket::collidedWithSides()方法,是检测火箭碰壁有的,如果碰壁,就重设火箭的状态。作为教学用例,效果非常棒。
我打算改写有两个原因
一:可是我深受CharlesPetzold 影响,觉得可以改写的更简练一些。if的复合语句作用有4点
1.重设火箭的坐标
2.设置旋转方向为ROTATE_NONE
3.设置新Vector
4.调用setRotationFromVector()
最后,最后就返回啦。
二:返回分支太多,打算改写成一个 return 出口。
好吧,是时候动手了。
让我从简单的返回分支开始,改写后
bool Rocket::collideWithSides() {
...
if (m_tPosition.x > screenSize.width - _radius) {
...
bResult = true;
}
if (m_tPosition.x < _radius) {
...
bResult = true;
}
if (m_tPosition.y < _radius) {
...
bResult = true;
}
if (m_tPosition.y > screenSize.height - _radius) {
...
bResult = true;
}
return bResult;
}
看着真不错,可是总觉得哪里不对劲耶?
4个if {},每次都执行一遍。
还是默默地,改过来吧。
既然改写return出口是白忙活,那就看看 if 复合语句
上面已经概括 if 复合语句的使用,下面来写个private属性的方法,实现上面的4个功能
声明:
private:
bool collideWithSide(float& side,const float newSide,const cocos2d::CCPoint& point,int rotationOrientation = ROTATE_NONE);
实现:
bool Rocket::collideWithSide(float& side,const float newSide,const cocos2d::CCPoint& point,int rotationOrientation) {
side = newSide;
this->_rotationOrientation = rotationOrientation;
_vector = ccp(point.x, point.y);
this->setRotationFromVector();
return true;
}
collideWithSide方法的返回值,做成bool,以方便collideWithSides()
调用。
/*此方法名为collideWithSides,后面有S,以区别collideWithSide*/
bool Rocket::collideWithSides(void) {
CCSize screen = CCDirector::sharedDirector()->getWinSize();
CCPoint pos = this->getVector();
if (m_tPosition.x < _radius) {
return collideWithSide(m_tPosition.x,_radius, ccp(pos.x * -1, pos.y));
}
if (m_tPosition.x + _radius > screen.width) {
return collideWithSide(m_tPosition.x,screen.width - _radius, ccp(pos.x * -1, pos.y));
}
if (m_tPosition.y < _radius) {
return collideWithSide(m_tPosition.y,_radius, ccp(pos.x, pos.y * -1));
}
if (m_tPosition.y + _radius > screen.height) {
return collideWithSide(m_tPosition.y, screen.height - _radius, ccp(pos.x, pos.y));
}
return false;
}
正如你现在所看到的,这些是我改写的过程。欢迎大家来拍砖。