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];
};
}
全文完