当前位置: 首页 > news >正文

【cocos2d-x 3.7 飞机大战】 决战南海I (四) 敌机管理

        敌方飞机应该不定时的出现,有自己的生命周期、运动轨迹。这个类用来管理敌机的产生、移动、爆炸、销毁等。


敌机管理类主要函数例如以下


	//绑定控制器(更新分数)
	void bindController(Controller* controller);

	//依据分数决定加入敌机速度
	void addSpeed(float dt);

	// 加入敌机1
	void addEnemy1(float dt); 

	// 加入敌机2
	void addEnemy2(float dt); 

	// 加入敌机3
	void addEnemy3(float dt); 

	// 加入敌机4
	void addEnemy4(float dt);

	// 敌机爆炸
	void blowupEnemy(Enemy* pEnemySprite);	

	// 移除敌机pNode
	void removeEnemy(Node *pNode);		


其成员变量例如以下

Vector<Enemy*> vecEnemy;// 敌机容器。用于遍历碰撞问题
Controller* m_controlLayer;	//控制器
float m_fSpeed;	//加入敌机速度
float m_fEnemy1;
float m_fEnemy2;
float m_fEnemy3;
float m_fEnemy4;


敌机产生后。要先存储在容器中,通过容器来进行与子弹、我方飞机的碰撞检測,之后统一销毁。


还有就是,由于分数是要存储在数据库中的。所以我们用一个控制器来管理分数。对于我方飞机的触摸移动,也能够用控制器来控制。由于本游戏中的我方飞机操作简单,代码就嵌在了我方飞机类中。

(⊙o⊙)…扯远了。先介绍敌机管理类的实现。再讲控制器。


bool EnemyManager::init()
{
	if (!Layer::init())
	{
		return false;
	}
	cocos2d::Vector<SpriteFrame*> vecTemp;
	vecTemp.clear();

	// 敌机1爆炸
	for (int i = 0; i < 4; i++)
	{
		auto blowUpName = __String::createWithFormat("enemy1_down%d.png", i + 1);
		auto tempBlowUp = SpriteFrameCache::getInstance()->getSpriteFrameByName(
			blowUpName->getCString());
		vecTemp.pushBack(tempBlowUp);
	}

	Animation* pAnimation1 = Animation::createWithSpriteFrames(vecTemp, 0.1f);
	
	// 加入到AnimationCache。而且命名为Enemy1Blowup
	AnimationCache::getInstance()->addAnimation(pAnimation1, "Enemy1Blowup");

	// 敌机2爆炸
	vecTemp.clear();
	for (int i = 0; i < 4; i++)
	{
		auto blowUpName = __String::createWithFormat("enemy2_down%d.png", i + 1);
		auto tempBlowUp = SpriteFrameCache::getInstance()->getSpriteFrameByName(
			blowUpName->getCString());
		vecTemp.pushBack(tempBlowUp);
	}

	Animation *pAnimation2 = Animation::createWithSpriteFrames(vecTemp,0.1f);

	AnimationCache::getInstance()->addAnimation(pAnimation2, "Enemy2Blowup");

	// 敌机3爆炸
	vecTemp.clear();
	for (int i = 0; i < 4; i++)
	{
		auto blowUpName = __String::createWithFormat("enemy3_down%d.png", i + 1);
		auto tempBlowUp = SpriteFrameCache::getInstance()->getSpriteFrameByName(
			blowUpName->getCString());
		vecTemp.pushBack(tempBlowUp);
	}

	Animation *pAnimation3 = Animation::createWithSpriteFrames(vecTemp,0.1f);

	AnimationCache::getInstance()->addAnimation(pAnimation3, "Enemy3Blowup");

	// 敌机4爆炸
	vecTemp.clear();
	for (int i = 0; i < 4; i++)
	{
		auto blowUpName = __String::createWithFormat("enemy4_down%d.png", i + 1);
		auto tempBlowUp = SpriteFrameCache::getInstance()->getSpriteFrameByName(
			blowUpName->getCString());
		vecTemp.pushBack(tempBlowUp);
	}

	Animation *pAnimation4 = Animation::createWithSpriteFrames(vecTemp, 0.1f);

	AnimationCache::getInstance()->addAnimation(pAnimation4, "Enemy4Blowup");

	//依据当前分数来设定加入各种敌机的速度
	this->schedule(schedule_selector(EnemyManager::addSpeed), 0.1f);

	return true;
}

//绑定控制器(更新分数)
void EnemyManager::bindController(Controller* controller)
{
	this->m_controlLayer = controller;
	m_controlLayer->retain();
}

//依据分数决定加入敌机速度
void EnemyManager::addSpeed(float dt)
{
	m_fSpeed = m_controlLayer->getSaveData()->getScore() / 1000 + 1;

	this->schedule(schedule_selector(EnemyManager::addEnemy1), m_fEnemy1 / m_fSpeed); // 每1秒出现一架敌机1
	this->schedule(schedule_selector(EnemyManager::addEnemy2), m_fEnemy2 / m_fSpeed);
	this->schedule(schedule_selector(EnemyManager::addEnemy3), m_fEnemy3 / m_fSpeed);
	this->schedule(schedule_selector(EnemyManager::addEnemy4), m_fEnemy4 / m_fSpeed);

}

void EnemyManager::addEnemy1(float dt)
{
	Size size = Director::getInstance()->getVisibleSize();

	Enemy *pEnemySprite = Enemy::create();
	pEnemySprite->setEnemyByType(Enemy1);
	pEnemySprite->setTag(Enemy1);
	this->addChild(pEnemySprite);
	vecEnemy.pushBack(pEnemySprite);

	// 设置运动轨迹 以及到终点时调用的函数
	ccBezierConfig m_bezier;
	m_bezier.controlPoint_1 = ccp(size.width/20, size.height*0.7);
	m_bezier.controlPoint_2 = ccp(size.width/2, size.height/2);
	m_bezier.endPosition = ccp(size.width*0.9, size.height*0.9);
	auto actionMove = BezierTo::create(2.0f, m_bezier);

	auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyManager::removeEnemy, this));
	Sequence* sequence = Sequence::create(actionMove, actionDone, NULL);
	pEnemySprite->runAction(sequence);

	//依据分数改变敌机数量
	
}

void EnemyManager::addEnemy2(float dt)
{
	Size size = Director::getInstance()->getVisibleSize();

	Enemy *pEnemySprite = Enemy::create();
	pEnemySprite->setEnemyByType(Enemy2);
	pEnemySprite->setTag(Enemy2);
	this->addChild(pEnemySprite);
	vecEnemy.pushBack(pEnemySprite);

	// 设置运动轨迹 以及到终点时调用的函数
	ccBezierConfig m_bezier;
	m_bezier.controlPoint_1 = ccp(40, 500);
	m_bezier.controlPoint_2 = ccp(250, 400);
	m_bezier.endPosition = ccp(400, 700);
	auto actionMove = BezierTo::create(4.0f, m_bezier);

	auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyManager::removeEnemy, this));
	Sequence* sequence = Sequence::create(actionMove, actionDone, NULL); 
	pEnemySprite->runAction(sequence);
}

void EnemyManager::addEnemy3(float dt)
{
	Size size = Director::getInstance()->getVisibleSize();

	Enemy *pEnemySprite = Enemy::create();
	pEnemySprite->setEnemyByType(Enemy3);
	pEnemySprite->setTag(Enemy3);
	this->addChild(pEnemySprite);
	vecEnemy.pushBack(pEnemySprite);

	// 设置运动轨迹 以及到终点时调用的函数
	ccBezierConfig m_bezier;
	m_bezier.controlPoint_1 = ccp(60, 550);
	m_bezier.controlPoint_2 = ccp(100, 400);
	m_bezier.endPosition = ccp(400, 700);
	auto actionMove = BezierTo::create(6.0f, m_bezier);

	auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyManager::removeEnemy, this));
	Sequence* sequence = Sequence::create(actionMove, actionDone, NULL); 
	pEnemySprite->runAction(sequence);
}

// 加入敌机4
void EnemyManager::addEnemy4(float dt)
{
	Enemy *pEnemySprite = Enemy::create();
	pEnemySprite->setEnemyByType(Enemy4);
	pEnemySprite->setTag(Enemy4);
	this->addChild(pEnemySprite);
	vecEnemy.pushBack(pEnemySprite);

	// 设置运动轨迹 以及到终点时调用的函数
	ccBezierConfig m_bezier;
	m_bezier.controlPoint_1 = ccp(80, 650);
	m_bezier.controlPoint_2 = ccp(350, 450);
	m_bezier.endPosition = ccp(400, 700);
	auto actionMove = BezierTo::create(8.0f, m_bezier);

	auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyManager::removeEnemy, this));
	
	// 按顺序运行 敌机飞到边缘。敌机移动结束
	Sequence* sequence = Sequence::create(actionMove, actionDone, NULL);
	pEnemySprite->runAction(sequence);
}

void EnemyManager::removeEnemy(Node *pNode)
{
	Enemy* enemy = (Enemy*)pNode;
	if (enemy != NULL)
	{
		this->removeChild(enemy, true);
		vecEnemy.eraseObject(enemy);
	}
}

void EnemyManager::blowupEnemy(Enemy* pEnemySprite)
{
	auto saveData = m_controlLayer->getSaveData();

	Animation *pAnimation = NULL;
	if (Enemy1 == pEnemySprite->getTag())
	{
		// 之前缓存的爆炸动作
		pAnimation = AnimationCache::getInstance()->getAnimation("Enemy1Blowup");
		if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
		{
		}
		if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
		{
			CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/enemy1_down.wav");
		}
		saveData->setScore(saveData->getScore() + ENEMY1_SCORE);	
	}
	else if (Enemy2 == pEnemySprite->getTag())
	{
		pAnimation = AnimationCache::getInstance()->getAnimation("Enemy2Blowup");
		if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
		{
			CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/enemy2_down.wav");
		}
		saveData->setScore(saveData->getScore() + ENEMY2_SCORE);
	}
	else if (Enemy3 == pEnemySprite->getTag())
	{
		pAnimation = AnimationCache::getInstance()->getAnimation("Enemy3Blowup");
		if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
		{
			CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/enemy3_down.wav");
		}
		saveData->setScore(saveData->getScore() + ENEMY3_SCORE);
	}
	else if (Enemy4 == pEnemySprite->getTag())
	{
		pAnimation = AnimationCache::getInstance()->getAnimation("Enemy4Blowup");
		if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
		{
			CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/enemy4_down.wav");
		}
		saveData->setScore(saveData->getScore() + ENEMY4_SCORE);
	}
	else
	{
		return;
	}

	Animate *pAnimate = Animate::create(pAnimation);

	// 爆炸完。要移除敌机
	auto pActionDone = CallFuncN::create(CC_CALLBACK_0(EnemyManager::removeEnemy, this, pEnemySprite)); 
	Sequence* pSequence = Sequence::create(pAnimate, pActionDone, NULL);
	pEnemySprite->getSprite()->runAction(pSequence);
}



每种类型的敌机的爆炸代码比較短,直接在init()函数中进行初始化。为了使游戏难度不断添加,会依据分数来改变加入敌机的速度。敌机的运动轨迹大同小异,只是贝塞尔曲线看起来确实挺不错的。






转载于:https://www.cnblogs.com/clnchanpin/p/7028879.html

相关文章:

  • 先来认识一些UML图标
  • C# 泛型
  • Android使用Canvas画图
  • 14.6 将运算分组为事务
  • bpm功能指标
  • 《Effective Modern C++》翻译--条款4:了解怎样查看推导出的类型
  • nginx 前端调度 对后端的app的生存状态的检测
  • 《计算机科学导论》一1.6计算机科学作为一门学科
  • dede的应用
  • shell--3、Shell 传递参数
  • 网页版俄罗斯方块
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 测试框架Jest
  • 《伟大的计算原理》一交互系统
  • Maven的配置文件pom.xml
  • (三)从jvm层面了解线程的启动和停止
  • “大数据应用场景”之隔壁老王(连载四)
  • axios 和 cookie 的那些事
  • java多线程
  • Joomla 2.x, 3.x useful code cheatsheet
  • js对象的深浅拷贝
  • KMP算法及优化
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • mysql外键的使用
  • PHP 小技巧
  • vue 个人积累(使用工具,组件)
  • 安卓应用性能调试和优化经验分享
  • 产品三维模型在线预览
  • 理清楚Vue的结构
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 排序算法学习笔记
  • 驱动程序原理
  • 人脸识别最新开发经验demo
  • 推荐一个React的管理后台框架
  • 温故知新之javascript面向对象
  • 硬币翻转问题,区间操作
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • puppet连载22:define用法
  • ​​​​​​​​​​​​​​Γ函数
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​低代码平台的核心价值与优势
  • # 计算机视觉入门
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • $(selector).each()和$.each()的区别
  • (BFS)hdoj2377-Bus Pass
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (Java)【深基9.例1】选举学生会
  • (二)丶RabbitMQ的六大核心
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)http协议
  • (轉)JSON.stringify 语法实例讲解
  • **CI中自动类加载的用法总结
  • .bat文件调用java类的main方法