护盾的实现

本文介绍了一款游戏中护盾系统的实现细节,包括护盾的创建、启动、结束及计时等过程,并详细解释了椭圆碰撞检测算法。通过Cocos2d-x引擎,实现了动态调整护盾大小和透明度的效果。

在游戏中,由于大多的船的都是长方形的,所以把护盾做成了椭圆,而不是圆,另外也再护盾的外围增加一个护盾的持续时间的一个计时器。效果:


所以,这里当敌人的子弹发射过来时,要在护盾边上触发(也就是椭圆的边上)。

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);//计时器设置不可见
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值