在游戏中,由于大多的船的都是长方形的,所以把护盾做成了椭圆,而不是圆,另外也再护盾的外围增加一个护盾的持续时间的一个计时器。效果:
所以,这里当敌人的子弹发射过来时,要在护盾边上触发(也就是椭圆的边上)。
class ProtectBody : public CCSprite {
public:
static ProtectBody* create(float scaleX, float scaleY);//创造护盾
bool init(float scaleX, float scaleY);//初始化
bool checkCollision(const CCPoint &weaponPos);//椭圆碰撞
void protectStart();//开始启动护盾
void protectFinished();//护盾启动完成
void protectEnd();//护盾结束
void protectTimeEnd();//计时结束
CC_SYNTHESIZE_READONLY(float, _sx, SX);//x轴缩放(不同的体型控制不同的缩放)
CC_SYNTHESIZE_READONLY(float, _sy, SY);//y轴缩放(不同的体型控制不同的缩放)
CC_SYNTHESIZE_READONLY(bool, _active, Active);//是否激活
private:
CCProgressTimer* _protectTime;//计时器
};
实现的代码十分简单,可以一目了然。
ProtectBody* ProtectBody::create(float scaleX, float scaleY) {
ProtectBody* protectBody = new ProtectBody();
if(protectBody && protectBody->init(scaleX, scaleY)) {
protectBody->autorelease();
return protectBody;
}else {
delete protectBody;
protectBody = NULL;
return NULL;
}
}
bool ProtectBody::init(float scaleX, float scaleY) {
bool result = false;
if(CCSprite::init()) {//初始化
this->_active = false;
this->_sx = scaleX;
this->_sy = scaleY;
this->initWithSpriteFrameName(protect_body_png);
this->setScale(0);
this->setOpacity(0);
ccBlendFunc blend = {GL_SRC_ALPHA, GL_ONE};
this->setBlendFunc(blend);
this->_protectTime = CCProgressTimer::create(CCSprite::createWithSpriteFrameName(protect_time_png));
this->_protectTime->setOpacity(50);
this->_protectTime->setVisible(false);
this->_protectTime->setType(kCCProgressTimerTypeRadial);
this->_protectTime->setReverseProgress(true);
CCSize size = this->getContentSize();
this->_protectTime->setPosition(ccp(size.width / 2, size.height / 2));
this->addChild(this->_protectTime);
result = true;
}
return result;
}
bool ProtectBody::checkCollision(const CCPoint &weaponPos) {
CCPoint shipPos = GameLayer::shareGameLayer()->getShip()->getPosition();
CCSize s = this->getContentSize();
//椭圆碰撞
float x = weaponPos.x - shipPos.x;
float y = weaponPos.y - shipPos.y;
float w = s.width * this->_sx;
float h = s.height * this->_sy;
float r = (x * x) / (w * w) + (y * y) / (h * h);
if(abs(r) <= 0.25) {
return true;
}
return false;
}
void ProtectBody::protectStart() {
this->_active = true;
CCActionInterval* scaleAction = CCScaleTo::create(0.5f, this->_sx, this->_sy);
CCActionInterval* fadeAction = CCFadeTo::create(0.5f, 255);
CCCallFunc* callback = CCCallFunc::create(this, callfunc_selector(ProtectBody::protectFinished));
this->runAction(CCSequence::create(CCSpawn::create(scaleAction, fadeAction, NULL), callback, NULL));
}
void ProtectBody::protectFinished() {
GameLayer::shareGameLayer()->getShip()->setIsProtected(true);
CCProgressFromTo* to = CCProgressFromTo::create(STATIC_DATA_FLOAT("protect_time"), 100, 0);
CCCallFunc* callback = CCCallFunc::create(this, callfunc_selector(ProtectBody::protectEnd));
this->_protectTime->setPercentage(100);
this->_protectTime->setVisible(true);
this->_protectTime->runAction(CCSequence::create(to, callback, NULL));
}
void ProtectBody::protectEnd() {
CCActionInterval* scaleAction = CCScaleTo::create(0.5f, 0, 0);
CCActionInterval* fadeAction = CCFadeTo::create(0.5f, 0);
CCCallFunc* callback = CCCallFunc::create(this, callfunc_selector(ProtectBody::protectTimeEnd));
this->runAction(CCSequence::create(CCSpawn::create(scaleAction, fadeAction, NULL), callback, NULL));
GameLayer::shareGameLayer()->getShip()->setIsProtected(false);
GameLayer::shareGameLayer()->setIsAppearShield(false);
}
void ProtectBody::protectTimeEnd() {
this->_active = false;//不激活
this->_protectTime->setVisible(false);//计时器设置不可见
}