C++ 与cocos2d-x-4.0完成太空飞机大战 (四)
动画演示

工具类编码:Util.cpp
#include "Util.h"
namespace SpaceWar {
float Util::FPS = 60.0f;
float Util::D2R(double angle)
{
return angle / 180.0 * (float)M_PI;
}
float Util::R2D(double radian)
{
return radian / (float)M_PI * 180;
}
string Util::getPowerPath(int power)
{
if (power > 5)
{
return "power6.png";
}
else if (power > 4)
{
return "power5.png";
}
else if (power > 3)
{
return "power4.png";
}
else if (power > 2)
{
return "power3.png";
}
else if (power > 1)
{
return "power2.png";
}
else if (power > 0)
{
return "power1.png";
}
return "power0.png";
}
string Util::getArmType(int type)
{
if (type == 0)
{
return "E ";
}
else if (type == 1)
{
return "W ";
}
return "";
}
string Util::getMissileType(int type)
{
if (type == 0)
{
return "M ";
}
else if (type == 1)
{
return "H ";
}
return "";
}
string Util::getBombType(int type)
{
if (type == 0)
{
return "B1";
}
else if (type == 1)
{
return "B2";
}
return "";
}
float Util::getMoveTime(float speed, Vec2 position, Vec2 target)
{
float distance = position.distance(target);
float tspeed = distance / (speed * Util::FPS);
return tspeed;
}
float Util::getMoveTime(float speed, float distance)
{
float tspeed = distance / (speed * Util::FPS);
return tspeed;
}
float Util::getTrackRotation(Vec2 position, Vec2 newPosition)
{
return 90 - atan2(newPosition.y - position.y, newPosition.x - position.x) * 180 / (float)M_PI;
}
Vec2 Util::getTrackPosition(float speed, Vec2 track, Vec2 target)
{
Vec2 delta = target - track;
float distance = track.distance(target);
float x = speed * delta.x / distance;
float y = speed * delta.y / distance;
return Vec2(x, y);
}
string Util::getNearNodeKey(map<string, Node*> *mapNodes, Vec2 position)
{
string s;
if (mapNodes->size() > 0)
{
priority_queue<pair<float, string>, deque<pair<float, string>>, greater<pair<float, string>>> pq;
map<string, Node*>::iterator ite;
int n = 0;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
string key = ite->first;
Node* node = ite->second;
if (node != nullptr)
{
float dis = position.distance(node->getPosition());
pq.push(make_pair(dis, key));
}
}
if (pq.size() > 0)
{
return pq.top().second;
}
}
return s;
}
string Util::getRandomNodeKey(map<string, Node*> *mapNodes)
{
string s;
if (mapNodes->size() > 0)
{
map<string, Node*>::iterator ite;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
Node* node = ite->second;
if (node != nullptr)
{
int rint = random(0, 1);
if (rint == 0)
{
return ite->first;
}
}
}
}
return s;
}
string Util::getRandomNodeKey(map<string, Node*> *mapNodes, Vec2 position)
{
string s;
if (mapNodes->size() > 0)
{
map<string, Node*>::iterator ite;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
Node* node = ite->second;
if (node != nullptr)
{
float dis = position.distance(node->getPosition());
if (dis > 20 && dis < 200)
{
int rint = random(0, 1);
if (rint == 0)
{
return ite->first;
}
}
}
}
}
return s;
}
string Util::getTopNodeKey(map<string, Node*> *mapNodes)
{
string s;
if (mapNodes->size() > 0)
{
map<string, Node*>::iterator ite;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
Node* node = ite->second;
if (node != nullptr)
{
return ite->first;
}
}
}
return s;
}
Node* Util::getNearNode(map<string, Node*> *mapNodes, Vec2 position)
{
Node* node = nullptr;
if (mapNodes->size() > 0)
{
priority_queue<pair<float, string>, deque<pair<float, string>>, greater<pair<float, string>>> pq;
map<string, Node*>::iterator ite;
int n = 0;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
string key = ite->first;
node = ite->second;
if (node != nullptr)
{
float dis = position.distance(node->getPosition());
pq.push(make_pair(dis, key));
}
}
if (pq.size() > 0)
{
string key = pq.top().second;
return findNode(mapNodes, key);
}
}
return node;
}
Node* Util::getRandomNode(map<string, Node*> *mapNodes)
{
Node* node = nullptr;
if (mapNodes->size() > 0)
{
vector<string> vlist;
map<string, Node*>::iterator ite;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
node = ite->second;
if (node != nullptr)
{
vlist.push_back(ite->first);
}
}
if (vlist.size() > 0)
{
string key = vlist[random(0, (int)vlist.size() - 1)];
return findNode(mapNodes, key);
}
}
return node;
}
Node* Util::getRandomNode(map<string, Node*> *mapNodes, float minDistance, float maxDistance, Vec2 position)
{
Node* node = nullptr;
if (mapNodes->size() > 0)
{
vector<string> vlist;
map<string, Node*>::iterator ite;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
node = ite->second;
if (node != nullptr)
{
float dis = position.distance(node->getPosition());
if (dis > minDistance && dis < maxDistance)
{
vlist.push_back(ite->first);
}
}
}
if (vlist.size()>0)
{
string key = vlist[random(0, (int)vlist.size()-1)];
return findNode(mapNodes, key);
}
}
return node;
}
Node* Util::getTopNode(map<string, Node*> *mapNodes)
{
Node* node = nullptr;
if (mapNodes->size() > 0)
{
map<string, Node*>::iterator ite;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
node = ite->second;
if (node != nullptr)
{
return node;
}
}
}
return node;
}
Node* Util::getEndNode(map<string, Node*> *mapNodes)
{
Node* node = nullptr;
if (mapNodes->size() > 0)
{
map<string, Node*>::iterator ite;
for (ite = mapNodes->begin(); ite != mapNodes->end(); ite++)
{
Node* nodea = ite->second;
if (nodea != nullptr)
{
node = nodea;
}
}
}
return node;
}
Node* Util::findNode(map<string, Node*> *mapNodes, string key)
{
Node* node = nullptr;
map<string, Node*>::iterator ite;
ite = mapNodes->find(key);
if (ite != mapNodes->end()) {
node = ite->second;
}
return node;
}
unsigned int Util::getRandomChar()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 255);
return dis(gen);
}
std::string Util::getGUID(const unsigned int len)
{
std::stringstream ss;
for (auto i = 0; i < len; i++) {
const auto rc = getRandomChar();
std::stringstream hexstream;
hexstream << std::hex << rc;
auto hex = hexstream.str();
ss << (hex.length() < 2 ? '0' + hex : hex);
}
return ss.str();
}
std::string Util::getGUID()
{
return getGUID(32);
}
string Util::leftCover(int num)
{
return leftCover(num, 2, '0');
}
string Util::leftCover(int num, int coverCount)
{
return leftCover(num, coverCount, '0');
}
string Util::leftCover(int num, int coverCount, char s)
{
stringstream ls;
ls << setw(coverCount) << setfill(s) << num;
return ls.str();
}
string Util::leftCover(long num)
{
return leftCover(num, 2, '0');
}
string Util::leftCover(long num, int coverCount)
{
return leftCover(num, coverCount, '0');
}
string Util::leftCover(long num, int coverCount, char s)
{
stringstream ls;
ls << setw(coverCount) << setfill(s) << num;
return ls.str();
}
string Util::leftCover(string str)
{
return leftCover(str, 2, '0');
}
string Util::leftCover(string str, int coverCount)
{
return leftCover(str, coverCount, '0');
}
string Util::leftCover(string str, int coverCount, char s)
{
stringstream ls;
ls << setw(coverCount) << setfill(s) << str;
return ls.str();
}
Vec2 * Util::getVec2(PolygonInfo pi, Size size)
{
auto indices = pi.triangles.indices;
auto verts = pi.triangles.verts;
Vec2* vec2 = new Vec2[pi.triangles.indexCount];
for (int i = 0; i < pi.triangles.indexCount; i++)
{
vec2[i].x = verts[indices[i]].vertices.x - size.width / 2;
vec2[i].y = verts[indices[i]].vertices.y - size.height / 2;
}
return vec2;
}
PhysicsBody* Util::getPhysicsBody(PolygonInfo pi, Size size, int tag, int category, int collision, int contactTest, bool gravityEnable)
{
Vec2* ver2 = Util::getVec2(pi, size);
auto body = PhysicsBody::createPolygon(ver2, pi.triangles.indexCount);
body->setTag(tag);
body->setCategoryBitmask(category);
body->setCollisionBitmask(collision);
body->setContactTestBitmask(contactTest);
body->setGravityEnable(gravityEnable);
return body;
}
PhysicsBody* Util::getPhysicsBody(Size size, int tag, int category, int collision, int contactTest, bool gravityEnable)
{
auto body = PhysicsBody::createBox(size);
body->setTag(tag);
body->setCategoryBitmask(category);
body->setCollisionBitmask(collision);
body->setContactTestBitmask(contactTest);
body->setGravityEnable(gravityEnable);
return body;
}
Vector<SpriteFrame*> Util::getAnimation(const char *format, int count)
{
auto spritecache = SpriteFrameCache::getInstance();
Vector<SpriteFrame*> animFrames;
char str[100];
for (int i = 1; i <= count; i++)
{
sprintf(str, format, i);
auto name = spritecache->getSpriteFrameByName(str);
animFrames.pushBack(name);
}
return animFrames;
}
long Util::getLongTime() {
std::chrono::steady_clock::duration d = std::chrono::steady_clock::now().time_since_epoch();
std::chrono::milliseconds mil = std::chrono::duration_cast<std::chrono::milliseconds>(d);
return mil.count();
}
bool Util::isIntervalTime(long interval, long* time)
{
long now = Util::getLongTime();
long enemyInterval = now - *time;
if (enemyInterval < interval)
{
return false;
}
*time = now;
return true;
}
bool Util::isIntervalTime(long interval, long* baseTime, long* time)
{
long now = Util::getLongTime();
long enemyInterval = now - *time;
if (*time > 0)
{
*baseTime += enemyInterval;
}
if (enemyInterval < interval)
{
return false;
}
*time = now;
return true;
}
void Util::onKeyPressed(EventKeyboard::KeyCode keyCode, Control* conAct)
{
switch (keyCode) {
case EventKeyboard::KeyCode::KEY_W: {
conAct->controlAct[0] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_S: {
conAct->controlAct[1] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_A: {
conAct->controlAct[2] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_D: {
conAct->controlAct[3] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_SPACE: {
conAct->controlAct[4] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_B: {
conAct->controlAct[5] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_UP_ARROW: {
conAct->controlAct[100] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_DOWN_ARROW: {
conAct->controlAct[101] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_LEFT_ARROW: {
conAct->controlAct[102] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_RIGHT_ARROW: {
conAct->controlAct[103] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_0: {
conAct->controlAct[104] = 1;
break;
}
case EventKeyboard::KeyCode::KEY_1: {
conAct->controlAct[105] = 1;
break;
}
default:
break;
}
}
void Util::onKeyReleased(EventKeyboard::KeyCode keyCode, Control* conAct)
{
switch (keyCode) {
case EventKeyboard::KeyCode::KEY_W: {
conAct->controlAct[0] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_S: {
conAct->controlAct[1] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_A: {
conAct->controlAct[2] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_D: {
conAct->controlAct[3] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_SPACE: {
conAct->controlAct[4] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_B: {
conAct->controlAct[5] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_UP_ARROW: {
conAct->controlAct[100] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_DOWN_ARROW: {
conAct->controlAct[101] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_LEFT_ARROW: {
conAct->controlAct[102] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_RIGHT_ARROW: {
conAct->controlAct[103] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_0: {
conAct->controlAct[104] = 0;
break;
}
case EventKeyboard::KeyCode::KEY_1: {
conAct->controlAct[105] = 0;
break;
}
default:
break;
}
}
bool Util::spriteSceneMove(int act, Sprite* sprite, Size vsize, Size ssize, Vec2 position, float speed)
{
if (act == 0)
{
float s = vsize.height - (ssize.height / 2) - (position.y + speed);
if (s > 0)
{
auto moveBy = MoveBy::create(0.0f, Vec2(0, speed));
sprite->runAction(moveBy);
}
}
else if (act == 1)
{
float s = (position.y - speed) - (ssize.height / 2);
if (s > 0)
{
auto moveBy = MoveBy::create(0.0f, Vec2(0, -speed));
sprite->runAction(moveBy);
}
}
else if (act == 2)
{
float s = (position.x - speed) - (ssize.width / 2);
if (s > 0)
{
auto moveBy = MoveBy::create(0.0f, Vec2(-speed, 0));
sprite->runAction(moveBy);
}
}
else if (act == 3)
{
float s = vsize.width - (ssize.width / 2) - (position.x + speed);
if (s > 0)
{
auto moveBy = MoveBy::create(0.0f, Vec2(speed, 0));
sprite->runAction(moveBy);
}
}
return false;
}
bool Util::isOutScene(Node* node, Size vsize)
{
Vec2 nPosition = node->getPosition();
Size nSize = node->getBoundingBox().size;
if (nPosition.y + nSize.height < 0)
{
return true;
}
if (vsize.height - nPosition.y + nSize.height < 0)
{
return true;
}
if (nPosition.x + nSize.width < 0)
{
return true;
}
if (vsize.width - nPosition.x + nSize.width < 0)
{
return true;
}
return false;
}
}
工具类编码:Util.h
#pragma once
#include <vector>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <set>
#include "cocos2d.h"
#include "Control.h"
using namespace std;
using namespace cocos2d;
namespace SpaceWar
{
class Util
{
public:
static float FPS;
static float D2R(double angle);
static float R2D(double radian);
static string getPowerPath(int power);
static string getArmType(int type);
static string getMissileType(int type);
static string getBombType(int type);
static float getMoveTime(float speed, Vec2 position, Vec2 target);
static float getMoveTime(float speed, float distance);
static float getTrackRotation(Vec2 position, Vec2 newPosition);
static Vec2 getTrackPosition(float speed, Vec2 track, Vec2 target);
static string getNearNodeKey(map<string, Node*>* mapNodes, Vec2 position);
static string getRandomNodeKey(map<string, Node*>* mapNodes);
static string getRandomNodeKey(map<string, Node*>* mapNodes, Vec2 position);
static string getTopNodeKey(map<string, Node*>* mapNodes);
static Node * getNearNode(map<string, Node*>* mapNodes, Vec2 position);
static Node * getRandomNode(map<string, Node*>* mapNodes);
static Node * getRandomNode(map<string, Node*>* mapNodes, float minDistance, float maxDistance, Vec2 position);
static Node * getTopNode(map<string, Node*>* mapNodes);
static Node * getEndNode(map<string, Node*>* mapNodes);
static Node * findNode(map<string, Node*>* mapNodes, string key);
static unsigned int getRandomChar();
static std::string getGUID(const unsigned int len);
static std::string getGUID();
static string leftCover(int num);
static string leftCover(int num, int coverCount);
static string leftCover(int num, int coverCount, char s);
static string leftCover(long num);
static string leftCover(long num, int coverCount);
static string leftCover(long num, int coverCount, char s);
static string leftCover(string str);
static string leftCover(string str, int coverCount);
static string leftCover(string str, int coverCount, char s);
static Vec2* getVec2(PolygonInfo pi, Size size);
static PhysicsBody * getPhysicsBody(PolygonInfo pi, Size size, int tag, int category, int collision, int contactTest, bool gravityEnable);
static PhysicsBody * getPhysicsBody(Size size, int tag, int category, int collision, int contactTest, bool gravityEnable);
static Vector<SpriteFrame*> getAnimation(const char * format, int count);
static long getLongTime();
static bool isIntervalTime(long interval, long * time);
static bool isIntervalTime(long interval, long* baseTime, long * time);
static void onKeyPressed(EventKeyboard::KeyCode keyCode, Control* conAct);
static void onKeyReleased(EventKeyboard::KeyCode keyCode, Control* conAct);
static bool spriteSceneMove(int act, Sprite* sprite, Size vsize, Size ssize, Vec2 position, float speed);
static bool isOutScene(Node * node, Size vsize);
};
}
奖励精灵编码:RewardSprite.cpp
#include "RewardSprite.h"
#include "ActionBase.h"
#include "Util.h"
namespace SpaceWar {
RewardSprite::RewardSprite()
{
}
RewardSprite::~RewardSprite()
{
}
void RewardSprite::update(float dt)
{
}
}
奖励精灵编码:RewardSprite.h
#pragma once
#include "cocos2d.h"
#include "SpriteBase.h"
using namespace std;
using namespace cocos2d;
namespace SpaceWar
{
class ActionBase;
class RewardSprite : public SpriteBase
{
public:
RewardSprite();
virtual ~RewardSprite();
void update(float dt);
ActionBase* actBase = nullptr;
int rewardType = 0;
float flightSpeed = 8.0f;
int rewardScore = -1;
int airSpeed = -1;
int armPower = -1;
int armType = -1;
int missilePower = -1;
int missileType = -1;
int bombCount = -1;
int bombType = -1;
int collisionCount = 0;
int maxCollisionCount = 0;
int category = 0b111;
int collision = 0b000;
int contact = 0b110;
bool gravityEnable = false;
};
}
飞机奖励编码:RewardQueue.cpp
#include "RewardQueue.h"
namespace SpaceWar {
RewardQueue::RewardQueue()
{
}
RewardQueue::~RewardQueue()
{
}
}
飞机奖励编码:RewardQueue.h
#pragma once
#include "cocos2d.h"
using namespace std;
using namespace cocos2d;
namespace SpaceWar
{
class RewardQueue
{
public:
RewardQueue();
virtual ~RewardQueue();
int rewardType = 0;
float x = 0.0f;
float y = 0.0f;
int rewardScore = -1;
int airSpeed = -1;
int armPower = -1;
int armType = -1;
int bombCount = -1;
int bombType = -1;
};
}
奖励形状编码:RewardPolygonInfo.cpp
#include "RewardPolygonInfo.h"
namespace SpaceWar {
RewardPolygonInfo::RewardPolygonInfo(string rinfo, int rmark)
{
this->rewardInfo = rinfo;
this->rewardMark = rmark;
}
RewardPolygonInfo::~RewardPolygonInfo()
{
}
}
奖励形状编码:RewardPolygonInfo.cpp
#include "cocos2d.h"
using namespace std;
using namespace cocos2d;
#pragma once
namespace SpaceWar
{
class RewardPolygonInfo
{
public:
RewardPolygonInfo(string rinfo, int rmark);
virtual ~RewardPolygonInfo();
string rewardInfo;
int rewardMark = -1;
};
}
C++ 与cocos2d-x-4.0完成太空飞机大战 (五)