《简单的飞机大战》事实上不简单(1)

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre">	</span>这是一个很easy的《经典飞机大战》游戏。实现的基本功能:包含Boss的随机生成,击中销毁;分数依据击毁Boss的数量添加。

附加功能有:道具的不定时产生,当英雄飞机碰撞到道具产生该道具的道具效果。</span>
</pre><pre name="code" class="cpp">

这里仅仅实现最基本功能。

环境搭配:

1.操作系统;Win7

2.cocos2d-x版本号:3.2

3.VS版本号:VS2013

一、首先确定飞机基类

1.在这里,因为节点的getBoundingBox()的到的矩形比实际要检測碰撞的矩形大效果不好,另一些英雄飞、和Boss飞机和子弹的同样的功能。首先写出一个公共基类:

class BoxTest :public cocos2d::Sprite
{
public:
	//CREATE_FUNC(BoxTest);
	//virtual bool init();

	cocos2d::Rect getBox();

	virtual void setStep(int step){ _step = step; }
	//是否爆炸
	virtual void setIsbomb(bool bomb) { _isbomb = bomb; }
	virtual bool getIsbomb() const { return _isbomb; }

	//被击中后降低最多击中次数
	virtual void reduceHP(){ ; };
	virtual int getHP() const { return _HP; };
	virtual void setHP(int hp){ _HP = hp; }
	virtual void setIsRemove(bool isremove){ _isremove = isremove; }
	virtual bool getIsRemove() const { return _isremove; }

	//击中动画
	virtual Animate *animateHit(){ return nullptr; };
	//爆炸动画
	virtual Animate *animateBomb(){ return nullptr; };

protected:
	float Minx;
	float Miny;

	//移动步数 速度
	int _step;
	//是否爆炸
	bool _isbomb;
	//最多被击中次数,为0时爆炸
	int _HP;

	bool _isremove;

};

2.实现该类的部分方法:

Rect BoxTest::getBox()
{
	Minx = this->getPosition().x - this->getContentSize().width / 2 * 0.5;
	Miny = this->getPosition().y - this->getContentSize().height / 2 * 0.5;

	return Rect(Minx, Miny, this->getContentSize().width * 0.5, this->getContentSize().height * 0.5);
}

二、创建英雄飞机和Boss飞机

1.继承上述公共基类:

class Boss1 :public BoxTest
{
public:
	CREATE_FUNC(Boss1);
	virtual bool init();

	virtual void update(float dt);

	//击中时降低挤肿次数
	virtual void reduceHP();

	//击中动画
	virtual Animate *animateHit();
	//爆炸动画
	virtual Animate *animateBomb();

};
class Boss2 :public BoxTest
{
public:
	CREATE_FUNC(Boss2);
	virtual bool init();

	virtual void update(float dt);

	//击中时降低挤肿次数
	virtual void reduceHP();

	//击中动画
	virtual Animate *animateHit();
	//爆炸动画
	virtual Animate *animateBomb();

};
//最牛逼的飞机
class Boss3 :public BoxTest
{
public:
	CREATE_FUNC(Boss3);
	virtual bool init();

	virtual void update(float dt);

	//击中时降低挤肿次数
	virtual void reduceHP();
	void actionMove();
	Animate *animateMove();
	//击中动画
	virtual Animate *animateHit();
	//爆炸动画
	virtual Animate *animateBomb();

};
//英雄飞机
class Plane :public BoxTest
{
public:
	CREATE_FUNC(Plane);
	virtual bool init();
	virtual	void update(float dt);
};

class Bullet :public BoxTest
{
public:
	CREATE_FUNC(Bullet);
	virtual bool init();

	virtual void update(float dt);
};

2.实现继承方法:

bool Plane::init()
{
	if (Sprite::initWithSpriteFrameName("hero1.png") == false)
		return false;
	//log("1%f    %f", this->getContentSize().width, this->getContentSize().height);
	//this->setContentSize(Size(this->getContentSize().width * 0.7f, this->getContentSize().height * 0.7f));
	//this->setScale(0.7f);
	//log("2%f    %f", this->getContentSize().width, this->getContentSize().height);
	this->scheduleUpdate();
	return true;
}

void Plane::update(float dt)
{
	auto VisbelSize = Director::getInstance()->getVisibleSize();
	if ((this->getPosition().x > (VisbelSize.width - this->getContentSize().width / 2)))
	{
		this->setPositionX(VisbelSize.width - this->getContentSize().width / 2 - 6);
	}
	else if ((this->getPosition().x < this->getContentSize().width / 2))
	{
		this->setPositionX(this->getContentSize().width / 2 - 6);
	}
	else if ((this->getPosition().y >(VisbelSize.height - this->getContentSize().height / 2)))
	{
		this->setPositionY(VisbelSize.height - this->getContentSize().height / 2);
	}
	else if ((this->getPosition().y < this->getContentSize().height / 2))
	{
		this->setPositionY(this->getContentSize().height / 2);
	}
}

//最小的Boss
bool Boss1::init()
{
	if (Sprite::initWithSpriteFrameName("enemy1.png") == false)
		return false;

	//移动速度
	this->_step = 3;
	this->_HP = 0;
	this->_isbomb = false;

	this->scheduleUpdate();
	return true;
}

void Boss1::reduceHP()
{
	if (_HP > 0)
	{
		this->runAction(this->animateHit());
		_HP--;
	}
	else
	{
		setIsbomb(true);
	}
}

Animate *Boss1::animateHit()
{
	SpriteFrame *frame = nullptr;
	Vector<SpriteFrame *> frameVec;

	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy2.png");
	frameVec.pushBack(frame);
	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy2_hit.png");
	frameVec.pushBack(frame);
	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy2.png");
	frameVec.pushBack(frame);

	Animation *animation = Animation::createWithSpriteFrames(frameVec);
	animation->setLoops(1);//设置次数
	animation->setDelayPerUnit(0.2f);//设置帧间隔
	Animate *animate = Animate::create(animation);

	return animate;
}

Animate *Boss1::animateBomb()
{
	SpriteFrame *frame = nullptr;
	Vector<SpriteFrame *> frameVec;

	int frameNum = 4;
	for (int i = 0; i < frameNum; i++)
	{
		frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(StringUtils::format("enemy1_down%d.png", i + 1).c_str());
		frameVec.pushBack(frame);
	}

	Animation *animation = Animation::createWithSpriteFrames(frameVec);
	animation->setLoops(1);//设置次数
	animation->setDelayPerUnit(0.1f);//设置帧间隔
	Animate *animate = Animate::create(animation);

	return animate;
}

void Boss1::update(float dt)
{
	this->setPositionY(this->getPositionY() - _step);
	if (this->getPositionY() < 0)
	{
		this->setIsRemove(true);
		this->removeFromParent();
	}
	else if (_isbomb == true)
	{
		this->setPositionY(this->getPositionY() - _step);
		if (this->getPositionY() < 0)
		{
			this->setIsRemove(true);
			this->removeFromParent();
		}
		else if (_isbomb == true)
		{
			auto callfunc = [this](){
				this->setIsRemove(true);
				this->removeFromParent();
			};
			//先停住
			_step = 0;
			//爆炸
			this->unscheduleUpdate();
			//this->runAction(animateBomb());
			this->runAction(Sequence::create(animateBomb(), CallFunc::create(callfunc), nullptr));
		}
	}

}

//中间Boss
bool Boss2::init()
{
	if (Sprite::initWithSpriteFrameName("enemy2.png") == false)
		return false;

	//移动速度
	this->_step = 2;
	this->_HP = 1;
	this->_isbomb = false;

	this->scheduleUpdate();
	return true;
}

void Boss2::reduceHP()
{
	if (_HP > 0)
	{
		this->runAction(animateHit());
		_HP--;
	}
	else
	{
		setIsbomb(true);
	}
}

Animate *Boss2::animateHit()
{
	SpriteFrame *frame = nullptr;
	Vector<SpriteFrame *> frameVec;

	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy2.png");
	frameVec.pushBack(frame);
	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy2_hit.png");
	frameVec.pushBack(frame);
	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy2.png");
	frameVec.pushBack(frame);

	Animation *animation = Animation::createWithSpriteFrames(frameVec);
	animation->setLoops(1);//设置次数
	animation->setDelayPerUnit(0.1f);//设置帧间隔
	Animate *animate = Animate::create(animation);

	return animate;
}

Animate *Boss2::animateBomb()
{
	SpriteFrame *frame = nullptr;
	Vector<SpriteFrame *> frameVec;

	int frameNum = 4;
	for (int i = 0; i < frameNum; i++)
	{
		frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(StringUtils::format("enemy2_down%d.png", i + 1).c_str());
		frameVec.pushBack(frame);
	}

	Animation *animation = Animation::createWithSpriteFrames(frameVec);
	animation->setLoops(1);//设置次数
	animation->setDelayPerUnit(0.1f);//设置帧间隔
	Animate *animate = Animate::create(animation);

	return animate;
}

void Boss2::update(float dt)
{
	this->setPositionY(this->getPositionY() - _step);
	if (this->getPositionY() < 0)
	{
		this->setIsRemove(true);
		this->removeFromParent();
	}
	else if (_isbomb == true)
	{
		this->setPositionY(this->getPositionY() - _step);
		if (this->getPositionY() < 0)
			this->setIsRemove(true);
		else if (_isbomb == true)
		{
			auto callfunc = [this](){
				this->setIsRemove(true);
				this->removeFromParent();
			};
			//先停住
			_step = 0;
			//爆炸
			this->unscheduleUpdate();
			//this->runAction(animateBomb());
			this->runAction(Sequence::create(animateBomb(), CallFunc::create(callfunc), nullptr));
		}
	}

}

//

bool Boss3::init()
{
	if (Sprite::initWithSpriteFrameName("enemy3_n1.png") == false)
		return false;

	//移动速度
	this->_step = 1;
	this->_HP = 2;
	this->_isbomb = false;

	actionMove();
	this->scheduleUpdate();
	return true;
}
void Boss3::actionMove()
{
	this->runAction(RepeatForever::create(animateMove()));
}
//
void Boss3::reduceHP()
{
	if (_HP > 0)
	{
		this->stopAllActions();
		this->runAction(Sequence::create(animateHit(), RepeatForever::create(animateMove()), nullptr));//animateHit());
		log("%d", _HP);
		_HP--;
	}
	else
	{
		setIsbomb(true);
	}
}
Animate *Boss3::animateMove()
{
	Animate * animate = nullptr;

	SpriteFrame *frame = nullptr;
	Vector<SpriteFrame *> frameVec;

	int frameNum = 2;
	for (int i = 0; i < frameNum; i++)
	{
		frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(StringUtils::format("enemy3_n%d.png", i + 1).c_str());
		frameVec.pushBack(frame);
	}

	Animation *animation = Animation::createWithSpriteFrames(frameVec);
	animation->setLoops(1);//设置次数
	animation->setDelayPerUnit(0.4f);//设置帧间隔
	animate = Animate::create(animation);

	return animate;
}

Animate *Boss3::animateHit()
{
	SpriteFrame *frame = nullptr;
	Vector<SpriteFrame *> frameVec;

	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy3_n1.png");
	frameVec.pushBack(frame);
	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy3_n2.png");
	frameVec.pushBack(frame);
	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy3_hit.png");
	frameVec.pushBack(frame);
	frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("enemy3_n1.png");
	frameVec.pushBack(frame);

	Animation *animation = Animation::createWithSpriteFrames(frameVec);
	animation->setLoops(1);//设置次数
	animation->setDelayPerUnit(0.1f);//设置帧间隔
	Animate *animate = Animate::create(animation);

	return animate;
}

Animate *Boss3::animateBomb()
{
	SpriteFrame *frame = nullptr;
	Vector<SpriteFrame *> frameVec;

	int frameNum = 6;
	for (int i = 0; i < frameNum; i++)
	{
		frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(StringUtils::format("enemy3_down%d.png", i + 1).c_str());
		frameVec.pushBack(frame);
	}

	Animation *animation = Animation::createWithSpriteFrames(frameVec);
	animation->setLoops(1);//设置次数
	animation->setDelayPerUnit(0.1f);//设置帧间隔
	Animate *animate = Animate::create(animation);

	return animate;
}
//
//void Boss3::SelfToRemove()
//{
//	this->removeFromParent();
//}
//

void Boss3::update(float dt)
{
	this->setPositionY(this->getPositionY() - _step);
	if (this->getPositionY() < 0)
	{
		this->setIsRemove(true);
		this->removeFromParent();
	}
	else if (_isbomb == true)
	{
		auto callfunc = [this](){
			this->setIsRemove(true);
			this->removeFromParent();
		};
		//先停住
		_step = 0;
		//爆炸
		this->unscheduleUpdate();
		this->stopAllActions();
		//this->runAction(animateBomb());
		this->runAction(Sequence::create(animateBomb(), CallFunc::create(callfunc), nullptr));
	}

}
//
//void Boss3::setStep(int step)
//{
//	_step = step;
//}
//
//

bool Bullet::init()
{
	if (Sprite::initWithSpriteFrameName("bullet1.png") == false)
		return false;

	this->setStep(20);
	this->scheduleUpdate();
	return true;
}

void Bullet::update(float dt)
{
	this->setPositionY(getPositionY() + _step);
	if (getIsbomb() == true)
	{
		this->setIsRemove(true);
		this->removeFromParent();
	}
	else if (this->getPositionY() > (Director::getInstance()->getVisibleSize().height + getContentSize().height / 2))

		this->setIsRemove(true);
		this->removeFromParent();
	}
}

三、实现基本游戏场景的基本功能

1.在场景的init()方法中生成英雄飞机和一定数量的Boss飞机。初始化英雄飞机的触摸时间(依据触摸点移动英雄飞机,生成子弹)。

bool GameScene::init()
{
	Layer::init();
	SpriteFrameCache::getInstance()->addSpriteFramesWithFile("shoot.plist", "shoot.png");
	VisbelSize = Director::getInstance()->getVisibleSize();

	initHero();
	initListener();
	initBoss();
	initaddBoss();

	this->scheduleUpdate();
	return true;
}

2.在定时随机产生Boss飞机和检測子弹、英雄飞机对Boss的碰撞:

//产生Boss
void GameScene::addBoss(float dt)
{
	int number = 0;
	for (int i = 0; i < 1; i++)
	{
		number = rand() % 10;
		//log("%d", number);
		if (number < 1)
		{
			auto boss = Boss3::create();
			auto x = boss->getContentSize().width / 2 + rand() % (int)(VisbelSize.width - boss->getContentSize().width * 2);
			boss->setPosition(Vec2(x, VisbelSize.height + boss->getContentSize().height / 2));
			this->addChild(boss);

			_bosses.pushBack(boss);;
		}
		else if (number > 2 && number < 4)
		{
			auto boss = Boss2::create();
			auto x = boss->getContentSize().width / 2 + rand() % (int)(VisbelSize.width - boss->getContentSize().width * 2);
			boss->setPosition(Vec2(x, VisbelSize.height + boss->getContentSize().height / 2));
			this->addChild(boss);

			_bosses.pushBack(boss);
		}
		else
		{
			auto boss = Boss1::create();
			auto x = boss->getContentSize().width / 2 + rand() % (int)(VisbelSize.width - boss->getContentSize().width * 2);
			boss->setPosition(Vec2(x, VisbelSize.height + boss->getContentSize().height / 2));
			this->addChild(boss);

			_bosses.pushBack(boss);
		}

	}
}

这里通过两个Vector管理子弹和Boss飞机的碰撞检測和销毁,这里有个bug,是有时候碰撞检測不准确。

望高手指点。

void GameScene::update(float dt)
{
	for (auto ieBoss = _bosses.begin(); ieBoss != _bosses.end(); ieBoss++)
	{
		//log("%d", _bosses.size());
		if ((*ieBoss)->getBox().intersectsRect(_hero->getBox()))
		{
			(*ieBoss)->setIsbomb(true);
		}
		for (auto ieBullet = _bullets.begin(); ieBullet != _bullets.end(); ieBullet++)
		{
			if ((*ieBoss)->getBoundingBox().intersectsRect((*ieBullet)->getBoundingBox()))
			{
				(*ieBullet)->setIsRemove(true);
				(*ieBoss)->reduceHP();
			}
		}
	}
	for (auto ieBoss = _bosses.begin(); ieBoss != _bosses.end(); ieBoss++)
	{
		if ((*ieBoss)->getIsRemove() == true)
		{
			_bosses.erase(ieBoss);
			break;
		}
	}

	for (auto ieBoss = _bullets.begin(); ieBoss != _bullets.end(); ieBoss++)
	{
		if ((*ieBoss)->getIsRemove() == true)
		{
			_bullets.erase(ieBoss);
			break;
		}
	}
}

源代码和资源下载:

http://download.csdn.net/detail/shinhwalin/8886755

时间: 2024-10-12 02:26:17

《简单的飞机大战》事实上不简单(1)的相关文章

《简单的飞机大战》其实不简单(1)

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre"> </span>这是一个非常简单的<经典飞机大战>游戏,实现的基本功能:包括Boss的随机生成,击中销毁:分数根据击毁Boss的数量增加.附加功能有:道具的不定时产生,当英

JS+html实现简单的飞机大战

游戏界面: 飞机html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>打飞机</title> <style> #bg { position: relative; width: 530px; height: 600px; margin-left: auto; margin-right: a

android:怎样用一天时间,写出“飞机大战”这种游戏!(无框架-SurfaceView绘制)

序言作为一个android开发人员,时常想开发一个小游戏娱乐一下大家,今天就说说,我是怎么样一天写出一个简单的"飞机大战"的. 体验地址:http://www.wandoujia.com/apps/edu.njupt.zhb.planegame 源码:https://github.com/nuptboyzhb/newplanegame 游戏分析 玩过"飞机大战"游戏的都知道,飞机大战中的主要"角色"有:1.玩家飞机2.敌方飞机3.玩家飞机发送的子

android:如何用一天时间,写出“飞机大战”这样的游戏!(无框架-SurfaceView绘制)

序言作为一个android开发者,时常想开发一个小游戏娱乐一下大家,今天就说说,我是怎么样一天写出一个简单的"飞机大战"的.体验地址:http://www.wandoujia.com/apps/edu.njupt.zhb.planegame游戏分析玩过"飞机大战"游戏的都知道,飞机大战中的主要"角色"有:1.玩家飞机2.敌方飞机3.玩家飞机发送的子弹4.敌方Boss飞机发送的子弹我们需要控制的有:1.绘制屏幕内的角色2.控制角色的逻辑,比如:敌方

飞机大战编写以及Java的面向对象总结

面向对象课程完结即可编写一个简单的飞机大战程序.我觉得我需要总结一下 飞机大战中类的设计: 父类:FlyingObject(抽象类) 接口:Award .Enemy 子类:Hero.Bullet.Airplane (实现Enemy接口). Bee (实现Award接口) 运行类:ShootGame Hero.Bullet.Airplane . Bee 均继承自FlyingObject类,FLyingObject具有他们的公共属性以及行为,因为FlyingObject并不需要被实例化,那么大可以将

【一】仿微信飞机大战cocos2d-x3.0rc1

參考 [偶尔e网事] 的 [cocos2d-x入门实战]微信飞机大战  cocos2dx 2.0版本号,偶尔e网事他写的很具体,面面俱到,大家很有必要看下.能够通过以下链接跳转: cocos2d-x入门实战 这里面我以[cocos2d-x入门实战]微信飞机大战 为蓝本,用cocos2dx 3.0rc1翻版.安装环境什么的,我就不说了,网上都能够找到,我直接从游戏開始界面说起. 想往下看的话,你必须会的一件事,就是你已经能创建出cocos2dx3.rc1的helloworldproject. 以下

cocos2dx 3.0 飞机大战

因为课程须要.然后又水平有限.所以写了个飞机大战.加上不会画画.所以图片资源也是从微信apk解压出来的,设计思路參考的偶尔e网事. 闲话不说.先讲一下设计.大体上一共分为3个场景.场景以下是Layer 開始场景:WelcomeScene -->WelcomeLayer  类似欢迎界面 游戏主场景:GameScene  --> GameLayer  游戏元素加入 和 碰撞检測 结束场景:GameOverScene -->GameOverLayer 然后是游戏的元素,在GameLayer加入

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中)

接<基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)> 三.代码分析 1.界面初始化 1 bool PlaneWarGame::init() 2 { 3 bool bRet = false; 4 do 5 { 6 CC_BREAK_IF(! CCLayer::init()); 7 8 _size = CCDirector::sharedDirector()->getWinSize(); 9 10 // 设置触摸可用 11 this->setIsTouchEnabled

Cocos2d-x飞机大战教程笔记

咳咳~跟着大神的教程学做Cocos2d-x的飞机大战...鉴于我是那种跟着教程都会出非常多错的人,所以还是一路跟着做些笔记比較好.并且因为是用课余时间,所以仅仅能断断续续地做,写下来也好让自己别忘记~ 2014/4/22  Day01 从apk解压获取素材.再用TexturePacker拼接成plist和png. 话说TexturePacker是收费的啊...7天免费,还能够申请1年的使用期. 之前看书还看到有个神器叫zwoptex,貌似是免费的.可惜仅仅有Mac版...╮(╯_╰)╭Howev