豪华版飞机大战系列(六)--附源码

最后一篇讲一下游戏中的主要逻辑判断,在上面的工作都做充分准备后,游戏主要逻辑将变得特别清晰,接下来你会看到所有的逻辑都是那么的清晰自然,因为前面已经做好了充分的准备工作,这里只是整合了前面的工作,稍微加入了一些游戏判断元素。

同时源码会在文章最后给出链接地址,源码托管在github上,所有的东西都是开源免费的,在现在的大环境下,开源才是王道,分享才能双赢,我始终觉得这是对的,你有一种思想我有一种思想,交流分享后我们都有了两种思想,何乐而不为呢。

好了,回归正题,游戏主要判断逻辑都在GameScene场景中,其中包括了GameLayer层,在层中进行游戏的逻辑判断。

来看一下GameScene.h的内容:

#include "cocos2d.h"
#include "PlaneLayer.h"
#include "BulletSprite.h"
#include "EnemyLayer.h"

USING_NS_CC;

class GameLayer: public cocos2d::Layer {
public:
//创建GameLayer层所属的场景
static cocos2d::Scene* createScene();
virtual bool init();
//在onEnter执行完成之后调用此函数
virtual void onEnterTransitionDidFinish();
CREATE_FUNC(GameLayer);

public:
//根据每帧来更新游戏
void gameUpdate(float dt);
//子弹碰撞检测
bool bulletCollisionEnemy(Sprite* pBullet);
//飞机碰撞检测
bool enemyCollisionPlane();
//menu回调函数
void menuCloseCallback(cocos2d::Ref* pSender);
public:
PlaneLayer *planeLayer;//飞机层
BulletSprite *bulletSprite;//子弹层
EnemyLayer *enemyLayer;//敌机层


int getRand(int start, int end);//获取从start到end的随机数
};

```


不做太多解释,直接看各个函数的具体实现,GameScene.cpp
#include "GameScene.h"
/**
 * 创建场景,并添加GameLayer层
 */
cocos2d::Scene* GameLayer::createScene() {
auto scene = Scene::create();
auto layer = GameLayer::create();
scene->addChild(layer);
return scene;
}


bool GameLayer::init() {
if (!Layer::init()) {
return false;
}
this->setTouchEnabled(true);//设置层中可触摸点击
Size winSize = Director::getInstance()->getWinSize();
/**
  * 随即加载背景图片,
  */
char buff;
int id = getRand(1, 5);//返回1~5之间的随机数
sprintf(buff, "img_bg_%d.jpg", id);
auto over = Sprite::create(buff);
over->setPosition(Point(winSize.width / 2, winSize.height / 2));
this->addChild(over);
return true;
}
/**
 * 返回从start到end的随机整数
 */
int GameLayer::getRand(int start, int end) {
struct timeval tv;
gettimeofday(&tv, NULL);
unsigned long int rand_seed = tv.tv_sec * 1000 + tv.tv_usec / 1000;//随机数种子
srand(rand_seed);
float i = CCRANDOM_0_1() * (end - start + 1) + start;
return (int) i;
}
/**
 * 在onEnter函数之后调用
 * 功能:创建飞机、子弹、敌机并添加到层中
 */
void GameLayer::onEnterTransitionDidFinish() {
planeLayer = PlaneLayer::create();
this->addChild(planeLayer);
bulletSprite = BulletSprite::create();
this->addChild(bulletSprite);
enemyLayer = EnemyLayer::create();
this->addChild(enemyLayer);
//设置每帧时都调用gameUpdate函数
this->schedule(schedule_selector(GameLayer::gameUpdate));
//添加menu,并设置回调函数
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
auto closeItem = MenuItemImage::create("CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(GameLayer::menuCloseCallback, this));
closeItem->setPosition(
Point(
origin.x + visibleSize.width
- closeItem->getContentSize().width / 2,
origin.y + closeItem->getContentSize().height / 2));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
}
/**
 * menu的回调函数
 */
void GameLayer::menuCloseCallback(Ref* pSender) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
return;
#endif
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}


/**
 * 子弹和敌机碰撞检测函数
 */
bool GameLayer::bulletCollisionEnemy(Sprite* pBullet) {
//遍历场景中的所有敌机,看子弹是否和敌机的包装矩形有重叠
for (auto& eEnemy : enemyLayer->vecEnemy) {
EnemySprite* pEnemySprite = (EnemySprite*) eEnemy;
//判断矩形是否有重叠
if (pBullet->boundingBox().intersectsRect(
pEnemySprite->getBoundingBox())) {
if (1 == pEnemySprite->getLife()) {
pEnemySprite->loseLife();
enemyLayer->blowupEnemy(pEnemySprite);
} else {
pEnemySprite->loseLife();
}
//有重叠则移除子弹
bulletSprite->removeBullet(pBullet);
return true;
}
}
return false;
}


/**
 * 在每帧时都进行游戏逻辑检测,
 * 检测子弹和敌机是否有碰撞
 * 检测主角飞机和敌机是否有碰撞
 */
void GameLayer::gameUpdate(float dt) {
bool bMoveButt = false;
for (auto& eButtle : bulletSprite->vecBullet) {
Sprite* pBullet = (Sprite*) eButtle;
bMoveButt = bulletCollisionEnemy(pBullet);
if (bMoveButt) {
return;
}
}
enemyCollisionPlane();
}
/**
 * 敌机和主角飞机是否有碰撞
 * 遍历所有敌机进行检测
 */
bool GameLayer::enemyCollisionPlane() {
Sprite* pPlane = (Sprite*) planeLayer->getChildByTag(AIRPLANE);
for (auto& eEnemy : enemyLayer->vecEnemy) {
EnemySprite* pEnemySprite = (EnemySprite*) eEnemy;
if (pPlane->boundingBox().intersectsRect(pEnemySprite->getBoundingBox())
&& pEnemySprite->getLife() > 0) {
//TODO,DO WHAT YOU WANT
// this->unscheduleAllSelectors();
// this->bulletLayer->StopBulletShoot();
// this->planeLayer->blowUp();
return true;
}
}


return false;
}

```


在各个关键的地方都有详细注释,了解引擎的都应该可以看明白的,有具体问题的可以留言。

最后附上源码的下载链接,托管在github上,本人最烦的就是下载个东西还TM的需要积分,比如CSDN上的资源,你分享就分享吧,还得给你个积分来下载,要不你就别上传,既然开源,就不要想为自己谋多少利,可能又要被喷,但是我始终坚信开源才是王道,不喜务喷。

https://github.com/superman-t/PlaneGame/archive/master.zip,1

楼主源码是不是大了点呢

放百度云盘吧会快点

DAY DAY UP!:2::2:

下载下来没有东西

我错了。。是有的。。不过要自己Add一次

237mb下载中,很好奇资源占多大…

楼主,你的这个系列教程缺呀,只有一,五,六。中间的其他教程呢?写的挺好的,支持你。!!!!:14:

你好lz,我下载后直接解压文件然后编译,classes的文件全都加了。但是编译报错,请问一下要导入什么库吗?

我下linux环境下编译运行的,NDK版本4.8.1,Ant是官网上自己安装的,同时还有好多linux下用到的opengl库,这个我建议你新建立一个工程,把Classes和Resources文件夹拷贝到新建立的工程中,按你以往的方式来进行编译,环境是3.2的应该都行,我从网上下载的例子一般都是这样做的,由于环境的不同,可能编译有差别,我把我编译后的可执行文件打包上传上来,linux双击就能运行。

好的 :7:

Description Resource Path Location Type
make.exe: *** No rule to make target /home/tubuntu/game/android-ndk-r9d/sources/android/cpufeatures/cpu-features.c', needed by obj/local/armeabi/objs/cpufeatures/cpu-features.o’. Stop. Plane C/C++ Problem
Description Resource Path Location Type
make.exe: *** Waiting for unfinished jobs… Plane C/C++ Problem

Description Resource Path Location Type
make.exe: *** Error 1 PlanePro C/C++ Problem

这个错怎么解决?

可以运行,非常感谢

为啥我下载下来解压出错

支持楼主 谢谢这么详细 这么好的教程 还免积分开源 很好 跟楼主一样同感csdn恶心人

你可以编译成功了吗?
我这里还有问题呢

你有解决吗,我和你的情况一样

楼主,为什么我用3.0编译报了79个错误:6:

你用的什么版本可以运行呀