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

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

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

动作类游戏,战斗类场景很常见,接下来几篇文章,我将记录用WiEngine编写游戏的战斗场景。本文介绍boss相关的内容,包括boss动画,boss的health bar等。先看几个效果图:

初始化时,boss为满血。

攻击两次之后,boss的血剩余1/3。


最后的致命一击,boss颤抖几下,然后爆炸了。

战斗场景的序列基本这样,接下来就是实现了。这篇文章主要使用到的技术有:1)动画的切换;2)health bar的实现;3)Action的序列化运行。其实还是比较简单的。

=======

使用Texture Packer进行动画文件的创建。TexturePacker的操作界面如下:


导出的文件名为:enemy.plist和enemy.png,在scene中载入贴图集:

zm->addZwoptex("enemy", RES("R.raw.enemy"), wyTexture2D::makePNG(RES("R.drawable.enemy")));

使用贴图集创建sprite的代码如下:

boss = zm->makeSprite("enemy_01.png");
在enemy类中,初始化动画,代码如下:

enum EnemyActionsTag {
	EMY_RUN = 0, EMY_DIED, EMY_HIT
} ;
。。。。
actions[EMY_RUN] = makeAction("enemy", zm, 4);
actions[EMY_HIT] = makeAction("enemy", zm, 4);
actions[EMY_DIED] = makeAction("explode", zm, 16);
。。。。
wyAction* makeAction(const char* an, wyZwoptexManager* zm, int num) {
	char buf[128];
	wyAnimation* anim = wyAnimation::make(0);
	for (int i = 1; i < num+1; i++) {
		sprintf(buf, "%s_%02d.png", an, i);
		LOGI(buf);
		wySpriteFrame* f = zm->getSpriteFrame(buf);
		f->setDuration(0.15f);
		anim->addFrame(f);
	}

	wyRepeatForever* rp = wyRepeatForever::make(wyAnimate::make(anim));
	rp->retain();
	return rp;
}

boss的Health bar的实现了运用了WiEngine中的wyProgressTimer类来实现,其实这个类也是一个sprite,它只是是对Sprite的一个封装,赋予sprite进度条的功能,创建的代码如下:

blood = wyProgressTimer::make(zm->makeSprite("blood.png"));
blood->setStyle(HORIZONTAL_BAR_LR); //设置进度条的改变方式
blood->setPosition(blood->getPositionX(), blood->getPositionY()+50);
blood->setScale(0.5f);
addChildLocked(blood);
改变进度的方法:

1)直接改变

blood->setPercentage(60);
2)动画渐变

blood->runAction(wyProgressBy::make(2, 60)); //在2秒内,改变进度到60%


boss抖动爆炸效果的实现。

抖动要用到wyShake实现的动画,爆炸就是使用帧动画来实现,然后把两个动画序列化起来,成为一个组合动画,代码如下:

void die() {
	wyCallFunc* explode = wyCallFunc::make(wyTargetSelector::make(this, SEL(Enemy::explode)));
	wySequence* s = wySequence::make(wyShake::make(1, 5), explode,  NULL);
	boss->runAction(s);
	blood->setPercentage(0);
}
void explode() {
	changeAction(Enemy::EMY_DIED);
}

======

ok,把Enemy.h完整的代码贴上:

#ifndef ENEMY_H_
#define ENEMY_H_

class Enemy: public wyNode {
public:
	enum EnemyActionsTag {
		EMY_RUN = 0, EMY_DIED, EMY_HIT
	} ;
public:
	MyScene* scene;

	wyAction* actions[3];
	wySprite* boss;
	wyProgressTimer* blood;
	const char* soundEffect;
	float health;

public:
	Enemy(MyScene* scene) {
		health = 100;
		soundEffect = NULL;
		wyZwoptexManager* zm = wyZwoptexManager::getInstance();

		// add sprite
		boss = zm->makeSprite("enemy_01.png");
		addChildLocked(boss);

		// ADD BLOOD
		blood = wyProgressTimer::make(zm->makeSprite("blood.png"));
		blood->setStyle(HORIZONTAL_BAR_LR);
		blood->setPosition(blood->getPositionX(), blood->getPositionY()+50);
		blood->setScale(0.5f);
		addChildLocked(blood);

		// create animation
		actions[EMY_RUN] = makeAction("enemy", zm, 4);
		actions[EMY_HIT] = makeAction("enemy", zm, 4);
		actions[EMY_DIED] = makeAction("explode", zm, 16);

		// init the animation
		renew();

		this->setPosition(400, 35);

		wyAudioManager::getInstance()->preloadEffect(RES("R.raw.explore"), FORMAT_MP3);
		wyAudioManager::getInstance()->preloadEffect(RES("R.raw.damage"), FORMAT_OGG);
	}

	virtual ~Enemy() {
	}

	void renew() {
		health = 100;
		blood->runAction(wyProgressBy::make(2, health));
		changeAction(EMY_RUN);
	}

	void die() {
		wyCallFunc* explode = wyCallFunc::make(wyTargetSelector::make(this, SEL(Enemy::explode)));
		wySequence* s = wySequence::make(wyShake::make(1, 5), explode,  NULL);
		boss->runAction(s);
		blood->setPercentage(0);
	}

	void explode() {
		changeAction(Enemy::EMY_DIED);
	}

	void shot() {
		health -= 33;
		if(health<10) {
			health = 0;
			die();
		} else {
			changeAction(Enemy::EMY_HIT);
		}
		blood->setPercentage(health);

	}

	void changeAction(EnemyActionsTag bat) {
		boss->stopAllActions(true);
		boss->runAction(actions[bat]);
		playEffect(bat);
	}

	wyAction* makeAction(const char* an, wyZwoptexManager* zm, int num) {
		char buf[128];
		wyAnimation* anim = wyAnimation::make(0);
		for (int i = 1; i < num+1; i++) {
			sprintf(buf, "%s_%02d.png", an, i);
			LOGI(buf);
			wySpriteFrame* f = zm->getSpriteFrame(buf);
			f->setDuration(0.15f);
			anim->addFrame(f);
		}

		wyRepeatForever* rp = wyRepeatForever::make(wyAnimate::make(anim));
		rp->retain();
		return rp;
	}

	void playEffect(EnemyActionsTag tag) {
		const char* preEffect = soundEffect;
		switch (tag) {
		case EMY_RUN:
			soundEffect = NULL;
			break;
		case EMY_DIED:
			soundEffect = "R.raw.explore";
			_playEffect(preEffect, soundEffect, FORMAT_MP3);
			break;
		case EMY_HIT:
			soundEffect = "R.raw.damage";
			_playEffect(preEffect, soundEffect, FORMAT_OGG);
			break;
		}
	}

	void _playEffect(const char* preEffect, const char* curEffect, int type) {
		if (curEffect != NULL) {
			if (preEffect != NULL)
				wyAudioManager::getInstance()->stopEffect(RES(preEffect));
			wyAudioManager::getInstance()->playEffect(RES(curEffect), type);
		}
	}
};


#endif /* ENEMY_H_ */







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值