cocos2d-x 3.2 |飞机大战:碰撞与分数
来源:互联网 发布:windows系统常用命令 编辑:程序博客网 时间:2024/05/22 11:30
cocos2d-x 3.2 |碰撞与分数
前情提要:飞机大战第五篇 实现碰撞与分数
思路:游戏里物体与物体的碰撞每帧都会检测 这里我们利用前面讲过的贪吃蛇移动原理 利用update方法来实时检测
如下:新建类----->Game
第一步:Game类(实现主要的游戏逻辑模块)
Game.h
//引入需要用到的类
#include <stdio.h>#include "cocos2d.h"#include "cocos-ext.h"#include "cocosGUI.h"#include "Bullet.h"#include "Enemy.h"#include "Boom.h"#include "Tool.h"USING_NS_CC;using namespace cocos2d;class Game:Layer{public: Vector<Bullet *> allBullet;//集合:子弹 float startX,startY; CREATE_FUNC(Game); static Scene * CreateScene(); bool init(); virtual bool onTouchBegan(Touch *touch, Event *unused_event);//触摸检测 按下 virtual void onTouchMoved(Touch *touch, Event *unused_event);<span style="font-family: Arial, Helvetica, sans-serif;">//触摸检测 移动</span> void newBullet(float t);//产生子弹 void moveBullet(float t);//移动子弹 Vector<Enemy *> allEnemy;//<span style="font-family: Arial, Helvetica, sans-serif;">集合:</span><span style="font-family: Arial, Helvetica, sans-serif;">敌机</span> void newEnemy(float t);//产生敌机 void moveEnemy(float t);//移动敌机 void update(float t);//游戏逻辑 碰撞检测 int m_score; void reCallBack(Ref * obj); Vector<Tool *> allTool;//集合:道具};Game.cpp
#include "Game.h"#include "BackGround.h"#include "Plane.h"#include "MainMenu.h"#include "SimpleAudioEngine.h"#include "cocosGUI.h"#include "GameOver.h"#include "Tool.h"#include "Enemy.h"using namespace ui;using namespace CocosDenshion;USING_NS_CC;Scene * Game::CreateScene(){ auto scene=Scene::create(); auto layer=Game::create(); scene->addChild(layer); return scene;}bool Game::init(){ if (!Layer::init()) { return false; } //创建 返回 按钮 auto menurt=MenuItemLabel::create(Label::createWithSystemFont("返回", "", 32),CC_CALLBACK_1(Game::reCallBack, this)); menurt->setAnchorPoint(Vec2::ZERO); menurt->setPosition(600-30,Director::getInstance()->getWinSize().height-36); menurt->setColor(Color3B::GREEN); //创建菜单 auto menu=Menu::create(menurt,nullptr); menu->setPosition(Vec2::ZERO); this->addChild(menu,2); //添加背景 auto bk=BackGround::create(); this->addChild(bk); //添加飞机 auto fly1=Plane::create(); this->addChild(fly1,1); fly1->moveTo(100,100); fly1->setTag(10); //处理飞机的HP for (int i=0; i<fly1->hp; i++) { auto sphp=Sprite::create("hp_1.png"); sphp->setTag(1000+i); this->addChild(sphp); sphp->setAnchorPoint(Vec2(0,1)); sphp->setPosition(Vec2(i*sphp->getContentSize().width+3*i,Director::getInstance()->getWinSize().height)); } //控制飞机飞行 auto listener=EventListenerTouchOneByOne::create();//创建侦听 listener->onTouchBegan=CC_CALLBACK_2(Game::onTouchBegan, this);//定义侦听的回调 listener->onTouchMoved=CC_CALLBACK_2(Game::onTouchMoved, this); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);//将侦听添加到事件分发器中 //产生子弹 计划任务 this->schedule(schedule_selector(Game::newBullet),0.2);//每隔200毫秒产生一次子弹 this->schedule(schedule_selector(Game::moveBullet),0.01); //产生敌机 this->schedule(schedule_selector(Game::newEnemy),1); this->schedule(schedule_selector(Game::moveEnemy),0.01); //实现游戏逻辑 this->scheduleUpdate(); //分数显示器1 this->m_score=0; auto tscore=TextAtlas::create("0000", "img_num_dis.png",17 , 22, "0"); this->addChild(tscore,12); tscore->setTag(210); tscore->setPosition(Vec2(Director::getInstance()->getWinSize().width/2, Director::getInstance()->getWinSize().height-64)); //分数显示2// auto scoreLb = Label::createWithSystemFont(StringUtils::format("分数:%d",score), "", 32);// scoreLb->setAnchorPoint(Vec2::ZERO);// scoreLb->setColor(Color3B::GREEN);// scoreLb->setPosition(0,Director::getInstance()->getWinSize().height-36);// scoreLb->setTag(123);// this->addChild(scoreLb,2); return true;}//返回主菜单void Game::reCallBack(Ref * obj){ auto scene=MainMenu::CreateScene(); Director::getInstance()->replaceScene(scene);}//按下bool Game::onTouchBegan(Touch *touch, Event *unused_event){ this->startX=touch->getLocation().x; this->startY=touch->getLocation().y; return true;}//移动void Game::onTouchMoved(Touch *touch, Event *unused_event){ float mx=touch->getLocation().x-startX; float my=touch->getLocation().y-startY; auto fly1=(Plane *)this->getChildByTag(10); fly1->moveTo(fly1->px+mx, fly1->py+my); this->startX=touch->getLocation().x; this->startY=touch->getLocation().y;}void Game::newBullet(float t)//产生子弹{ auto fly1=(Plane *)this->getChildByTag(10); Bullet * bt=Bullet::newBullet(1, 0,fly1->px,fly1->py); allBullet.pushBack(bt); this->addChild(bt); //子弹音效 SimpleAudioEngine::getInstance()->playEffect("launch_1.wav");}void Game::moveBullet(float t)//移动子弹{ for (int i=0;i<allBullet.size();i++) { Bullet * nowB=allBullet.at(i); nowB->moveTo(nowB->px, nowB->py+15); if (nowB->py>Director::getInstance()->getWinSize().height) { allBullet.erase(i); this->removeChild(nowB); i--; } } }void Game::newEnemy(float t){ int type=random()%10; if (type < 3) { type = 1; } else if (type > 8) { type = 2; }else { type = 1; } int ex=random()%(int)Director::getInstance()->getWinSize().width; Enemy * news=Enemy::createEnemy(type, ex, Director::getInstance()->getWinSize().height+200); allEnemy.pushBack(news);//将新产生的敌机添加到集合 this->addChild(news); //在当前GAME图层添加敌机层}void Game::moveEnemy(float t){ for (int i=0; i<allEnemy.size(); i++) { //获取第i架敌机 Enemy * nowE=allEnemy.at(i); nowE->moveTo(nowE->ex, nowE->ey-5); if (nowE->ey<-nowE->eSprite->getContentSize().height) { allEnemy.erase(i); this->removeChild(nowE); i--; } }}void Game::update(float t){ //创建一个Label层 获取计数器标签 //auto scoreLb = (Label *)this->getChildByTag(123); //碰撞检测 if (allEnemy.size()==0 || allBullet.size()==0) { return; } auto fly1=(Plane *)this->getChildByTag(10); //判断飞机和道具 for (int j = 0; j<allTool.size(); j++) { //得到第j架敌机 Tool * nowTool=allTool.at(j); Rect br(fly1->px, fly1->py, fly1->getChildByTag(10)->getContentSize().width, fly1->getChildByTag(10)->getContentSize().height); //敌机的矩形大小 Rect er(nowTool->tx, nowTool->ty, nowTool->sp->getContentSize().width, nowTool->sp->getContentSize().height); if (br.intersectsRect(er)) {//碰撞检测到两个矩形相交 //判断吃到哪种道具 switch (nowTool->type) { case 1://hp { fly1->hp++; int i=fly1->hp-1; auto sphp=Sprite::create("hp_1.png"); sphp->setTag(1000+i); this->addChild(sphp); sphp->setAnchorPoint(Vec2(0,1)); sphp->setPosition(Vec2(i*sphp->getContentSize().width+3*i,Director::getInstance()->getWinSize().height)); } break; case 2://炸雷 { //所有敌机都销毁 while (allEnemy.size()>0) { Enemy * nowEnemy=allEnemy.at(0); Boom * boom=Boom::createBoom(2, nowEnemy->ex, nowEnemy->ey); this->addChild(boom,10); //爆炸一次 总增加分数 this->m_score+=300; allEnemy.eraseObject(nowEnemy); nowEnemy->removeFromParentAndCleanup(true); } //播放音效 SimpleAudioEngine::getInstance()->playEffect("launch_1.wav"); //播放爆炸粒子 Boom * boom=Boom::createBoom(2, Director::getInstance()->getWinSize().width/2, Director::getInstance()->getWinSize().height/2); this->addChild(boom,15); } break; case 3://激光 break; case 4://散弹 break; } //敌机消失 nowTool->unscheduleAllSelectors(); nowTool->removeFromParentAndCleanup(true); allTool.eraseObject(nowTool); j--; } } for (int j = 0; j<allEnemy.size(); j++) { //得到第j架敌机 Enemy * nowEnemy=allEnemy.at(j); //子弹的矩形大小 Rect br(fly1->px, fly1->py, fly1->getChildByTag(10)->getContentSize().width, fly1->getChildByTag(10)->getContentSize().height); //敌机的矩形大小 Rect er(nowEnemy->ex, nowEnemy->ey, nowEnemy->eSprite->getContentSize().width, nowEnemy->eSprite->getContentSize().height); if (br.intersectsRect(er)) {//碰撞检测到两个矩形相交 //敌机消失 allEnemy.eraseObject(nowEnemy); nowEnemy->removeFromParentAndCleanup(true); j--; //掉血音效 SimpleAudioEngine::getInstance()->playEffect("skill_1.wav"); //我方Hp-- if (fly1->hp>0) { this->removeChildByTag(1000+fly1->hp-1); fly1->hp=fly1->hp-1; } if(fly1->hp<=0) {//Game Over //创建一个场景 auto scene=GameOver::createScene(); //将场景覆盖到Game Over 并释放之前场景 Director::getInstance()->replaceScene(scene); } } } //判断子弹 是否碰到敌机 for (int i=0; i<allBullet.size(); i++) { //得到第i颗子弹 Bullet * nowBullet=allBullet.at(i); for (int j = 0; j<allEnemy.size(); j++) { //得到第j架敌机 Enemy * nowEnemy=allEnemy.at(j); //子弹的矩形大小 Rect br(nowBullet->px, nowBullet->py, nowBullet->bt->getContentSize().width, nowBullet->bt->getContentSize().height); //敌机的矩形大小 Rect er(nowEnemy->ex, nowEnemy->ey, nowEnemy->eSprite->getContentSize().width, nowEnemy->eSprite->getContentSize().height); if (br.intersectsRect(er)) { //检测到两个矩形相交 子弹消失 allBullet.eraseObject(nowBullet); nowBullet->removeFromParentAndCleanup(true); i--; nowEnemy->hp=nowEnemy->hp-1; if(nowEnemy->hp<=0) { //爆炸 if(nowEnemy->type==1) { Boom * boom=Boom::createBoom(1, nowEnemy->ex, nowEnemy->ey); this->addChild(boom); //scoreLb->setString(StringUtils::format("分数:%d",score+=40)); //增加分数 this->m_score+=40; } else { Boom * boom=Boom::createBoom(2, nowEnemy->ex, nowEnemy->ey); this->addChild(boom); //scoreLb->setString(StringUtils::format("分数:%d",score+=60)); this->m_score+=60; } //分数增加器 auto score1=(TextAtlas *)this->getChildByTag(210); score1->setString(StringUtils::format("%d",m_score)); //爆炸音效 SimpleAudioEngine::getInstance()->playEffect("launch_2.wav"); //道具处理 if (nowEnemy->toolID>0) { //掉落道具 auto tool=Tool::newTool(nowEnemy->toolID,nowEnemy->ex,nowEnemy->ey); this->addChild(tool); allTool.pushBack(tool); } allEnemy.eraseObject(nowEnemy); nowEnemy->removeFromParentAndCleanup(true); j--; } break;//退出这次循环 } } }}
总结:至此利用5个篇章简单实现了一下飞机大战的主要核心内容,希望对读者有帮
后期还有两个番外篇:游戏分数保存+安卓导出调试(因为安卓实在是让人蛋疼)
ps:游戏中用到的素材与音效请自行替换。
0 0
- cocos2d-x 3.2 |飞机大战:碰撞与分数
- cocos2d-x 3.2 |飞机大战:飞机与子弹
- Cocos2d-x 3.2 lua飞机大战开发实例(三)道具的掉落,碰撞检测,声音,分数,爆炸效果,完善游戏的功能细节
- cocos2d-x 3.2 |飞机大战:背景与滚动
- cocos2d-x 3.2 |飞机大战:敌机与爆炸
- cocos2d-x 3.2 |飞机大战:技能
- quick-cocos2d-x 飞机大战(打飞机)小demo教程------碰撞检测以及胜负
- Cocos2d-x 3.2 lua飞机大战开发实例(二)敌机类的封装,以及碰撞检测的实现
- cocos2dx飞机大战Cocos2d-x飞机实现
- 【cocos2d-x入门实战】微信飞机大战之九:碰撞检测
- 【cocos2d-x入门实战】微信飞机大战之九:碰撞检测
- 【cocos2d-x入门实战】微信飞机大战之十二:分数的本地存储
- 【cocos2d-x 3.7 飞机大战】 决战南海I (十三) 分数场景
- cocos2dx飞机大战教程Cocos2d-x飞机大战运行效果
- [cocos2d-x][游戏开发]通过cocos2d-x实现简易飞机大战 08.游戏界面 碰撞检测
- Cocos2d-x 3.2 简易飞机大战教程系列 【一】
- Cocos2d-x飞机大战教程笔记
- cocos2d-x小游戏——飞机大战
- 开源夏令营(6)
- RocketMQ原理解析-producer 4.发送分布式事物消息
- gitbub-android-async-http框架使用
- [cocos2d-x][游戏开发]通过cocos2d-x实现简易飞机大战 05.游戏界面 主角飞机的移动
- 开源夏令营(7)
- cocos2d-x 3.2 |飞机大战:碰撞与分数
- 针对main函数的运行时stack的分析
- xp system权限提升
- RocketMQ原理解析-producer 5.消息在broker落地之普通消息
- Android高版本打开网络设置界面
- RGB888和565相互转换
- 黑马程序员_iso入门基础学习_C语言day5
- hdu 1022 Train Problem I
- 开源夏令营(8)