C++程序设计及互动多媒体开发 课件 罗立宏 第9章 Cocos2d-X开发基础;第10章 虚拟现实应用_第1页
C++程序设计及互动多媒体开发 课件 罗立宏 第9章 Cocos2d-X开发基础;第10章 虚拟现实应用_第2页
C++程序设计及互动多媒体开发 课件 罗立宏 第9章 Cocos2d-X开发基础;第10章 虚拟现实应用_第3页
C++程序设计及互动多媒体开发 课件 罗立宏 第9章 Cocos2d-X开发基础;第10章 虚拟现实应用_第4页
C++程序设计及互动多媒体开发 课件 罗立宏 第9章 Cocos2d-X开发基础;第10章 虚拟现实应用_第5页
已阅读5页,还剩144页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C++程序设计第9章Cocos2D-X开发基础第1节Cocos2d-X开发环境搭建第2节游戏案例——宇宙战记第3节安卓版发布第1节Cocos2d-X开发环境搭建Cocos2d-x简介Cocos2d-x开发环境搭建创建项目HelloCocosHelloCocos程序阅读1.1Cocos2d-x简介Cocos2D-X是全球知名的开源跨平台游戏引擎,易学易用,目前已经支持iOS、Android、Windows桌面、MacOSX、Linux、BlackBerry、WindowsPhone等平台。目前与Unity、虚幻4一起是使用最广泛的三大游戏引擎开发语言:C++,LUA典型游戏案例:捕鱼达人、我叫MT、大掌门……Cocos2d-x发展历程2008.02Ricardo在阿根廷LosCocos组建游戏开发团队并开始创建游戏开发引擎;2008.03在PyCon2008芝加哥宣布了alpha版本(v0.1),命名Loscocos,之后改名为Cocos2d;2011.07发布了使用Objective-C编写Cocos2d-iphonev1.0;随后尝试了各种平台和各种语言版本;2010.07王哲创建Cocos2d-x项目,使用C++;2011.07发布Cocos2d-xv2.0版本Cocos2d-xv3.0Cocos2d-xv4.0……1.2Cocos2d-x开发环境搭建讲解环境:Windows10,VS2022MacOS上的环境搭建,请参考《cocos2d-x4.0环境搭建Mac版》

(一)准备工作(1)安装Python安装Python配置这个库需要Python2,官方推荐的是Python2.7。注意:Python3是不行的!(要是安装过Python3以后的版本,也可以再装2.7,两个可以分开用。)设置Path环境变量

此电脑—属性—高级系统设置—环境变量—编辑“系统变量”中的Path,加入Python的安装目录—重启电脑检查Python版本在控制台中使用命令“python--version”查看(2)安装CMake安装CMake去官网下载或问指导老师获取,本教案安装CMake3.28安装过程中选择添加Path环境变量检查CMake版本在控制台中使用命令“cmake--version”查看(3)设置VisualStudio确认VisualStudio为2015或之后版本,如不是则安装本教案使用VS2022确认以下模块是否已安装,未安装则补装把VC编译环境路径加到Path环境变量中▶开始栏搜索x86NativeToolsCommandPromptforVS2022,运行▶输入“wherecl”查找出cl的路径▶把路径加入到Path环境变量中(二)安装配置Cocos2d-x下载或向指导老师获取cocos2d-x-4.0压缩包;解压。把解压目录放置在适当位置(这个位置就将是Cocos2d-x的安装位置)进入cocos2d-x-4.0文件夹,运行setup.py进行安装。安装过程中会若问NDK和AndroidSDK的路径,如果没有,先直接回车。安装程序运行完后,按提示重启计算机重启完成后,安装就完成了。验证一下版本信息cocos--version1.3例9-1创建项目HelloCocos在控制台中输入以下命令创建Cocos新项目

格式:cocosnew项目名称-l语言-d路径cocosnewHelloCocos-lcpp-dE:\MyProjects在资源管理器中可看到新建成的项目文件夹继续在控制台中使用CMake对项目进行编译

进入工程目录

创建一个名为“win32-build”的目录,进入该目录

使用Cmake编译:cmake..-G"VisualStudio172022"-Tv143-Awin32

注意VS版本号,2022是“VisualStudio172022”2019则为“VisualStudio162019”生成工具是v143,要对应“设置VisualStudio”页中的截图中红框cocos2dx只支持32位编译,要加-Awin32使用VS2022打开win32-build目录下的工程文件把工程设为启动项运行----OK!1.4HelloCocos程序阅读(1)程序入口main.cpp中intWINAPI_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);//没引用的这个参数不要给编译警告UNREFERENCED_PARAMETER(lpCmdLine);//createtheapplicationinstanceAppDelegateapp;returnApplication::getInstance()->run();//实际上的入口是\AppDelegate.cpp}实际的程序入口是applicationDidFinishLaunching()boolAppDelegate::applicationDidFinishLaunching(){//初始化导演autodirector=Director::getInstance();autoglview=director->getOpenGLView();if(!glview){#if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)||(CC_TARGET_PLATFORM==CC_PLATFORM_MAC)||(CC_TARGET_PLATFORM==CC_PLATFORM_LINUX)glview=GLViewImpl::createWithRect("HelloCocos",cocos2d::Rect(0,0,

mediumResolutionSize.width,

mediumResolutionSize.height));//改动这两参数使窗口变大#elseglview=GLViewImpl::create("HelloCocos");#endifdirector->setOpenGLView(glview);

}//显示帧率director->setDisplayStats(true);//设置帧率,如果不调用此句,默认帧率为1.0/60director->setAnimationInterval(1.0f/60);//设置designresolutionglview->setDesignResolutionSize(designResolutionSize.width,designResolutionSize.height,ResolutionPolicy::NO_BORDER);autoframeSize=glview->getFrameSize();//如果帧高度>中等尺寸if(frameSize.height>mediumResolutionSize.height){director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height,largeResolutionSize.width/designResolutionSize.width));}

//如果帧尺寸>小尺寸

elseif(frameSize.height>smallResolutionSize.height){director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height,mediumResolutionSize.width/designResolutionSize.width));}//如果帧高度<小尺寸else{director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height,smallResolutionSize.width/designResolutionSize.width));}register_all_packages();//创建场景。这个场景是自动释放的对象。autoscene=HelloWorld::createScene();//该函数中会调用init()//运行场景director->runWithScene(scene);returntrue;}(2)场景初始化init()boolHelloWorld::init(){////////1.先调用父类的init()if(!Scene::init()){returnfalse;}autovisibleSize=Director::getInstance()->getVisibleSize();Vec2origin=Director::getInstance()->getVisibleOrigin();////////2.增加一个menuitemimage,点击它可以退出程序autocloseItem=MenuItemImage::create(“CloseNormal.png”,//未点击时显示该图像“CloseSelected.png”,//点击时显示该图像CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));//设置点击回调函数if(closeItem==nullptr||closeItem->getContentSize().width<=0||closeItem->getContentSize().height<=0){problemLoading("'CloseNormal.png'and'CloseSelected.png'");}else{//创建成功则布置在右下角位置floatx=origin.x+visibleSize.width-closeItem->getContentSize().width/2;floaty=origin.y+closeItem->getContentSize().height/2;closeItem->setPosition(Vec2(x,y));}//创建menu控件。此为一个能自动释放的对象automenu=Menu::create(closeItem,NULL);menu->setPosition(Vec2::ZERO);this->addChild(menu,1);增加控件的流程:<1>实例化一个控件XXX::create(),里面设置好图片,有动作的设置好回调函数<2>计算显示的位置,设置位置setPosition()<3>添加到场景中this->addChild()////////3.addyourcodesbelow...////////4.增加一个label显示文字"HelloCocos2d-x"autolabel=Label::createWithTTF("HelloCocos2d-x","fonts/MarkerFelt.ttf",24);if(label==nullptr){problemLoading("'fonts/MarkerFelt.ttf'");}else{//把label放在屏幕中间label->setPosition(Vec2(origin.x+visibleSize.width/2,origin.y+visibleSize.height-label->getContentSize().height));//把label加入到图层this->addChild(label,1);}////////5.增加“HelloWorld.png”图片autosprite=Sprite::create("HelloWorld.png");if(sprite==nullptr){problemLoading("'HelloWorld.png'");}else{//把sprite放到窗口中间sprite->setPosition(Vec2(visibleSize.width/2+origin.x,visibleSize.height/2+origin.y));//把sprite加入到图层this->addChild(sprite,0);}returntrue;}各控件的更详细方法,请参考官方文档第2节游戏案例——宇宙战记创建新项目清除HelloWorld内容添加背景图添加主角战机添加敌机发射子弹碰撞检测敌机发射子弹主角战机中弹切换场景例9-2编写一个战机对战游戏,如图。2.1创建新项目按1.3节的方法创建新项目,新项目起名为SpaceWar完成后,使用VS2022打开win32-build目录下的工程文件SpaceWar.sln。不要忘记把工程SpaceWar设为启动项。修改applicationDidFinishLaunching()中的分辨率,使窗口变大。运行。可看到HelloWorld的界面。下面我们将基于这个程序框架进行修改。2.2清除HelloWorld内容HelloWorldScene.cpp里的init()函数,只留下以下代码,删除其他:boolHelloWorld::init(){//////1.superinitfirstif(!Scene::init()){returnfalse;}//////在此增加新代码returntrue;}2.3添加背景图准备一张背景图,放进Resource目录中修改init函数,增加以下代码:boolHelloWorld::init(){……//////在此增加新代码autowinSize=Director::getInstance()->getVisibleSize();autoorigin=Director::getInstance()->getVisibleOrigin();//增加背景图autospriteBackGround=Sprite::create("space.jpg");if(spriteBackGround==nullptr){problemLoading("'space.jpg'");}else{//把sprite放在窗口中间spriteBackGround->setPosition(Vec2(winSize.width/2+origin.x,winSize.height/2+origin.y));this->addChild(spriteBackGround,0);//增加sprite到图层}returntrue;}2.4添加主角战机准备一张主角战机的图片PlaneMe.png,放进Resource目录中在HelloWorldScene.h中添加以下代码:classHelloWorld:publiccocos2d::Scene{......private:cocos2d::Sprite*_player;};继续修改init()函数,在前述增加背景图代码的后面增加以下代码:boolHelloWorld::init(){......//增加主角战机_player=Sprite::create("planeme.png");_player->setPosition(Vec2(winSize.width*0.1,winSize.height*0.5));//加到靠左边中间this->addChild(_player);returntrue;}测试,运行继续2.5添加敌机准备一张敌机图片PlaneEnemy.png,放进Resource目录中

添加一个函数来做此事。在HelloWorldScene.h中添加函数声明:classHelloWorld:publiccocos2d::Scene{......CREATE_FUNC(HelloWorld);voidaddEnemy(floatdt);private:cocos2d::Sprite*_player;};注意图片文件名大小写要完全一致,否则后面发布成Android版本后会因为会大小写不同而找不到图片素材,从而导致程序运行出错。本程序中所有的素材文件都要注意此问题。在HelloWorldScene.cpp中添加函数定义:voidHelloWorld::addEnemy(floatdt){autoenemy=Sprite::create("PlaneEnemy.png");//增加敌机

autoenemyContentSize=enemy->getContentSize();autoselfContentSize=this->getContentSize();intminY=enemyContentSize.height/2;//最低位置比窗口底部高半个战机intmaxY=selfContentSize.height-minY;//最高位置比窗口顶部低半个战机intrangeY=maxY-minY;//高度位置取值范围intrandomY=(rand()%rangeY)+minY;//在取值范围内随机取值enemy->setPosition(Vec2(selfContentSize.width+enemyContentSize.width/2,randomY));this->addChild(enemy);//让敌机动起来intminDuration=2.0;//计划从出现处(最右)移到目标点(最左)花费的最少时间intmaxDuration=4.0;//计划从出现处(最右)移到目标点(最左)花费的最多时间intrangeDuration=maxDuration-minDuration;;//计划时间的取值范围intrandomDuration=(rand()%rangeDuration)+minDuration;//在取值范围内随机取值

//定义移动的object//在randomDuration这个时间内(2-4秒内),让敌机从屏幕右边移动到左边(有快有慢)autoactionMove=MoveTo::create(randomDuration,Vec2(-enemyContentSize.width/2,randomY));//定义消除的Object。敌机移出屏幕后被消除,释放资源。

autoactionRemove=RemoveSelf::create();enemy->runAction(Sequence::create(actionMove,actionRemove,nullptr));}两个移动类:MoveTo:是在多长时间内,移动到指定的点。MoveBy:是在当前位置移动多少步。移除类:RemoveSelf执行动作runAction。通过Sequence来组织,以nullptr结束

在init()前述中添加主角战机的代码后面继续添加以下代码:boolHelloWorld::init(){……//设置随机种子。因为addEnemy()中用了rand()。如果不执行这一步,每次运行程序都会//产生一样的随机数。

srand((unsignedint)time(nullptr));//每隔1.5秒生成一个怪物。schedule提供一个连续动作的功能

this->schedule(CC_SCHEDULE_SELECTOR(HelloWorld::addEnemy),1.5);returntrue;}编译运行。可看到不断有新产生

敌机并冲过来。2.6发射子弹准备一张子弹图片BulletMe.png,放进Resource目录中在init()中添加敌机的代码后面增加代码,注册事件和绑定响应函数:boolHelloWorld::init(){……//为发射子弹注册事件和绑定处理函数

//定义触摸事件的监听器

autoeventListener=EventListenerTouchOneByOne::create();//定义回调函数onTouchBegan():手指一碰到屏幕时就被调用。

eventListener->onTouchBegan=CC_CALLBACK_2(HelloWorld::onTouchBegan,this);//使用EventDispatcher来处理各种各样的事件,如触摸和其他键盘事件。

this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(eventListener,_player);returntrue;}触摸事件监听器和回调函数两种触摸(点击)事件的监听器:▶EventListenerTouchOneByOne:对每个触摸事件调用一次回调方法。▶EventListenerTouchAllAtOnce:对所有的触摸事件调用一次回调方法。每个触摸事件监听器支持4个回调,只需要对关心的事件绑定▶onTouchBegan:手指刚碰到屏幕时被调用。如果使用EventListenerTouchOneByOne,必须返回true才能获取另外3个触摸事件。▶onTouchMoved:手指接触屏幕并移动(保持接触)时被调用。▶onTouchEnded:手指离开屏幕时被调用。▶onTouchCancelled:在特定的结束事件处理的环境中被调用,比如触摸时被电话打断开在HelloWorldScene.h中添加事件处理函数的声明:classHelloWorld:publiccocos2d::Scene{......CREATE_FUNC(HelloWorld);voidaddEnemy(floatdt);boolonTouchBegan(cocos2d::Touch*touch,cocos2d::Event*unused_event);private:cocos2d::Sprite*_player;};在HelloWorldScene.cpp中添加函数定义:boolHelloWorld::onTouchBegan(Touch*touch,Event*unused_event){

Vec2touchLocation=touch->getLocation();//获取触摸点的坐标Vec2offset=touchLocation-_player->getPosition();//计算触摸点相对于_player的偏移量。

//不允许向后射击。

if(offset.x<0){returntrue;}

//在玩家当前位置创建一个子弹,将其添加到场景中。

autoprojectile=Sprite::create("BulletMe.png");projectile->setPosition(_player->getPosition());this->addChild(projectile);

//将偏移量转化为单位向量,即长度为1的向量。

offset.normalize();

//将其乘以1500,获得了一个指向用户触摸点方向并保证超出屏幕的向量。

autoshootAmount=offset*1500;

//将此向量叠加到子弹位置上,这样就有了一个目标位置。

autorealDest=shootAmount+projectile->getPosition();

//创建一个动作,将飞镖在3秒内移动到目标位置,然后将它从场景中移除。

autoactionMove=MoveTo::create(3.0f,realDest);autoactionRemove=RemoveSelf::create();projectile->runAction(Sequence::create(actionMove,actionRemove,nullptr));returntrue;}编译,运行。此时主角战机已能发射子弹。2.7碰撞检测初始化Physics类。要用物理碰撞,需要在init()中加载它boolHelloWorld::init(){//////1.superinitfirstif(!Scene::init()){returnfalse;}//////在此增加新代码

//初始化Physicsif(!Scene::initWithPhysics()){returnfalse;}autowinSize=Director::getInstance()->getVisibleSize();……}给敌机加上physicsBody。这样敌机精灵对象就承载了物理属性。在addEnemy()中添加代码,加载addChild前面:voidHelloWorld::addEnemy(floatdt){......enemy->setPosition(Vec2(selfContentSize.width+enemyContentSize.width/2,randomY));//为敌机增加physicsBodyautophysicsBody=PhysicsBody::createBox(enemy->getContentSize(),PhysicsMaterial(0.0f,0.0f,0.0f));physicsBody->setDynamic(false);//设为不受重力影响physicsBody->setContactTestBitmask(0xFFFFFFFF);//设为能跟所有物体碰撞enemy->setPhysicsBody(physicsBody);this->addChild(enemy);......}同理,给子弹加上physicsBody。在onTouchBegan()中添加代码,加载addChild前面:boolHelloWorld::onTouchBegan(Touch*touch,Event*unused_event){......projectile->setPosition(_player->getPosition());//为子弹添加physicsBodyautophysicsBody=PhysicsBody::createBox(projectile->getContentSize(),PhysicsMaterial(0.0f,0.0f,0.0f));physicsBody->setDynamic(false);//设为不受重力影响physicsBody->setContactTestBitmask(0xFFFFFFFF);//设为能跟所有物体碰撞projectile->setPhysicsBody(physicsBody);projectile->setTag(100);//做一个标记,等会方便识别this->addChild(projectile);......}碰撞事件监听器和回调函数碰撞(接触)事件的监听器:▶EventListenerPhysicsContact碰撞事件监听器支持4个回调,只需要对关心的事件绑定▶onContactBegin:两物体刚接触时被调用一次。▶onContactPreSolve:两物体接触时持续被调用。▶onContactPostSolve:碰撞处理完成后被调用,此时两物体还接触。▶onContactSeparate:两物体分开时被调用一次。在init()中注册发射子弹事件后面增加代码,注册碰撞事件和绑定响应函数:boolHelloWorld::init(){……this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(eventListener,_player);//为子弹碰撞注册事件和绑定处理函数

autocontactListener=EventListenerPhysicsContact::create();contactListener->onContactBegin=CC_CALLBACK_1(HelloWorld::onContactBegin,this);_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,this);returntrue;}在HelloWorldScene.h中添加碰撞事件处理函数的声明:classHelloWorld:publiccocos2d::Scene{......CREATE_FUNC(HelloWorld);voidaddEnemy(floatdt);

boolonTouchBegan(cocos2d::Touch*touch,cocos2d::Event*unused_event);boolonContactBegin(cocos2d::PhysicsContact&contact);private:cocos2d::Sprite*_player;};在HelloWorldScene.cpp中添加函数定义:boolHelloWorld::onContactBegin(cocos2d::PhysicsContact&contact){autonodeA=contact.getShapeA()->getBody()->getNode();autonodeB=contact.getShapeB()->getBody()->getNode();

//如果其中一个物体为子弹,删除另一个if(nodeA&&nodeB){if(nodeA->getTag()==100){//前面对子弹做了个100标记,这里靠该标记来识别nodeB->removeFromParentAndCleanup(true);}elseif(nodeB->getTag()==100){nodeA->removeFromParentAndCleanup(true);}}returntrue;}编译,运行。此时子弹已能消灭敌机。2.8敌机发射子弹设计目标敌人在移动的过程中,随机位置发射一枚子弹思路在原来的代码中,敌机只有一个MoveTo的Action,我们把它改成MoveTo->shootStar->MoveTo这样的动作序列。前半段MoveTo的距离随机产生。素材准备一张子弹图片BulletEnemy.png,放进Resource目录中在HelloWorldScene.cpp中修改addEnemy():voidHelloWorld::addEnemy(floatdt){......this->addChild(enemy);//注释掉下面两段//删除//让敌机动起来

//删除intminDuration=2.0;

//删除intmaxDuration=4.0;

//删除intrangeDuration=maxDuration-minDuration;

//intrandomDuration=(rand()%rangeDuration)+minDuration;

//

//删除//定义移动的object

//删除//在randomDuration这个时间内(2-4秒内),让怪物从屏幕右边移动到左边。

//删除autoactionMove=MoveTo::create(…参数长,略…);

//删除//定义消除的Object。怪物移出屏幕后被消除,释放资源。

//删除autoactionRemove=RemoveSelf::create();

//删除enemy->runAction(Sequence::create(actionMove,actionRemove,nullptr));

//增加以下代码:

//让敌机动起来

intmaxX=selfContentSize.width;intrandomX=maxX-(rand()%(int)(maxX/2));//计算敌机发射子弹袋随机位置floatenemySpeed=150;floatrandomDuration2=(float)randomX/enemySpeed;//敌机运动第一段的时间floatrandomDuration1=(float)(maxX-randomX)/enemySpeed;//敌机运动第二段的时间automove1=MoveTo::create(randomDuration1,Vec2(randomX,randomY));//第一段移动automove2=MoveTo::create(randomDuration2,Vec2(-enemyContentSize.width/2,randomY));//第二段移动

//定义消除的Object。怪物移出屏幕后被消除,释放资源。

autoactionRemove=RemoveSelf::create();

//敌机发射子弹autoshootStar=CallFunc::create([=](){//自定义动作

//创建敌人子弹

Sprite*eProjectile=Sprite::create("BulletEnemy.png");eProjectile->setPosition(enemy->getPosition());

//添加敌机子弹袋physicsBodyautophysicsBody=PhysicsBody::createBox(eProjectile->getContentSize(),PhysicsMaterial(0.0f,0.0f,0.0f));physicsBody->setDynamic(false);//设置成不受重力影响physicsBody->setCategoryBitmask(3);//设置自己的碰撞掩码为0011physicsBody->setContactTestBitmask(4);//设置用掩码0100去碰别人。4能跟F碰,不跟3碰eProjectile->setPhysicsBody(physicsBody);eProjectile->setTag(101);//做个标记101this->addChild(eProjectile);

//敌机发射子弹

floatstarSpeed=130;//敌机子弹速度floatstarDuration=(float)randomX/starSpeed;//敌机子弹移动时间autoprojectileMove=MoveTo::create(starDuration,_player->getPosition());//移动动作autoprojectileRemove=RemoveSelf::create();eProjectile->runAction(Sequence::create(projectileMove,projectileRemove,nullptr));});

//敌人发射子弹时,停顿一下

DelayTime*delay=cocos2d::DelayTime::create(0.05);enemy->runAction(Sequence::create(move1,delay,shootStar,move2,actionRemove,nullptr));}编译,运行。此时敌机已能发射子弹。2.9主角战机中弹碰撞检测再分析。有以下三种情况(1)敌机的子弹或者敌人碰到主角战机,游戏结束。(2)主角战机的子弹碰到敌机或者敌机的子弹,会将它们都消灭。(3)主角战机的子弹对自己是没影响,敌机的子弹对自己也没影响。为实现以上碰撞功能,掩码设计如下:角色掩码设计二进制值主角战机setCategoryBitmask(5)0101setContactTestBitmask(1)0001主角战机子弹setCategoryBitmask(5)0101setContactTestBitmask(2)0010敌机setCategoryBitmask(3)0011setContactTestBitmask(1)0001敌机子弹setCategoryBitmask(3)0011setContactTestBitmask(4)0100根据上表,在init()中增加主角战机的碰撞属性:boolHelloWorld::init(){......//增加主角战机

_player=Sprite::create("planeme.png");_player->setPosition(Vec2(winSize.width*0.1,winSize.height*0.5));//为主角战机添加碰撞属性

autophysicsBody=PhysicsBody::createBox(_player->getContentSize(),PhysicsMaterial(0.0f,0.0f,0.0f));physicsBody->setDynamic(false);physicsBody->setCategoryBitmask(5);physicsBody->setContactTestBitmask(1);_player->setPhysicsBody(physicsBody);_player->setTag(TAG_MY_PLANE);//#defineTAG_MY_PLANE102this->addChild(_player);

......}原来设置标记直接写整数,改为用宏定义,提高程序可读性#defineTAG_MY_PROJECTILE100//主角战机子弹#defineTAG_ENEMY_PROJECTILE101//敌机子弹#defineTAG_MY_PLANE102//主角战机#defineTAG_ENEMY_PLANE103//敌机搜索setTag,把所有语句的参数改为相应宏定义修改onContactBegin()中添加主角战机被碰的代码:boolHelloWorld::onContactBegin(cocos2d::PhysicsContact&contact){autonodeA=contact.getShapeA()->getBody()->getNode();autonodeB=contact.getShapeB()->getBody()->getNode();if(nodeA&&nodeB){intnTagA=nodeA->getTag();intnTagB=nodeB->getTag();if(nTagA==TAG_MY_PROJECTILE){nodeB->removeFromParentAndCleanup(true);}elseif(nTagB==TAG_MY_PROJECTILE){nodeA->removeFromParentAndCleanup(true);}

//当player碰到碰到敌人或者敌机的子弹,就该GameOver了

if(nTagA==TAG_MY_PLANE||nTagB==TAG_MY_PLANE){log("Gameover");}}returntrue;}编译,运行。此时主角战机被碰撞到时VS输出窗口会产生GameOver提示。2.10切换场景在输出窗口提示GameOver是不合适的。应该在界面上显示GameOver画面,并让游戏停止。专门设计一个GameOver场景,游戏应该结束时,就切换到该场景。在Classes文件夹中,新建一个cpp文件,取名为GameOverScene.cpp同理,在Classes文件夹中,新建一个头文件,取名为GameOverScene.h把例8-1HelloCocos中的HelloWorldScene.h中的代码全部拷贝到GameOverScene.h中。把HelloCocos中的HelloWorldScene.cpp中的代码全部拷贝到GameOverScene.cpp中。把两个文件中所有“HELLOWORLD”和“HelloWorld”字样替换成“GAMEOVER”和“GameOver”修改GameOver::init(),修改文字字体和内容,删除HelloWorld图像:boolGameOver::init(){......//3.addyourcodesbelow...//addalabelshows“GameOver"//createandinitializealabelautolabel=Label::createWithTTF("GameOver!","fonts/MarkerFelt.ttf",48);

label->setTextColor(Color4B(249,194,111,255));if(label==nullptr){problemLoading("'fonts/MarkerFelt.ttf'");}else{//positionthelabelonthecenterofthescreenlabel->setPosition(Vec2(origin.x+visibleSize.width/2,origin.y+visibleSize.height/2));//addthelabelasachildtothislayerthis->addChild(label,1);}

//删除//add"GameOver"splashscreen"

//删除autosprite=Sprite::create("GameOver.png");

//删除if(sprite==nullptr)

//删除{

//删除problemLoading("'GameOver.png'");

//删除}

//删除else

//删除{

//删除//positionthespriteonthecenterofthescreen

//删除sprite->setPosition(Vec2(visibleSize.width/2+origin.x,visibleSize.height/2+origin.y));

//删除//addthespriteasachildtothislayer

//删除this->addChild(sprite,0);

//删除}returntrue;}修改HelloWorld::onContactBegin(),切换GameOver场景:boolHelloWorld::onContactBegin(cocos2d::PhysicsContact&contact){......//当player碰到碰到敌机或者敌机的子弹,切换GameOver场景

if(nTagA==TAG_MY_PLANE||nTagB==TAG_MY_PLANE){log("Gameover");Director::getInstance()->replaceScene(GameOver::createScene());}}returntrue;}编译,运行。至此主角战机被碰撞到时会弹出GameOver场景。----OK!第3节安卓版发布发布准备导入cocos的测试工程导入SpaceWar工程常见错误及解决办法3.1发布准备安装AndroidStudio以及AndroidSDK下载或向指导老师取得AndroidStudio,安装。AndroidSDK会一并装上。新定义一个系统变量ANDROID_SDK_ROOT,写上AndroidSDK的路径

下载或向指导老师取得AndroidNDK压缩文件,不需安装,解压,直接拷贝至某个目录下。在AndroidStudio中填入NDK目录(在ProjectStructure按钮--SDKLocation--AndroidNDKlocation)新定义一个系统变量NDK_ROOT,写上NDK的路径在path系统变量中加上下面这4个路径-%ANDROID_SDK_ROOT%\platforms-%ANDROID_SDK_ROOT%\platforms-tools-%ANDROID_SDK_ROOT%\tools-%NDK_ROOT%安装NDK验证安装在cmd中输入android,出现下面的提示说明安装成功。3.2导入cocos的测试工程在AndroidStudio中导入HelloCocos工程(例8-1)以作测试。导入时候不要着急操作什么,因为IDE还要安装编译Gradle等一些工作等下面的状态条显示已经稳定了之后,点击Build->RebuildProject。编译会持续几分钟至十几分钟的时间,直到提示编译成功。运行测试工程将安卓手机连接到电脑,手机上如果有提示,一定要选“传输文件”,并且将开发者模式打开(各个手机情况不一样,请自己查找)。在Device栏会看到你手机的信息。然后点击右边的绿色三角箭头3.3导入SpaceWar工程总体步骤同3.2节但由于SpaceWar工程多创建了一个GameOver场景。因此要在CMakeLists.txt中加入新增场景文件:在工程根目录底下有一个CMakeLists.txt。打开,在下面位置加上GameOver场景的.cpp和.h……#addcross-platformssourcefilesandheaderfileslist(APPENDGAME_SOURCEClasses/AppDelegate.cppClasses/HelloWorldScene.cpp

Classes/GameOverScene.cpp)list(APPENDGAME_HEADERClasses/AppDelegate.hClasses/HelloWorldScene.h

Classes/GameOverScene.h)……编译,运行3.4常见错误及解决办法RebuildProject没反应--需要重新同步,点工具栏中的SyncProjectwithGradleFiles按钮。打开工程后在Download/distributions/gradle-5.1.1-all.zip长时间不动。--把以上地址输入浏览器,手动下载。找到gradle的目录,一般在C:\Users\<当前用户名>\.gradle\wrapper\dists\下面。找到对应的gradle版本目录,进去,看到有一个名字有二十多个字母数字的目录,再进去,把下载好的gradle-x.x.x-all.zip放进去。例如我的目录是:C:\Users\llh\.gradle\wrapper\dists\gradle-5.4.1-all\95oh3es52vukhe1f02mlm4ly1重新同步(SyncProjectwithGradleFiles按钮)

参考:/badaoli

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论