疯狂ios讲义之创建cocos2d项目(3)

article/2025/9/18 8:49:18

13.3.3 cocos2d项目结构和代码分析

这一节将向游戏开发者介绍HelloWorld项目的目录结构,以及各个部分是如何协同工作的。通过本节的学习,你会对各个部分之间的联系有个大致的了解。

13.22显示了HelloWorld项目的项目导航面板。

164919_6G44_262659.jpg

164945_DMil_262659.jpg

164955_P8CU_262659.jpg

13.22


cocos2d项目引用两类不同的文件:源码文件和资源文件(包括图像文件、声音文件和属性文件等)。Default.png文件是在iOS加载应用程序时显示的图像,Icon.png是应用程序部署在设备上的图标。不同设备上可能使用这些文件类型的不同版本。例如,Retina 设备上会加载带有@2x后缀的图像文件。关于应用程序图标、启动图像等图像尺寸和格式的完整列表,可以参考苹果公司的开发者文档中的Custom Icon and Image Creation Guidelines,具体网址是:http://developer.apple.com/library/ios/ documentation/userexperience/conceptual/ mobilehig/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1

fps_images.png文件用于显示帧率,是不允许删除或修改的。

Info.plist文件包含了一些与项目相关的配置信息,同时也可以在这个文件中修改一些重要的设置,如项目图标、支持设备的方向等。

1. 主程序入口main.m

任何一个使用Xcode开发的应用程序或游戏都是从main.m开始的。在导航区域的“Supporting Files”组下面可以找到main.m文件。main.m的代码如下。

程序清单:codes/13/13.3/HelloWorld/HelloWorld/main.m

#import <UIKit/UIKit.h>

int mainint argcchar *argv[] {

@autoreleasepool {

int retVal = UIApplicationMain(argc,argv,nil,@"AppController");

return retVal;

}

}

简单来说,main函数创建了@autoreleasepool(自动释放池),然后调用UIApplicationMain来启动程序。其中,AppController是实现UIApplicationDelegate协议的类,AppController类的实现包含在AppDelegate文件中。在启用了ARCcocos2d应用程序中,Autorelease Pool(自动释放池)可以确保内存的对象最终被释放。

2. 预编译头文件Prefix.pch

该组中的另一个文件Prefix.pch是预编译头文件,用于加快编译速度。pch表示Pre-Compiled Header,游戏开发者应该把不常变化的框架(Frameworks)头文件添加到该文件中。这样做可以使框架的代码提前被编译,并对所有类可见。

不过,这样做要注意一个问题:如果pch前缀头文件中的一个头文件发生了变化,项目中的所有代码都将会重新编译。所以,pch前缀头文件中只应该添加那些极少或者从来都不发生变化的头文件。

游戏开发者可以将cocos2d.h头文件添加到pch前缀头文件中,因为它几乎不会改变。而且,一开始就将cocos2d.h添加到预编译头文件中是一个非常好的习惯,这样在其他源文件中就不必再写“#import "cocos2d.h"”了。在预编译头文件中加入cocos2d.h,代码如下。

程序清单:codes/13/13.3/HelloWorld/HelloWorld/Prefix.pch

#import <Availability.h>

#ifndef __IPHONE_3_0

#warning "This project uses features only available in iPhone SDK 3.0 and later."

#endif

#ifdef __OBJC__

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#import "cocos2d.h"

#endif

3. AppDelegate

每个iOS程序都有一个AppDelegate类,用于实现UIApplicationDelegate协议。AppDelegate实现的方法用于处理iOS应用程序的状态改变。例如,可以通过它来处理用户来电或者系统内存不足时程序需要采取的措施。在查看AppDelegate方法的具体实现代码前,先要了解AppDelegate.h中的类定义。在AppDelegate.h中定义了AppController这个类,它直接继承自NSObject类,并且遵循UIApplicationDelegateCCDirectorDelegate两个协议。

程序加载完成后,立即执行的方法就是applicationDidFinishLaunchingWithOptions:,在该方法中,通常都是应用启动后需要执行的初始化代码。

Xcode中打开AppDelegate.m文件,找到applicationDidFinishLaunchingWithOptions方法,代码如下。

程序清单:codes/13/13.3/HelloWorld/HelloWorld/AppDelegate.m

-(BOOL)application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

// 创建程序主窗口

window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

// 创建CCGLView对象,用于游戏中的渲染

// cocos2d v2.0之后,CCGLView替代了之前的EAGLView

// 使用CCGLViewOpenGL ES命令发送给OpenGL ES驱动

CCGLView *glView =[CCGLView viewWithFrame:[window_ bounds]

pixelFormat:kEAGLColorFormatRGB565depthFormat:0

preserveBackbuffer:NOsharegroup:nilmultiSampling:NO

numberOfSamples:0];

// ①创建导演对象

director_ =(CCDirectorIOS*) [CCDirector sharedDirector];

director_.wantsFullScreenLayout = YES;

// FPSFrames Per Second)和SPFSecond Per Frame)显示设置为开

// cocos2d会自动计算游戏的当前帧数,并显示在屏幕的左下角

// 在调试过程中FPS显示对我们调试会非常有用

// 在游戏正式上传到设备时可以将其设置为NO,则FPSSPF不会再显示在设备中

[director_ setDisplayStats:YES];

// 将动画间距设置为每秒60次,这也是cocos2d中的默认设置

// 在正常情况下,cocos2d每秒最高会刷新屏幕中的显示60

[director_ setAnimationInterval:1.0/60];

// openglView绑定到director_导演对象上

[director_ setView:glView];

// director_的代理对象设置为self(自身),用于获取屏幕信息

[director_ setDelegate:self];

// 设置2D3D投射

[director_ setProjection:kCCDirectorProjection2D];

// [director setProjection:kCCDirectorProjection3D];

// 启用Retina高清显示模式

if(! [director_ enableRetinaDisplay:YES] )

CCLOG(@"Retina Display Not supported");

// 设置cocos2d的纹理格式

[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];

// iPadRetina高清显示模式下,使用CCFileUtils自动添加图片的后缀

CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];

[sharedFileUtils setEnableFallbackSuffixes:NO];

[sharedFileUtils setiPhoneRetinaDisplaySuffix:@"-hd"];

[sharedFileUtils setiPadSuffix:@"-ipad"];

[sharedFileUtils setiPadRetinaDisplaySuffix:@"-ipadhd"];

// 设置PVR图像具备多重透明度

[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];

// ②初始化IntroLayer场景,并使用pushScene方法切换到该场景

[director_ pushScene: [IntroLayer scene]];

// 使用director_创建NavigationController导航控制器

navController_ = [[UINavigationController alloc] initWithRootViewController:director_];

// 设置navigationBarHiddenYES

navController_.navigationBarHidden = YES;

// NavigationController导航控制器设置为根视图控制器

[window_ setRootViewController:navController_];

// 设置主窗口可见

[window_ makeKeyAndVisible];

return YES;

}

applicationDidFinishLaunchingWithOptions方法中,①号代码创建了一个CCDirector导演对象,在cocos2d中,CCDirector导演对象负责游戏的循环运行,并且在游戏中渲染所有的图像,它会掌控游戏的运行、暂停或停止。AppController中包括了CCDirector响应iOS操作系统在内的暂停或继续等各个事件。代码如下。

程序清单:codes/13.3/HelloWorld/HelloWorld/AppDelegate.m

// 当操作系统暂停应用时执行,调用此方法来暂停游戏和所有的计时器

// 当玩家在玩游戏的过程中锁定了iPadiPhone,或者有电话打进来

// 或者其他类似事件发生需要强迫游戏进入后台时,会调用此方法

-(void)applicationWillResignActive:(UIApplication *)application

{

if([navController_ visibleViewController] == director_ )

[director_ pause];

}

// 当玩家解锁iPadiPhone,或电话已接听完毕时,会调用此方法来继续游戏和所有的计时器

-(void)applicationDidBecomeActive: (UIApplication *application

{

if( [navController_ visibleViewController] == director_ )

[director_ resume];

}

// iOS 4.0及以后的版本中,开始支持应用在后台运行,此时会停止运行屏幕中的动画

-(void)applicationDidEnterBackground: (UIApplication*)application

{

if( [navController_ visibleViewController] == director_ )

[director_ stopAnimation];

}

// 当应用重新回到前台来运行时,重新启动屏幕中的动画

-(void)applicationWillEnterForeground: (UIApplication*)application

{

if( [navController_ visibleViewController] == director_ )

[director_ startAnimation];

}

// 应用程序即将中止时调用此方法

// 该方法会终止CCDirector的控制,并从应用程序的UIWindow中解除对CCGLView的绑定

// 同时还将结束游戏循环,从内存中清除所有的纹理和计时器

-(void)applicationWillTerminate: (UIApplication *)application

{

CC_DIRECTOR_END();

}

// 当系统收到内存不足的警告时,会调用此方法从内存中清除未在屏幕中显示的纹理图。

-(void)applicationDidReceiveMemoryWarning: (UIApplication *)application

{

[[CCDirector sharedDirector] purgeCachedData];

}

// 将上一次时间调用和当前事件调用间的增量时间设置为0

// 该方法的调用场景是:两次调用之间已经过了太长的时间。

// 这通常是由于iPhone重新调整了系统时间而导致。

-(void)applicationSignificantTimeChange: (UIApplication *)application

{

[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];

}

applicationDidFinishLaunchingWithOptions方法中,编号②代码初始化IntroLayer场景,并使用pushScene方法切换到该场景。下面我们来看看IntroLayer类的实现。

4. IntroLayer

IntroLayer类继承自CCLayer,因为CCDirector只能运行CCScene对象,所以需要实现IntroLayerscene方法,它会把IntroLayer当作唯一的子节点添加进去,并返回一个CCScene。打开IntroLayer.m文件,找到scene方法,代码如下。

程序清单:codes/13/13.3/HelloWorld/HelloWorld/IntroLayer.m

+(CCScene *)scene

{

// 创建CCScene场景对象

CCScene *scene = [CCScene node];

// 创建IntroLayer层对象

IntroLayer *layer = [IntroLayer node];

// layer添加为scene的子节点

[scene addChild: layer];

// 返回scene对象

return scene;

}

以前的cocos2d版本中是不存在IntroLayer类的,这是cocos2d 2.0新加的类,它的主要目的就是在进入游戏之前,可以显示游戏制作公司的Logo等信息。显示Logo的实现代码在onEnter方法当中,代码如下(程序清单同上)。

-(void)onEnter

{

[super onEnter];

// 获得设备支持的窗口大小

CGSize size = [[CCDirector sharedDirector] winSize];

CCSprite *background;

// 判断设备是iPhone还是iPad,并据此来加载不同的背景资源图片

if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone ){

background = [CCSprite spriteWithFile:@"Default.png"];

background.rotation = 90;

} else {

background = [CCSprite spriteWithFile:@"Default-Landscape~ipad.png"];

}

// 设置背景图片的位置居中

background.position = ccp(size.width/2,size.height/2);

// 把背景图片添加到IntroLayer

[self addChild: background];

// 触发一个定时器方法调用,在1秒后会调用makeTransition函数

[self scheduleOnce:@selector(makeTransition:)delay:1];

}

接下来看看makeTransition方法的实现,代码如下(程序清单同上)。

-(void)makeTransition: (ccTime)delta

{

[[CCDirector sharedDirector] replaceScene:

[CCTransitionFade transitionWithDuration:1.0

scene:[HelloWorldLayer scene] withColor:ccWHITE]];

}

该方法只有一句代码调用,就是使用CCDirector配合CCTransitionFade场景切换特效类,把HelloWorldLayer类在1秒屏幕变白后展示出来。最后来看看HelloWordLayer类的实现。

5. HelloWorldLayer.m

HelloWorldLayer类继承自CCLayer。因为CCScene只是一个抽象的接口,而默认设置场景的方法通常是在类里使用一个静态初始化方法+(id)scene。此方法会创建一个CCScene对象,并且将HelloWorldLayer的对象添加为场景的子节点。代码如下。

程序清单:codes/13/13.3/HelloWorld/HelloWorld/HelloWorldLayer.m

+(CCScene *)scene

{

// 创建CCScene场景对象

CCScene *scene = [CCScene node];

// 创建HelloWorldLayer层对象

HelloWorldLayer *layer = [HelloWorldLayer node];

// layer添加为scene的子节点

[scene addChild: layer];

// 返回scene对象

return scene;

}

接下来再看看-(id)init初始化方法的实现,代码如下(程序清单同上)。

-(id) init

{

if((self=[super init])) {

// 创建和初始化一个标签对象

CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World"

fontName:@"Marker Felt" fontSize:64];

// 实例化得到一个CCDirector的单例,并获得窗口的尺寸

CGSize size = [[CCDirector sharedDirector] winSize];

// 将标签位置设置在屏幕中央,ccpcocos2d对于CGPointMake的宏定义

label.position = ccp(size.width /2,size.height/2);

// label添加为scene的子节点

[self addChild: label];

// 下面是初始化游戏中心的成就榜和高分榜的代码,此处先略去暂时不讨论

}

return self;

}

以上就是HelloWorld项目的详细实现过程。读者之前已经学习过iOS基础知识,所以这里并没有对所有类的所有实现代码进行逐行解释和分析。但通过以上详细代码分析,我们初步了解了一个cocos2d应用的启动和运行过程,这将为以后开发更复杂的游戏或应用程序打下扎实的基础。

HelloWorld项目中,使用了场景(CCScene)、层(CCLayer)、导演(CCDirector)等核心类,在cocos2d的开发中,几乎任何一款cocos2d游戏中都会用到这些类,所以了解它们的作用、属性和方法,以及如何将这些类组织在一起,是我们学习cocos2d游戏开发的必修课。掌握了这些基本知识之后,大家就会发现使用cocos2d开发游戏其实很简单。接下来重点介绍cocos2d中的核心类。


 

本文转自 fkJava李刚 51CTO博客,原文链接:http://blog.51cto.com/javaligang/1394268 ,如需转载请自行联系原作者


http://chatgpt.dhexx.cn/article/ZeyEFEIR.shtml

相关文章

2016如何突破自我,这么疯狂的事谁敢做

2016一定要做一件令自己疯狂的事&#xff0c;想想自己20多年过去了&#xff0c;却发现没有什么可以回忆的事情是多么的悲催…… 再不疯狂我们就老了…… 2016趁自己还年轻&#xff0c;还有激情&#xff0c;还有动力&#xff0c;放肆的去疯狂…… 一定要疯狂的去玩&#xff0c;…

前有视觉中国后有来电,知识产权勒索为何屡禁不止?

不久前&#xff0c;一张黑洞照片在全网引发了轩然大波&#xff0c;因知识产权被外界熟知的公司“视觉中国”在诸多蓝V的狂轰滥炸下狼狈收场。起因就在于&#xff0c;视觉中国高举知识产权大旗却对外行使近乎于“敲诈勒索”之事。“黑洞事件”后&#xff0c;就在公众以为知产行业…

2016如何突破自我,必做十件疯狂的事

2016一定要做一件令自己疯狂的事&#xff0c;想想自己20多年过去了&#xff0c;却发现没有什么可以回忆的事情是多么的悲催…… 再不疯狂我们就老了…… 2016趁自己还年轻&#xff0c;还有激情&#xff0c;还有动力&#xff0c;放肆的去疯狂…… 一定要疯狂的去玩&#xff0…

[android基础]《疯狂android讲义》重点整理(2)

十、Service与BroadcastReceiver&#xff1a; 1.Service与Activity还有一点相似之处&#xff0c;它们都是从Context派生出来的&#xff0c;因此它们都可调用Context里定义的如getResources()、getContentResolver()等方法。 2.与配置Activity相似的是&#xff0c;配置Service时…

大厂地震,疯狂裁员大换血,面试冲击大厂Android移动开发工程师就在此时

前段时间在准备面试跳槽Android高级工程师时&#xff0c;发现各个大厂都在疯狂裁员&#xff0c;对于处于大厂之中的程序员来说&#xff0c;无疑是一场大地震&#xff01;但对于新想要冲击大厂的朋友们来说也是一场非常大的机遇&#xff01; 不过在积极备战大厂时&#xff0c;发…

男子刷机多次拒绝来电 维修师傅的做法被网友怒赞

昨日&#xff0c;一段男子到维修店刷机的视频在抖音上火了&#xff0c;目前已经有18万人点赞。 视频画面中&#xff0c;一男子前往手机维修店&#xff0c;表示忘记密码要刷机。 师傅查看时手机突然来了个电话&#xff0c;维修师问男子要不要接一下电话&#xff0c;男子说“不接…

街电、来电、小电、怪兽们熬出了头?

配图来自Canva可画 近期&#xff0c;共享充电宝涨价的消息甚嚣尘上&#xff0c;一众涨价哀怨声中还夹杂着几条共享充电宝安全隐患的吐槽声。 2015年&#xff0c;共享经济崛起&#xff0c;万物共享的概念深入人心。彼时共享经济正火热&#xff0c;单车、充电宝、雨伞、鲜花等物…

安卓来电归属地_唯一数码带你看WWDC | 数码怪圈,安卓、IOS、WP居然互相抄袭

IOS一直是手机领域的系统高端产品&#xff0c;也一直是其他手机争相模仿的对象&#xff0c;不过这些年来&#xff0c;苹果是否有点“黔驴技穷”&#xff1f;比如这次WWDC2020开完后&#xff0c;网上一度的风评是&#xff1a;“苹果终于实装了这些安卓/WP上的功能。” 其实&…

安卓手机来电防火墙_手机号变“广告号”?来电显示暗藏黑色利益链!你可能也被卷入其中...

微调查&#xff1a;手机号变“广告号”&#xff1f;想取消&#xff0c;先交钱。来电显示暗藏黑色利益链&#xff01;道钉说说你现在还接谁的电话&#xff0c;你的内心独白是什么&#xff1f; 当下&#xff0c;几乎人人手机上都会有“来电显示”。智能手机还会显示特殊的“标注”…

Linux系统安装Nodejs详细教程

前言 第一次在Linux系统上安装Nodejs&#xff0c;我的服务器系统是CentOS 7&#xff0c;找了很多教程&#xff0c;都不是很详细完善&#xff0c;特此记录一下本人详细的安装过程。下面我们就开始吧&#xff01; 下载Node.js 方法一&#xff1a;下载到本地后上传到服务器 下…

Node.js 安装教程(Windows)

什么是Node.js&#xff1f; 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff1b; Node.js使用一个事件驱动、非阻塞式 I/O 的模型&#xff0c;使其轻量且高效&#xff1b; Node.js的软件包生态系统npm是全…

windows安装npm教程(nodejs)

1、在使用之前&#xff0c;先类掌握3个东西&#xff0c;明白它们是用来干什么的&#xff1a; npm: nodejs 下的包管理器。 webpack: 它主要用途是通过CommonJS 的语法把所有浏览器端需要发布的静态资源作相应的准备&#xff0c;比如资源的合并和打包。 vue-cli: 用户生成Vu…

Node.js下载及安装步骤

一、安装环境 1、本机系统&#xff1a;Windows 11&#xff08;64位&#xff09; 2、Node.js&#xff1a;v16.14.2LTS&#xff08;64位&#xff09; 二、安装Node.js步骤 1、下载对应系统的Node.js版本:Download | Node.js 2、选安装目录进行安装 3、环境配置 4、测试 三、前…

nodejs安装及环境配置详细教程

nodejs安装及环境配置一、nodejs安装环境 本机系统:Windows 10 Pro(64位) Node.js : 14.17.5(64位) nodejs安装及环境配置二、安装Node.js步骤 《1》下载对应你系统的Node.js版本: https://nodejs.org/en/download/ 《2》选安装目录进行安装 《3》环境配置 《4》测试 …

NodeJS、NPM安装配置步骤(windows版本)

原文章&#xff1a;NodeJS、NPM安装配置步骤(windows版本) 参考菜鸟教程学习nodeJS&#xff0c;碰到npm安装express&#xff0c;一直提示缺少xx文件之类的&#xff0c;终于找到解决方案了&#xff0c;原来要提前配置好环境变量的。 原文章棒棒哒&#xff0c;下面粘贴一下&…

2023年node.js最新版(18.15.0)详细安装教程(保姆级)

本文章作者本人卸载之后重新安装的完整详细教程, 包含了环境变量的详细配置,以及常见的错误解决方法 一. node.js安装与环境变量配置 1 .node.js下载(包含国内和国外下载地址) 1.国外的官网地址: Node.js (nodejs.org) 下载慢,下面提供国内地址. 可以看到当前的版本 LTS是大多用…

nodejs安装及环境配置

安装环境 本机系统&#xff1a;Windows 10 Pro&#xff08;64位&#xff09; Node.js : 14.17.5&#xff08;64位&#xff09; 安装Node.js步骤 《1》下载对应你系统的Node.js版本: https://nodejs.org/en/download/ 《2》选安装目录进行安装 《3》环境配置 《4》测试 前期准备…

ubuntu安装nodejs

推荐使用方法1进行安装 方法1&#xff1a; curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs如果安装nodejs 9.x版本 curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash - sudo apt-get install -y nodejs方法…

node.js 安装,详细步骤教程

本机环境&#xff1a;Windows 10 专业版 x64 1、下载安装包 Node.js 官方网站下载&#xff1a;https://nodejs.org/en/ 选择操作系统对应的包&#xff1a; 下载完成&#xff0c;安装包如下&#xff1a; 2、安装 打开安装&#xff0c;傻瓜式下一步即可&#xff1a; 选择安装位置…

Centos安装Nodejs简单方式

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。本文主要讲的是如何在Linux即Centos上安装Nodejs的简单方式&#xff0c;有比设置环境变量更加简单的方式&#xff0c;那就是设置软链接&#xff0c;软连接到已经设置环境变量的路径即可&#xff0c;如/usr/bin 1.官网 …