基于WiEngine游戏引擎--战斗场景之技能

28 篇文章 0 订阅
16 篇文章 0 订阅

转发,请保持地址:http://blog.csdn.net/stalendp/article/details/8606424

游戏战斗场景中的技能也是游戏的特色之一,这篇文章将记录使用WiEngine来设计游戏中的技能及其按钮特效。

先看效果图吧:

点击技能的按钮,就会放出技能。技能有冷却事件,表现在按钮上(下图更清晰一些)。


这里的技能用到的是WiEngine粒子系统中的特效。我的理解,粒子系统是一个标准,只要给定相应的参数,就可以显示一些很炫的效果。我本来是想用ParticleDesigner来设计粒子效果的,不过试了一下,发现载入有些问题,所以改用WiEngine中内置的特效了。我这里使用的是官方例子的Meteor(位于Demo/ParticleDemon.h中;补充一下WiEngine的好处,引擎中例子特别详细,我这个demo中的大部分代码都是从例子中改过来的)。我对Meteor进行了一个改进,代码如下:

class ParticleMeteorSystem: public wyQuadParticleSystem {
public:
	ParticleMeteorSystem() :
			wyQuadParticleSystem(150) {
		// duration
		setDuration(PARTICLE_DURATION_INFINITY);

		// gravity
		setParticleGravity(DP(-133.33f), DP(0.33f));

		// angle
		setDirectionAngleVariance(90, 360);

		// speed of particles
		setSpeedVariance(DP(10), DP(3.33f));

		// life of particles
		setLifeVariance(2, 1);

		// size, in pixels
		setStartSizeVariance(DP(40.0f), DP(6.6f));

		// emits per second
		setEmissionRate(getMaxParticles() / getLife());

		// color of particles
		setStartColorVariance(0.2f, 0.4f, 0.7f, 1.0f, 0.0f, 0.0f, 0.2f, 0.1f);
		setEndColorVariance(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);

		//set texture
		setTexture(wyTexture2D::makePNG(RES("R.drawable.fire")));

		// additive
		setBlendAdditive(true);
	}
};

class FightBullet: public wyLayer {
private:
	ParticleMeteorSystem* data;
public:
	FightBullet(float px, float py) {
		data = new ParticleMeteorSystem();
		data->autoRelease();
		addChildLocked(data);
		setScale(0.6f);
		setPosition(px, py);
	}

	virtual ~FightBullet() {
	}
};
这里对子弹射击,只是用于演示有些特效的,并没有处理碰撞监测相关的内容(会在接下来的介绍Box2d时讨论),这里使用动画来演示子弹飞行、击中物体,然后使其爆炸的特效。代码如下:

void Boy::shot() {
	wyCallFunc* sbegin = wyCallFunc::make(wyTargetSelector::make(this, SEL(Boy::shotBegin)));
	wyCallFunc* bulletfly = wyCallFunc::make(wyTargetSelector::make(this, SEL(Boy::letBulletFlying)));
	wySequence* s = wySequence::make(sbegin, bulletfly,  NULL);
	sprite->runAction(s);
}

void Boy::shotBegin() {
	LOGI("Shot begin");
	hitBullet = new FightBullet(sprite->getPositionX()-60, sprite->getPositionY()-50);
	addChildLocked(hitBullet);

	sprite->runAction(boyActions[Boy::BOY_HIT]); //让Hero进行攻击的动画
	playEffect(Boy::BOY_HIT); //播放攻击时的音效
}
void Boy::letBulletFlying() {
	LOGI("Shotting");

	wyActionCallback callback = { NULL, onMoveEnd, NULL }; 
	wyMoveBy* moveby = wyMoveBy::make(3, 235, 0);
	moveby->setCallback(&callback, this);
	hitBullet->runAction(moveby);  // 子弹飞行中
}
static void onMoveEnd(wyAction* action, void* data) { // 子弹飞行完,停止射击动画
	Boy* b = (Boy*)data;b->shotEnd();
}
void Boy::shotEnd() {
	LOGI("Shot end");
	changeAction(Boy::BOY_RUN); //子弹飞行完之后,让Hero进行奔跑动画
	removeChild(hitBullet, true);
	hitBullet->release();
	scene->enemyKilled(); // 表明击中物体,这里应当使用碰撞监测的。
}

接下来介绍技能按钮的实现。技能按钮有个冷却的时间(常识啊),在这里我将实现这个效果。相同的技能要准备两张图片,一张明亮一点的,表明技能可以使用,一张暗一点的,表示技能需要冷却。技能冷却时,吧暗一点的图片覆盖在亮一点的图片上, 播放一个动画时暗图片逐渐消失,就达到冷却效果了(效果在上面的第二张图片上很清晰。技能冷却的效果,对于玩过魔兽世界的同学来说,这是理所当然了)。 

OK,附上代码:

class Button2: public wyNode {
public:
	MyScene* scene;
	wyButton* button;
	wySprite* enable;
	wyProgressTimer* disable;
	wyCallFunc* action;
	int type;

public:
	Button2(MyScene* scene, const char* ne, const char* ndis, int type) {
		this->scene = scene;
		this->type = type;

		wyZwoptexManager* zm = wyZwoptexManager::getInstance();

		// create sprites
		enable = zm->makeSprite(ne);
		disable = wyProgressTimer::make(zm->makeSprite(ndis));
		disable->setStyle(RADIAL_CCW); //设置进度条的改变方式
		disable->setScale(0.9f);

		// create atlas button
		button = new wyButton(enable, enable, enable, NULL, NULL,
				wyTargetSelector::make(this, SEL(Button2::onButtonClicked)));
		addChildLocked(button);
		disable->setPosition(button->getPositionX(), button->getPositionY());
		disable->setVisible(false);

		addChildLocked(disable);
	}

	virtual ~Button2() {
	}


	void onButtonClick() {
		switch(type) {
		case Boy::BOY_JUMP:
			scene->jump();
			break;
		case Boy::BOY_HIT:
			scene->shot();
			break;
		}
	}

	void onButtonClickedEnd() {
		disable->setVisible(false);
		button->setEnabled(true);
	}

	void onButtonClicked(wyTargetSelector* ts) {
		button->setEnabled(false);
		disable->setVisible(true);

		wyCallFunc* onaction = wyCallFunc::make(wyTargetSelector::make(this, SEL(Button2::onButtonClick)));
		wyCallFunc* setenable = wyCallFunc::make(wyTargetSelector::make(this, SEL(Button2::onButtonClickedEnd)));
		wySequence* s = wySequence::make(onaction, wyProgressTo::make(3, 100, 0), setenable,  NULL);
		disable->runAction(s);
	}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值