cocos2d-x的HelloWorld很简单一行标题、一个图片、一个按钮、一花一世界(⊙_⊙)。

也许有人会说了,左下角还有几行数据呢。额,那个不是HelloWorld本身的部分,只是一些统计数据。

在分析代码前,阅读以下两篇博文,会对理解代码有所帮助:

【玩转cocos2d-x之二】游戏和引擎构成

http://www.jb51.cc/article/p-wtgzxjqe-ep.html

【玩转cocos2d-x之十】cocos2d-x坐标系

http://www.jb51.cc/article/p-wwzvwhfo-ep.html

【玩转cocos2d-x】系列我也只是看了其中几篇,有时间要系统的研究一下。

那么接下来,我将尝试逐层的分析HelloWorld源码。初学cocos2d-x,难免有理解不准确的地方,望理解与指正。

首先,一切从main()开始。main.cpp中12~13行,告诉编译器hPrevInstance和lpCmdLine这两个变量我不用,就不要再向我报警告了。不过说句题外话,HelloWorld在编译过程中警告真不少,而且第一次编译下来这个速度啊……

16行,定义一个AppDelegate类的实例。17行,稀里糊涂的就run起来了。我第一次看到这里的时候感觉有些奇怪,定义的app看起来没有使用啊。同时,类的成员函数怎么用类名就直接调用起来了,难道不用通过类的实例调用?后来经过一番查阅资料,得知这里使用的是C++单例类的设计思想。通俗的讲就是保证单例类只有一个实例,无论从程序的什么地方获取该类的实例都是那一个。具体的东西请各位网上查阅资料,这里就不再赘述了。

17行虽然稀里糊涂的就让整个程序跑起来了,可分析代码可不能稀里糊涂,还是先从定义实例开始看吧。定义一个类的实例会调用一系列类的构造函数,看看这些构造函数中都做了写什么。AppDelegate类的相关继承关系如下:

ApplicationProtocol 无Construct

Application Application()

AppDelegate AppDelegate()中无内容

可以看到,定义实例app后,只有Application的构造函数做了实际的工作。CCApplication-win32.cpp中49行,Application::_instance获得了当前程序的句柄,这个和windows启动一个程序有关,具体没有研究过。51行,是一个cocos2d-x封装后的断言。如果Application::sm_pSharedApplication非空,即已经被初始化过,则要报错,中止程序。因为接下来马上就要初始化Application::sm_pSharedApplication了,如果之前初始化过,那是在哪儿初始化的★_★?!52行,由于AppDelegate是Application的子类,所以这一this实际上是指向AppDelegate的实例的。(⊙_⊙)终于知道main()中定义的那个app实例是做什么用的了,那么52行这里,Application::_sm_pSharedApplication实际得到的是app的地址。至此,Application的构造函数结束。main.cpp中16行这么一行代码实际上也就做了以上这些事情,总结一下就是对Application::_instance和Application::_sm_pSharedApplication赋值。

接下来回到main()中,该深入了解一下程序是怎么稀里糊涂的跑起来的了。main.cpp,17行,首先是Application::getInstance()。CCApplication-win32.cpp中126行,首先还是个断言,Application::_sm_pSharedApplication必须已被初始化过。这回很踏实,上面已经看到它是怎么被初始化的了。之后127行返回Application::_sm_pSharedApplication,通过上面的分析实际上返回的是app的地址。此时回到main()中继续往后看,->run(),这里又明了了,类的成员函数实际上还是通过类的实例调用起来的,只不过这里隐藏起来的而已,这是单例类的特点。

进入run(),CCApplication-win32.cpp中63行,这个没有仔细研究,往里看看好像是在往注册表里写什么东西,同时在网上查到这么一段资料:

A: 谁知道PVRFrame是什么东西?

B: PVR是ios里面用的opengles硬件加速芯片的厂商名字,PowerVR。在cocos2d-iphone里支持,在cocos2d-x里为了跨平台不支持。

反正设置成false了,那就是不起作用,先不管它了。

66~68行,这3个变量用于存储windows平台内部高精度计数器的值,通过这3个变量监测时间的流逝,从而决定何时应该渲染下一帧。

70行,获取cpu的时钟频率。71行,获取cpu至此时已运行了多长时间。都是windows平台内部高精度计数器的相关操作。

73行,初始化OpenGL的上下文,HelloWorld程序中没有实际内容。不过我现在还不太明白初始化的这个上下文是怎么个意思,看来需要学习OpenGL的相关知识。

76行,这个函数比较重要,HelloWorld中有什么元素,摆放的位置等等都在其中进行了设置。我们暂且先不继续看run(),先从这个函数深入进去,看看HelloWorld中的文字、图片、按钮都是怎么出来的。

AppDelegate.cpp中27行,这里碰到了cocos2d-x的核心类之一,Director。还记得分析代码前熟悉的“【玩转cocos2d-x之二】游戏和引擎构成”这篇博文中的内容吗,这个就是最顶层的那个Director。Director也是个单例类,这里不深入分析,只知道director获得了Director类的实例就可以了。28~32行,glview尝试通过director获得OpenGL的操控权。接下来个人理解是如果系统不支持OpenGL,则使用cocos2d-x自己实现的OpenGL,并将该OpenGL的操控权给glview。这里也暂不深入,因为需要了解更多的OpenGL知识。

35行,开启FPS状态显示。这里与程序运行起来后显示的一块东西关联起来了,就是左下角的那几行数据。这里也暂不深入,涉及到cocos2d-x核心类的相关操作都暂且跳过哈。

38行,设置FPS,每秒60帧。

41行,scene通过HelloWorld类创建一个屏幕。可以想象,HelloWorld类中定义好了屏幕中要显示的元素以及元素的相关属性,通过createScene()成员函数创建好一个可供显示的屏幕,然后将其交给scene。

44行,拿着这个scene给director,说我就要显示这个屏幕了。

AppDelegate::applicationDidFinishLaunching()中将所有准备工作都做好了,一会儿出去就等着让OpenGL一帧一帧的绘制了。在这里我们先不出去,从41行继续深入一下,看看HelloWorld::createScene()是如何将要显示的元素以及其相关属性设置好的。

HelloWorldScene.cpp中9行,调用cocos2d-x核心类Scene创建一个屏幕。12行,又是HelloWorld的create,看来实际创建的源码藏的挺深。15行,拿着创建好的一套元素大类将其加入scene中。18行,返回这个屏幕。返回的这个屏幕就是函数外面要显示的屏幕。至此,还是没有看到HelloWorld设置元素实际的源码,因此从12行继续深入。

HelloWorldScene.h中19行,看到这里会发现HelloWorld::create()实际上是通过CREATE_FUNC这个宏定义实现的,宏CREATE_FUNC定义在CCPlatformMacros.h中39行。我们结合给宏定义传递的参数,将宏定义展开,得到HelloWorld::create()的实现源码:

可以看到,创建了一个HelloWorld类的实例,成功后调用其init()进行初始化。init()也成功之后,调用autorelease()让实例在适当的时候自动释放,这个具体的机制没有研究,暂不深入。HelloWorld类的相关继承关系如下:

Ref

Node

Layer

HelloWorld

HelloWorld类本身没有构造函数,由于其父类是cocos2d-x的核心类之一,所以HelloWorld类的父类们的构造函数就先暂不分析了,只要知道cocos2d-x为我们做好了充分的准备工作就可以了,╰( ̄▽ ̄)╮。

接下来深入HelloWorld::init(),HelloWorldScene.cpp中22行,粗略的看了看函数的实现,发现我们终于看到了真相,一堆create(),setPosition()什么的,一看就知道是在设置要显示的元素极其相关属性。27行,先让它的父类Layer进行初始化,准备工作做充分<( ̄︶ ̄)>。32行,visibleSize获得屏幕可见区域的宽和高。33行,origin获得OpenGL坐标系原点,在屏幕的左下角,这里可以阅读文章开始给出的“【玩转cocos2d-x之十】cocos2d-x坐标系”博文了解相关概念。

40行,closeItem通过MenuItemImage创建一个按钮,正常情况下的图片是“Closenormal.png”,被点击情况下的图片是“CloseSelected.png”。对了,HelloWorld程序所用到的素材都在Resources/下,程序运行起来后也是从这个目录下寻找素材的。最后,当按钮被点击后调用HelloWorld::menuCloseCallback回调函数,CC_CALLBACK_1就是注册这个回调函数的过程。这里可以去看一眼这个回调函数,里面很简单,只有一句话起作用,436行,让Director说“咔”,然后程序就结束了。

接下来继续,45行,设置这个关闭按钮的位置。origin.x是x轴0点,也就是屏幕最左边;visibleSize.width是屏幕的宽度;closeItem->getContentSize().width是按钮的宽度。由于关闭按钮这个元素的锚点在图片的中心,所以需要减去图片宽度的一半,才能让图片正好贴着屏幕右边沿显示。y轴坐标的设置同理,最终将图片放置在屏幕的右下角。这里设置的实际上是相对坐标,一会儿要将closeItem放在Menu中,还要根据Menu的坐标最终确定这个关闭按钮的绝对坐标。

关于锚点的描述,建议参考cocos2d-x英文官网上的编程手册Chapter 2中的介绍:http://www.cocos2d-x.org/programmersguide/2/

49行,menu获得通过closeItem创建的Menu。50行,设置Menu的坐标为(0,0),和上面联系起来,关闭按钮的绝对坐标就是屏幕的右下角。51行,将按钮添加进屏幕中(实际上是添加进了Layer中,在函数外面HelloWorldScene.cpp的15行,再将Layer添加进Scene中)。

至此,一个关闭按钮的相关属性设置就完成了。总结一下,其实有3大步,create()、setPosition()、addChild()。接着往下看,你会发现屏幕中其他元素的设置也是这3大步这么个流程。

59行,ttf是一种字体文件格式,这里就是用Marker Felt字体写了一个“Hello World”放在一个标签中给label。62行,设置label的坐标。66行,将label添加进屏幕。看看,是不是还是这3大步的节奏。

下面69~75行同样,是创建图片的过程。

至此,HelloWorld::init()函数结束,屏幕上要显示的东西都准备好了,就差去渲染它们了,让我们一直往前退吧。往前退会发现一只能退到CCApplication-win32.cpp中的76行,还记得之前说过的吗,当时Application::run()就是分析到这里然后深入进去了,现在分析完了,我们继续在run()中往下走。

81行,director获得Director类的实例。82行,glview获得OpenGL的控制权。这段好像在哪儿看到过,没错,就是在AppDelegate::applicationDidFinishLaunching()中看到过。单例类,操控的都是同一个实例。

85行,看注释是说防止glview在主循环中被释放,具体没有研究。主循环的渲染都没有结束,OpenGL的控制权当然不能释放了,不过为什么有可能会被释放呢?

87行这个while,如果程序窗口没有被关闭,则通过windows内部高精度计数器计算时间的流逝,以决定是否要渲染下一帧。如果需要则调用director->mainLoop(),这里就不深入了,深入进去的事儿可大了,⊙﹏⊙。同时95行,还在监听着游戏摇杆时间,不过在这个版本中没有实现。另外,如果不需要渲染下一帧,则等待1s。这里不很理解,FPS是60,等待1s难道要错过60帧的内容?

104行,如果程序窗口被关闭了,也就跳出了上面的while(),那么之后就是要做一些清理工作了。104~110行,导演说:“收工了,大家都回家吃饭了,glview别忘了把OpenGL控制权还给人家!”

好了,至此run()分析完,main()中的代码也就都执行完毕了。额,饿了,回家吃饭了,<( ̄︶ ̄)>。

cocos2d-x v3.3之HelloWorld浅析windows的更多相关文章

  1. three.js模拟实现太阳系行星体系功能

    这篇文章主要介绍了three.js模拟实现太阳系行星体系功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. HTML5页面无缝闪开的问题及解决方案

    这篇文章主要介绍了HTML5页面无缝闪开方案,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. ios – 痛苦地减慢软件向量,特别是CoreGraphics与OpenGL

    )在这个实验之后,我切换到了OpenGL和MonkVG库,我感到非常高兴.我现在可以在没有任何帧速率下降的情况下同时渲染HUNDREDS曲线,对保真度的影响很小.>我是否有可能以某种方式滥用CoreGraphics,或者性能真的那么糟糕?我的预感是问题在于CoreGraphics,基于StackOverflow/论坛问题的数量以及有关CG性能的答案.从技术上讲,为什么会这样呢?>如果CoreGraphics真的那么慢,Safari究竟如何顺利地工作?OpenGL在早餐时吃这个测试.矢量绘图怎么可能如此慢得

  4. ios – 为什么,将nil作为参数从Objc C发送到swift类初始化器,用新对象替换nil参数

    除非属性本身被声明为nonnull:

  5. 为什么这个OpenGL ES 2.0着色器不能在iOS上使用我的VBO?

    如果有人能够了解这里出了什么问题,也许是对gl命令或其他一些不兼容的命令序列的错误排序,我将非常感谢你的帮助.尽管谷歌在“OpenGLES2.0编程指南”中进行了大量研究和研究,但我一直试图让这段代码整天都没有成功.我正在尝试在iPhone上的OpenGLES2.0中使用顶点缓冲区对象和自定义着色器.我试图交错来自以下类型的一系列自定义结构的顶点数据:位置,半径和颜色字节分别考虑顶点位置,点大小和

  6. ios – 为什么Apple建议在串行后台队列中调度OpenGL命令,这不可避免地会导致崩溃?

    他们suggest:WhenusingGCD,useadedicatedserialqueuetodispatchcommandstoOpenGLES;thiscanbeusedtoreplacetheconventionalmutexpattern.我不明白这个建议.我无法解决这种冲突:当应用程序的app委托收到-applicationWillResignActive调用时,它必须立即停止调用任

  7. ios – 在Swift中对MKCircle进行子类化

    我想通过添加另一个String属性来继承MKCircle,我们称之为“代码”.这个属性不是可选的和常量的,所以我必须从初始化器设置它,对吧?有没有办法定义一个单一的便利初始化器,在这种情况下需要3个参数?本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  8. ios – AVAudioPlayer不再使用Swift 2.0/Xcode 7 beta

    对于我的iPhone应用程序中的vartestAudio声明,我在这里收到错误“调用可以抛出,但错误不能从属性初始化程序中抛出”当我转到Xcode7测试版时,就发生了这种情况.如何在Swift2.0中使用此音频剪辑?

  9. ios – 斯威夫特.在初始化所有存储的属性之前在方法调用中使用’self’

    解决方法在初始化所有非可选实例变量之前,您无法在self上调用方法.有几种方法可以解决这个问题.>将属性更改为选项或隐式解包选项(不建议)>使buildCircle()方法静态或只是一个在文件中运行并为所有圆圈调用addSubview()在所有属性初始化并且您调用之后super.init()等等.你必须避免在自己之前打电话给自己class已初始化.

  10. ios – Objective-C警告未找到超类“-init”的指定的初始化程序的方法覆盖

    我在一个应用程序中清理警告,我收到了两次这个警告对于这行代码和这一行我相当新的Objective-C和谷歌这个警告,只是不明白的解决方案我的问题是如何摆脱这些警告?

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部