【cocos2d-x入门实战】微信飞机大战之8:自定义敌机精灵

【cocos2d-x入门实战】微信飞机大战之八:自定义敌机精灵

转载请表明地址:http://blog.****.net/jackystudio/article/details/11890969

飞机可以控制飞行,并且发射子弹,那没有敌机怎么行?

敌机共有3种类型,分别为Enemy1,Enemy2和Enemy3,按大小排列,从程序角度看来,它们的本质都是一样的。不同点在于:

A.图像不一样

B.生命值不一样

C.移动速度和出现频率不一样

D.第三种敌机也就是最大的敌机,在飞行的过程中带有动画效果。

这里以最小的敌机(Enemy1)为例。


1.有生命的敌机

自定义的敌机类是少不了的,但是要从CCNode继承还是CCSprite继承,那就要看实际需要了,从CCNode继承灵活度会高一点,但是也麻烦一点,从CCSprite继承就会相对简单一点,但是灵活度就低了。建议还是从CCNode继承,这里因为只为飞机添加一个生命值属性,所以就直接从CCSprite继承了。

//Enemy1Sprite.h
#pragma once
#include "cocos2d.h"
USING_NS_CC;
const int ENEMY1_MAXLIFE=1;//小飞机的生命值为1,中的我设置为2,大的设置为5,难度比较小
class Enemy1Sprite :
	public CCSprite
{
public:
	static Enemy1Sprite* create(CCSpriteFrame *pSpriteFrame);//重载create(CCSpriteFrame *pSpriteFrame),因为这里我们只用到这个构造函数
public:
	int life;//生命值
};

//Enemy1Sprite.cpp
#include "Enemy1Sprite.h"
Enemy1Sprite* Enemy1Sprite::create(CCSpriteFrame *pSpriteFrame)
{
	Enemy1Sprite *pobSprite = new Enemy1Sprite();
	if (pobSprite && pobSprite->initWithSpriteFrame(pSpriteFrame))
	{
		pobSprite->life=ENEMY1_MAXLIFE;//初始生命值为1
		pobSprite->autorelease();
		return pobSprite;
	}
	CC_SAFE_DELETE(pobSprite);
	return NULL;
}


2.敌机的随机初始位置和速度

敌机出现的位置和飞行速度是随机值,从我们设定的范围中得出,敌机的回收机制同子弹层的处理是一样的,采用CCArray管理,这里不再赘诉。

//随机初始位置
Enemy1Sprite* enemy1=Enemy1Sprite::create(enemy1SpriteFrame);//enemy1SpriteFrame是从CCSpriteFrameCache取出的精灵帧
CCSize enemy1Size=enemy1->getContentSize();
CCSize winSize=CCDirector::sharedDirector()->getWinSize();
int minX=enemy1Size.width/2;
int maxX=winSize.width-enemy1Size.width/2;
int rangeX=maxX-minX;//获取初始随机位置范围
int actualX=(rand()%rangeX)+minX;//实际x位置
enemy1->setPosition(ccp(actualX,winSize.height+enemy1Size.height/2));
this->addChild(enemy1);

//随机飞行速度
int minDuration=2;
int maxDuration=4;
int rangeDuration=maxDuration-minDuration;//获取速度范围
int actualDuration=(rand()%rangeDuration)+minDuration;//实际速度
CCFiniteTimeAction* actionMove=CCMoveTo::create(actualDuration,ccp(actualX,0-enemy1->getContentSize().height/2));
CCFiniteTimeAction* actionDone=CCCallFuncN::create(this,callfuncN_selector(Enemy1Layer::enemy1MoveFinished));//超出屏幕进行回收,回收机制和子弹层的处理是一样的
CCSequence* sequence=CCSequence::create(actionMove,actionDone);
enemy1->runAction(sequence);//执行飞行动作


3.敌机爆炸

敌机在与子弹碰撞后,会产生爆炸效果,也就是一串帧动画,动画结束后,敌机消失,同时进行回收处理。这里的animate如果能加入动画缓冲池,效率会更高。

//敌机爆炸
void Enemy1Layer::enemy1Blowup(Enemy1Sprite* enemy1)
{
	CCAnimation* animation=CCAnimation::create();
	animation->setDelayPerUnit(0.1f);//设置帧动画间隔
	animation->addSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy1_down1.png"));
	animation->addSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy1_down2.png"));
	animation->addSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy1_down3.png"));
	animation->addSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy1_down4.png"));

	CCAnimate* animate=CCAnimate::create(animation);//创建帧动画
	CCCallFuncND* removeEnemy1=CCCallFuncND::create(this,callfuncND_selector(Enemy1Layer::RemoveEnemy1),(void*)enemy1);//爆炸后移除敌机
	CCSequence* sequence=CCSequence::create(animate,removeEnemy1);
	enemy1->runAction(sequence);
}

4.Enemy1Layer敌机层的其他接口

//移除单架敌机
void Enemy1Layer::RemoveEnemy1(CCNode* pTarget, void* data)
{
	Enemy1Sprite* enemy1=(Enemy1Sprite*)data;
	if (enemy1!=NULL)
	{
		m_pAllEnemy1->removeObject(enemy1);
		this->removeChild(enemy1,true);
	}
}

//移除所有敌机,干嘛用?还记得有个ufo炸弹全屏秒么。。。
void Enemy1Layer::RemoveAllEnemy1()
{
	CCObject* obj;
	CCARRAY_FOREACH(m_pAllEnemy1,obj)//遍历所有敌机
	{
		Enemy1Sprite* enemy1=(Enemy1Sprite*)obj;
		if (enemy1->life>0)
		{
			enemy1Blowup(enemy1);//全部爆炸
		}
	}
}


5.超大型敌机的飞行动画

这里简单采用帧动画,单独执行,也可以使用CCSpawn类来实现同时动画效果

enemy3SpriteFrame_1=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy3_n1.png");
enemy3SpriteFrame_2=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy3_n2.png");
CCAnimation* animation=CCAnimation::create();//创建帧动画
animation->setDelayPerUnit(0.1f);
animation->addSpriteFrame(enemy3SpriteFrame_1);
animation->addSpriteFrame(enemy3SpriteFrame_2);
CCAnimate* animate=CCAnimate::create(animation);
enemy3->runAction(CCRepeatForever::create(animate));//采用CCRepeaterForever不断重复动画

好了,把中型敌机和大型敌机也添加进GameLayer,运行一下,敌机满天飞了,控制你的手指头移动主角飞机进行射击,我了个去,死不了是闹哪样。。。。

这不废话!最最重要的碰撞检测还没加入呢!

4楼suannai03141小时前
您的文章已被推荐到****首页,感谢您的分享。
3楼xiaoxilovewu昨天 19:04
LZ回复的好快。。。现在手头上的项目刚好做完了,有点时间。搭个环境先,哈哈
2楼lxq_2012昨天 15:45
哥哥,在跟你的代码学习中,初学者,似懂非懂。。。。
Re: jackyvincefu昨天 15:48
回复lxq_2012n嗯,如果哪里有写不清楚的留言,互相探讨下。
Re: lxq_2012昨天 15:53
回复jackyvincefun我的工作是涉及页游后端的,语言不是C++,C++也就大学弄过。COCO2D-X是兴趣着学,通过你这个打飞机游戏分析收益颇丰啊。。虽然看着有点费劲,……也按照你的流程建立各个模块文件了,编译不通过。。各种报错。呵呵
Re: jackyvincefu昨天 17:43
回复lxq_2012n这还是要有C++的基础的,不然很多东西都看不懂,我这里也没有进行解释,因为那样的话解释的东西就太多了。大家都干这行的,都知道得多动手,多google哈哈。
1楼xiaoxilovewu昨天 12:10
去年的时候就想学一下cocos2d-x了,因为每个程序员都有一颗游戏的心嘛,虽然现在做的是应用开发。当时因为工作的事情和C++基础也不是很好,所以就放下了,看了你的博客,心又有点痒痒了,准备重新好好学下这个。
Re: jackyvincefu昨天 13:27
回复xiaoxilovewun好一个每个程序猿都有一颗游戏的心哈哈。我现在也不是从事相关的,但是先拿起来学吧。