C++ 与cocos2d-x-4.0完成太空飞机大战 (五)

动画演示

游戏画面演示

敌人精灵编码:EnemySprite.cpp

#include "EnemySprite.h"
#include "ActionBase.h"
#include "Util.h"

namespace SpaceWar {

	EnemySprite::EnemySprite()
	{
	}

	EnemySprite::~EnemySprite()
	{
	}

	void EnemySprite::update(float dt)
	{

	}
}

敌人精灵编码:EnemySprite.h

#pragma once
#include "cocos2d.h"
#include "SpriteBase.h"

using namespace std;
using namespace cocos2d;

namespace SpaceWar
{
	class ActionBase;

	class EnemySprite : public SpriteBase
	{
	public:
		EnemySprite();
		virtual ~EnemySprite();

		void update(float dt);

		ActionBase* actBase = nullptr;

		/*敌人类型*/
		int enemyType = 0;

		/*杀死得分*/
		int killScore = 0;

		/*敌人速度*/
		float enemySpeed = 10.0f;

		/*武器威力*/
		int armPower = 6;

		/*武器类型*/
		int armType = 0;

		/*武器上次发射时间*/
		long armTime = 0;

		/*碰撞次数*/
		int collisionCount = 0;

		/*最大碰撞次数*/
		int maxCollisionCount = 0;

		/*碰撞类型掩码*/
		int category = 0b111;

		/*碰撞掩码*/
		int collision = 0b000;

		/*碰撞事件掩码*/
		int contact = 0b110;

		/*是否允许重力*/
		bool gravityEnable = false;

		/*是否允许碰撞*/
		bool collisionEnable = false;
	};
}


敌人编码:Enemy.cpp

#include "Enemy.h"
#include "ActionBase.h"

namespace SpaceWar {

	Enemy::Enemy()
	{
	}

	Enemy::~Enemy()
	{
	}

	bool Enemy::createEnemy(int eType)
	{
		enemyType = eType;
		string enemyImg = getEnemyImg();
		auto pinfo = AutoPolygon::generatePolygon(enemyImg);
		sprite = new EnemySprite();
		sprite->actBase = this->actBase;
		EnemySprite::create(sprite, pinfo);
		if (sprite != nullptr)
		{
			sprite->setName(Util::getGUID(32));
			int tag = 10;
			sprite->enemyType = eType;
			auto size = sprite->getContentSize();
			auto body = Util::getPhysicsBody(pinfo, size, tag, sprite->category, sprite->collision, sprite->contact, sprite->gravityEnable);
			sprite->setPhysicsBody(body);
			sprite->setTag(tag);
			return true;
		}
		return false;
	}

	void Enemy::setMaxCollisionCount(EnemySprite* es, int eType)
	{
		Size ssize = es->getBoundingBox().size;
		float wh = ssize.width;
		if (ssize.height > ssize.width)
		{
			wh = ssize.height;
		}
		es->maxCollisionCount = 1;
		es->killScore = 1;
		if (eType==0) 
		{
			if (wh > 300)
			{
				es->maxCollisionCount = 20;
				es->killScore = 20;
			}
			else if (wh > 250)
			{
				es->maxCollisionCount = 16;
				es->killScore = 16;
			}
			else if (wh > 200)
			{
				es->maxCollisionCount = 12;
				es->killScore = 12;
			}
			else if (wh > 150)
			{
				es->maxCollisionCount = 8;
				es->killScore = 8;
			}
			else if (wh > 100)
			{
				es->maxCollisionCount = 6;
				es->killScore = 6;
			}
			else if (wh > 50)
			{
				es->maxCollisionCount = 4;
				es->killScore = 4;
			}
			else if (wh > 20)
			{
				es->maxCollisionCount = 2;
				es->killScore = 2;
			}
		}
	}

	string Enemy::getEnemyImg() {
		string s = "";
		if (enemyType == 0)
		{
			s = "ys" + to_string(random(1, 4)) + ".png";
		}
		else if (enemyType == 1)
		{
			s = "enemy/e_air01.png";
		}
		return s;
	}
}

敌人编码:Enemy.h

#pragma once
#include <vector>
#include "cocos2d.h"
#include "Util.h"
#include "EnemySprite.h"

using namespace std;
using namespace cocos2d;

namespace SpaceWar
{
	class ActionBase;

	class Enemy
	{
	public:
		Enemy();
		virtual ~Enemy();

		ActionBase* actBase = nullptr;

		/*敌人精灵*/
		EnemySprite* sprite;

		/*敌人类型*/
		int enemyType = 0;

		/*初始化敌人*/
		virtual bool createEnemy(int aType);

		/*设置最大碰撞次数*/
		void setMaxCollisionCount(EnemySprite * es, int eType);

		/*根据敌人类型返回对应图片*/
		string getEnemyImg();

	};
}


关卡1敌人编码:EnemyScene1.cpp

#include "EnemyScene1.h"
#include "renderer/backend/Device.h"
#include "ActionBase.h"

USING_NS_CC;

namespace SpaceWar {

	EnemyScene1::EnemyScene1()
	{
	}

	EnemyScene1::~EnemyScene1()
	{
	}

	bool EnemyScene1::createEnemys()
	{
		if (!Util::isIntervalTime(100, &baseTime, &enemyTime[0]))
		{
			return false;
		}
		createMeteorite();
		createEnemyAircraft();
	}

	bool EnemyScene1::createMeteorite()
	{
		if (baseTime < 100000)
		{
			return createMeteorite(200, 0.1f, 0.5f, 10.0f);
		}
		else if (baseTime < 200000)
		{
			return createMeteorite(200, 0.1f, 1.0f, 10.0f);
		}
		else
		{
			return createMeteorite(200, 0.1f, 1.5f, 8.0f);
		}
	}

	bool EnemyScene1::createEnemyAircraft()
	{
		if (baseTime < 10000) 
		{
		}
		else if (baseTime < 100000)
		{
			return createEnemyAircraft(10000, 100, 100, 20.0f);
		}
		else if (baseTime < 200000)
		{
			return createEnemyAircraft(10000, 200, 200, 20.0f);
		}
		else
		{
			return createEnemyAircraft(10000, 400, 400, 20.0f);
		}
	}

	bool EnemyScene1::createMeteorite(int delayTime, float sScale, float eScale, float speed)
	{
		if (!Util::isIntervalTime(delayTime, &enemyTime[500]))
		{
			return false;
		}
		Enemy enemy;
		enemy.actBase = this->actBase;
		if (enemy.createEnemy(0))
		{
			enemy.sprite->enemySpeed = speed;
			enemy.sprite->setScale(random(sScale, eScale));
			enemy.sprite->setRotation(random(0.0f, 360.0f));
			enemy.setMaxCollisionCount(enemy.sprite, enemy.enemyType);
			int sHeight = enemy.sprite->getContentSize().height;
			float px = actBase->origin.x + random(0.0f, actBase->vSize.width);
			float py = actBase->vSize.height + actBase->origin.y + sHeight * 2 + random(0.0f, actBase->vSize.height);
			enemy.sprite->setPosition(Vec2(px, py));
			actBase->addChild(enemy.sprite, 0);
			auto moveTo = MoveTo::create(enemy.sprite->enemySpeed, Vec2(px, -(sHeight * 2)));
			auto actRuin = CallFunc::create(std::bind(&EnemyScene1::removeRuin, this, enemy.sprite));
			auto sequence = Sequence::create(moveTo, actRuin, NULL);
			enemy.sprite->runAction(sequence);
			return true;
		}
		return false;
	}

	bool EnemyScene1::createEnemyAircraft(int delayTime, int score, int collision, float speed)
	{
		if (!Util::isIntervalTime(delayTime, &enemyTime[501]))
		{
			return false;
		}
		Enemy enemy;
		enemy.actBase = this->actBase;
		if (enemy.createEnemy(1))
		{
			enemy.sprite->enemySpeed = speed;
			enemy.sprite->maxCollisionCount = collision;
			enemy.sprite->killScore = score;
			enemy.sprite->enemySpeed = 20.0f;
			int sHeight = enemy.sprite->getContentSize().height;
			float px = actBase->origin.x + random(0.0f, actBase->vSize.width);
			float py = actBase->vSize.height + actBase->origin.y + sHeight * 2 + random(0.0f, actBase->vSize.height);
			enemy.sprite->setPosition(Vec2(px, py));
			actBase->addChild(enemy.sprite, 4);
			auto moveTo = MoveTo::create(enemy.sprite->enemySpeed, Vec2(px, -(sHeight * 2)));
			auto actRuin = CallFunc::create(std::bind(&EnemyScene1::removeRuin, this, enemy.sprite));
			auto sequence = Sequence::create(moveTo, actRuin, NULL);
			enemy.sprite->runAction(sequence);
			return true;
		}
		return false;
	}

	void EnemyScene1::createRuinAnimate(Node* node)
	{
		EnemySprite* eSprite = dynamic_cast<EnemySprite*>(node);
		if (eSprite->enemyType==1) 
		{
			createSerialBombRuinAnimate(eSprite);
		}
		else 
		{
			createRuinAnimate(eSprite);
		}
	}

	void EnemyScene1::createChangeColorAnimate(Node* node)
	{
		EnemySprite* eSprite = dynamic_cast<EnemySprite*>(node);
		if (eSprite->enemyType == 1)
		{
			createChangeColorAnimate(eSprite);
		}
	}

	void EnemyScene1::createChangeColorAnimate(EnemySprite* eSprite)
	{
		/*auto * fu = FileUtils::getInstance();
		auto vertexShader = fu->getStringFromFile("shaders/example_ColorBars.vsh");
		auto fragmentShader = fu->getStringFromFile("shaders/example_ColorBars.fsh");
		auto program = backend::Device::getInstance()->newProgram(vertexShader.c_str(), fragmentShader.c_str());
		auto programState = new backend::ProgramState(program);
		eSprite->setProgramState(programState);*/
	}

	void EnemyScene1::createRuinAnimate(EnemySprite* eSprite)
	{
		auto size = eSprite->getBoundingBox().size;
		auto position = eSprite->getPosition();
		SpriteFrameCache::getInstance()->addSpriteFramesWithFile("ysbz.plist");
		auto frames = Util::getAnimation("ysbz-%d.png", 16);
		auto sprite = Sprite::createWithSpriteFrame(frames.front());
		auto ssize = sprite->getContentSize();
		auto wf = size.width / ssize.width;
		auto hf = size.height / ssize.height;
		sprite->setScale(wf, hf);
		sprite->setPosition(position.x, position.y);
		actBase->addChild(sprite);

		auto animation = Animation::createWithSpriteFrames(frames, 1.0f / 16);
		auto animate = Animate::create(animation);
		auto repeat = Repeat::create(animate, 1);
		auto actRuin = CallFunc::create(std::bind(&EnemyScene1::removeRuin, this, sprite));
		auto sequence = Sequence::create(repeat, actRuin, NULL);
		playBOMB(eSprite);
		sprite->runAction(sequence);
	}

	void EnemyScene1::createSerialBombRuinAnimate(EnemySprite* eSprite)
	{
		Vec2 svec = eSprite->getPosition();
		Size size = eSprite->getBoundingBox().size;
		float sw = svec.x - size.width / 2;
		float ew = svec.x + size.width / 2;
		float sh = svec.y - size.height / 2;
		float eh = svec.y + size.height / 2;
		SpriteFrameCache::getInstance()->addSpriteFramesWithFile("fjbz.plist");
		auto frames = Util::getAnimation("fjbz(%d).png", 16);
		int tag = 6;
		for (int i = 0; i < 50; ++i)
		{
			auto delayAnimate = CallFunc::create(std::bind(&EnemyScene1::createSerialBombRuin, this, frames, sw, ew, sh, eh));
			auto dtime = DelayTime::create(random(0.0f, 1.0f));
			auto sequence = Sequence::create(dtime, delayAnimate, NULL);
			actBase->runAction(sequence);
		}
	}

	void EnemyScene1::createSerialBombRuin(Vector<SpriteFrame*> frames, float sw, float ew, float sh, float eh)
	{
		auto bsprite = Sprite::createWithSpriteFrame(frames.front());
		bsprite->setScale(random(1.0f, 2.0f));
		bsprite->setPosition(Vec2(random(sw, ew), random(sh, eh)));
		auto animation = Animation::createWithSpriteFrames(frames, 1.0f / 16);
		auto animate = Animate::create(animation);
		auto repeat = Repeat::create(animate, 1);
		auto actRuin = CallFunc::create(std::bind(&EnemyScene1::removeRuin, this, bsprite));
		auto sequence = Sequence::create(repeat, actRuin, NULL);
		bsprite->runAction(sequence);
		float mtime = random(0.2f, 1.0f);
		Vec2 move = Vec2(0.0f, random(-100.0f, -50.0f));
		auto moveBy = MoveBy::create(mtime, move);
		bsprite->runAction(moveBy);
		actBase->addChild(bsprite, 3);
		AudioEngine::play2d("BOMB1.ogg", false, 0.5f);
	}

	void EnemyScene1::playBOMB(EnemySprite* eSprite)
	{
		auto size = eSprite->getBoundingBox().size;
		float sz = size.height;
		if (size.width > size.height)
		{
			sz = size.width;
		}
		if (eSprite->enemyType == 0)
		{
			if (sz > 300)
			{
				AudioEngine::play2d("BOMB6.ogg", false, 0.5f);
			}
			else if (sz > 250)
			{
				AudioEngine::play2d("BOMB5.ogg", false, 0.5f);
			}
			else if (sz > 200)
			{
				AudioEngine::play2d("BOMB4.ogg", false, 0.5f);
			}
			else if (sz > 100)
			{
				AudioEngine::play2d("BOMB3.ogg", false, 0.5f);
			}
			else if (sz > 50)
			{
				AudioEngine::play2d("BOMB2.ogg", false, 0.5f);
			}
			else
			{
				AudioEngine::play2d("BOMB1.ogg", false, 0.5f);
			}
		}
	}

	void EnemyScene1::removeRuin(Sprite* sprite)
	{
		actBase->enemyNodes.erase(sprite->getName());
		sprite->removeFromParentAndCleanup(true);
	}

	Sprite* EnemyScene1::createRuinSprite()
	{
		SpriteFrameCache::getInstance()->addSpriteFramesWithFile("ysbz.plist");
		auto frames = Util::getAnimation("ysbz-%d.png", 16);
		auto sprite = Sprite::createWithSpriteFrame(frames.front());
		return sprite;
	}
}

关卡1敌人编码:EnemyScene1.h

#pragma once
#include <vector>
#include "cocos2d.h"
#include "audio/include/AudioEngine.h"
#include "Enemy.h"
#include "Util.h"

using namespace std;
using namespace cocos2d;

namespace SpaceWar
{
	class ActionBase;

	class EnemyScene1
	{
	public:
		EnemyScene1();

		virtual ~EnemyScene1();

		bool createEnemys();

		ActionBase* actBase = nullptr;
		
		bool createMeteorite();

		bool createEnemyAircraft();

		bool createMeteorite(int delayTime, float sScale, float eScale, float speed);

		bool createEnemyAircraft(int delayTime, int score, int collision, float speed);

		void createRuinAnimate(Node * node);

		void createChangeColorAnimate(Node * node);

		void createChangeColorAnimate(EnemySprite * eSprite);

		void createRuinAnimate(EnemySprite * eSprite);

		void createSerialBombRuinAnimate(EnemySprite * eSprite);

		void createSerialBombRuin(Vector<SpriteFrame*> frames, float sw, float ew, float sh, float eh);

		void playBOMB(EnemySprite * eSprite);

		void removeRuin(Sprite * sprite);

		Sprite * createRuinSprite();

		long enemyTime[1000];

		long baseTime = 0;
	};
}


控制器编码:Control.cpp

#include "Control.h"

namespace SpaceWar {

	Control::Control()
	{
	}

	Control::~Control()
	{
	}
}

控制器编码:Control.h

#pragma once
namespace SpaceWar
{
	class Control
	{
	public:
		Control();
		virtual ~Control();
		int controlAct[400];
	};
}


全文完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: cocos2d-x 4. 学习之路 cocos2d-x是一款开源的跨平台游戏引擎,支持多种平台,包括iOS、Android、Windows、Mac OS X等。cocos2d-x 4.是最新版本,相比之前版本,它有很多新特性和改进,如增强的渲染性能、更好的3D支持、更好的物理引擎等。 如果你想学习cocos2d-x 4.,可以从以下几个方面入手: 1. 学习基础知识:了解cocos2d-x的基本概念、架构和工作原理,掌握cocos2d-x的编程语言和开发环境。 2. 学习API:熟悉cocos2d-x的API,包括场景管理、精灵、动画、音频、物理引擎等。 3. 学习示例代码:通过阅读和分析cocos2d-x的示例代码,了解如何使用cocos2d-x开发游戏。 4. 学习实践:通过实践开发小游戏,掌握cocos2d-x的开发流程和技巧,提高自己的编程能力。 总之,学习cocos2d-x 4.需要一定的时间和耐心,但只要你有兴趣和热情,相信你一定能够掌握它。 ### 回答2: cocos2d-x是一个强大的游戏引擎,可用于开发移动和桌面游戏。随着cocos2d-x更新至4.0版本,它的功能得到了大幅升级。如果你想学习cocos2d-x 4.0,以下是一些重要的步骤和建议。 1. 更改代码结构 cocos2d-x 4.0中启用了新的代码结构,旨在更好地实现模块化和解耦。新代码结构包括Core、Renderer、2d等模块,使代码更易于维护和升级。要理解新代码结构,请先阅读cocos2d-x官方文档,并针对各个模块学习和熟悉其API。 2. 学习新功能 cocos2d-x 4.0中引入了许多新功能,例如Shader、Render Queue等。学习新功能是非常必要的,因为它们将改变以前的游戏开发模式。了解这些新功能的实现原理,并在自己的项目中应用它们,有助于提高游戏性能和质量。 3. 学习C++11 cocos2d-x 4.0开始支持C++11标准,这意味着你可以使用C++11的新特性来编写更好的代码。要理解C++11的特性,建议通读一遍C++11的官方标准,并尝试在cocos2d-x项目中使用这些新特性。 4. 实战练习 最后,实战练习是学习任何技能的关键。为了更好地学习cocos2d-x 4.0,建议你尝试开发自己的游戏项目。通过尝试解决实际问题,你能更好地理解cocos2d-x的API,并在实践中掌握游戏开发的技术。 总而言之,学习cocos2d-x 4.0需要掌握新的代码结构、新的功能和C++11标准,并通过实际项目实战练习来加深理解。这需要一定的时间和耐心,但只要你认真学习、实践和不断尝试,必定能够取得成功。 ### 回答3: cocos2d-x 4.0是目前市面上非常流行的开源游戏开发引擎,在游戏开发领域有着较为广泛的应用。然而,学习cocos2d-x 4.0需要付出一定的努力和时间。以下是我对cocos2d-x 4.0学习之路的一些经验和建议。 1. 学习基础知识 在开始学习cocos2d-x 4.0之前,我们需要了解一些基础知识,比如C++语言、OpenGL ES等,这些都是cocos2d-x 4.0的底层实现技术。掌握这些基础知识会让我们从事游戏开发时更加得心应手。 2. 学习文档 学习cocos2d-x 4.0需要阅读官方文档,这些文档详细介绍了引擎的各个方面,而且是学习的最佳资料。文档里包括了引擎的安装、使用、开发以及调试等。建议大家先从官网下载文档,并且仔细阅读。 3. 实践和开发 掌握了基础知识以及学习了文档之后,最好的方式就是通过实践和开发来加深对cocos2d-x 4.0的理解。通过实际开发游戏来体验引擎的使用,这样能够更深刻的理解引擎的机制以及遇到的各种问题该如何解决。同时,通过找到一些相近的问题,并通过查阅文档、代码实现等方式来解决问题,可以增强自己的技术水平。 4. 参与社区 cocos2d-x 4.0的官方论坛以及社区非常活跃,里面的开发者也有着丰富的经验和技术,在学习中可以多向论坛、社区里的大牛请教,获得更多的技术指导,同时也可以参与讨论,提出自己的问题和思考来获得反馈,这样可以更快地提高自己的技术。 总之,学习cocos2d-x 4.0需要耐心和对游戏开发的热情。只有通过不断的学习与实践,我们才能最终掌握这个优秀的游戏开发引擎,从而创建属于自己的游戏作品。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值