初学cocos2dx的时候都躲不过这个所谓的HelloworldScene,那么我这里就浅谈一下这个cpp文件中到底做了什么。
先看头文件(注释解释得很清楚了)
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
//注意HelloWorld公有继承自Layer,是个布景层,千万别理所当然地以为是场景
class HelloWorld : public cocos2d::Layer
{
//c++没有id类型,返回一个场景对象,这里是创建场景的静态方法
static cocos2d::Scene* createScene();
//注意返回值是bool,用于初始化布景层的虚函数(为了继承这里用虚函数)(cocos2d-iphone中init返回的是id)
virtual bool init();
//关闭按钮的回调函数
void menuCloseCallback(cocos2d::Ref* pSender);
//引擎宏定义:手动实现静态方法create();并且调用init()方法
CREATE_FUNC(HelloWorld);
};
#endif
这里有个宏定义
CREATE_FUNC(__TYPE__)
跳进去源码看看它到底干了什么
static __TYPE__* create()
{
__TYPE__ *pRet = new __TYPE__();
if (pRet && pRet->init())
{
pRet->autorelease();
return pRet;
}
else
{
delete pRet;
pRet = NULL;
return NULL;
}
}
宏里面new了一个这个层的对象,如果对象new成功且调用init()方法返回真时,将对象放入自动释放池中(所以此对象的内存你以后都不需要关心了),然后把对象
返回。
如果对象new失败或者init()失败就删除对象(其实是个指针),然后将指针置空(防止你操作野指针),然后返回空。
然后我们来看实现文件
#include "HelloWorldScene.h"
//等价于using namespace cocos2d;引入命名空间
USING_NS_CC;
Scene* HelloWorld::createScene()
{
//场景scene是一个自动释放的对象(自己跳到create中看源码,跟前面说过个宏类似操作)
auto scene = Scene::create();
//布景层layer也是一个自动释放的对象
auto layer = HelloWorld::create();
//把layer加到scene中
scene->addChild(layer);
//返回scene
return scene;
}
//初始化方法init用于初始化布景层实例
bool HelloWorld::init()
{
// 1.新手常忘的操作,一定要先初始化父类cocos2d::Layer啊!!
if ( !Layer::init() )
{
return false;
}
//getVisibleSize:获得可视区域的大小,如果DesignResolutionSize跟屏幕尺寸一样大,则getVisibleSize与getWinSize一样,此处不深究。
Size visibleSize = Director::getInstance()->getVisibleSize();
//getVisibleOrigin:获得可视区域的原点坐标的实际坐标,在处理相对位置时,确保节点在不同分辨率下的位置一致,此处不深究。
Vec2 origin = Director::getInstance()->getVisibleOrigin();
//这是个MenuItem,这里理解为一个按钮,创建需要参数有常态图片资源、选中图片资源,点击之后要回调的方法.CC_CALLBACK_1回调会自动传入一个参数,相关内容自行查资料吧
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
//设置按钮位置
closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y + closeItem->getContentSize().height/2));
//创建一个menu,这里理解为存放按钮的容器,MenuItem必须放入Menu才能响应回调方法
auto menu = Menu::create(closeItem, NULL);
//设置menu位置在Vec2(0,0),原点左下角
menu->setPosition(Vec2::ZERO);
//将menu加入到this中,此时this是一个layer,第二个参数是优先级
this->addChild(menu, 1);
// 创建标签Label用于显示文本
auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - label->getContentSize().height));
this->addChild(label, 1);
//创建精灵Sprite显示图片
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
this->addChild(sprite, 0);
return true;
}
//刚刚创建的menuItem按钮的回调方法,发现传入一个参数,就是CC_CALLBACK_1帮你传的
void HelloWorld::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
}
补充:
【Vec2】二维向量Vec2是以前的Point,它既可以表示一个二维坐标点,又可以表示一个二维向量。
同时Vec2对运算符进行了重载,可以很方便的完成Vec2的赋值、加减乘除等操作。另外还有与坐标向量相关的:距离、角度、点积、叉积、投影、标准化等操作。
此外在3.x中,还将2.x里的函数定义ccp***(如ccp,ccpAdd,ccpSub)相关的操作都封装到了这个Vec2的类中,这样就可以更加系统化地管理向量的运算操作了。
此外,除了Vec2。还有两个坐标类:Vec3、Vec4,分别代表了三维、四维坐标向量。
【Size】 Size只是一个用来表示尺寸大小的类。宽为width,高为height。
和Vec2一样,也对运算符进行了重载。Size和Vec2之间可以相互转换。