`
runfeel
  • 浏览: 906395 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

转发,请保持地址: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_ */







分享到:
评论

相关推荐

    一个用wiEngine写的非常简单的游戏

    这是一个使用wiEngine手机游戏引擎写的一个非常简单的游戏。游戏只有两个场景,一个是欢迎场景,一个是游戏场景。欢迎场景只有一个背景图,一张游戏logo和一个开始游戏的按钮,点击开始游戏按钮,会进入游戏场景。在...

    WiEngine-master

    WiEngine-master

    微云游戏引擎WiEngineDemos_java源代码

    微云游戏引擎WiEngineDemos_java源代码,欢迎大家前来拿走!

    WiEngine入门笔记(1)学习源码

    博客中的WiEngine入门笔记(1)学习源码,仅此做储存留给自己以后查看。 要是有朋友愿意看看,下载尽可,就是别喷我啊!

    ParticleDesigner

    ParticleDesigner可以用来设计粒子系统效果, 粒子相关的图片可以内嵌在导出的plist中, 目前WiEngine仅支持内嵌的图片格式是png.

    car2源代码

    棺材笔记一 大于你妹的20个字符啊

Global site tag (gtag.js) - Google Analytics