大家好,又见面了,我是全栈君。
最后一篇讲一下游戏中的主要逻辑推断,在上面的工作都做充分准备后,游戏主要逻辑将变得特别清晰,接下来你会看到全部的逻辑都是那么的清晰自然,由于前面已经做好了充分的准备工作,这里仅仅是整合了前面的工作,略微增加了一些游戏推断元素。
同一时候源代码会在文章最后给出链接地址,源代码托管在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[15]; 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上的资源,你分享就分享吧,还得给你个积分来下载,要不你就别上传,既然开源,就不要想为自己谋多少利,可能又要被喷,可是我始终坚信开源才是王道,不喜务喷。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/116500.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...