cocos 添加插件

2015年01月27日 11:06 0 点赞 0 评论 更新于 2017-05-08 11:51

下面将详细介绍 Cocos 添加插件相关内容,主要流程如下:

1、Cocos2d-x 项目的执行流程

Cocos2d-x 和 Python 的版本更迭速度快且兼容性不佳,这给开发者带来了一些不必要的麻烦。本文使用的是 Cocos2d-x 3.1 版本,创建好项目后,在 pro.win32 中打开 VS 工程。

任何 C++ 程序,无论项目规模大小,其与操作系统的接口都是通过 Main 函数实现的。需要注意的是,程序中调用的自定义函数和 main 函数不一定要放在同一个文件中。例如,可以在 main.c 文件中存放 main 函数,在另一个文件中编写要在 main 函数里调用的函数,最后在编译器将代码编译成可执行文件时,通过连接器连接这两个文件,形成最终的程序。

转到 run 函数可以看到,代码注释提示需要初始化一个应用实例,划红线处的函数应该就是初始化函数。若初始化失败,整个程序将立即退出。

转到该函数后,会发现其中包含一些初始化函数,划红线的代码用于创建一个场景,可理解为创建了一个大的框架。查看该函数的定义,执行的是 bool HelloWorld::init() 函数。这个函数内部包含插入图片、插入文字等代码,也就是说,执行 Cocos2d-x 程序时最初看到的内容,都是由该函数内的代码实现的。因此,重写这个方法,就能按照自己的想法初始化窗口。

2、如何使用 Sprite 控件

Sprite 控件与 2D 图像相关,可使用以下函数创建 Sprite 精灵对象,从而在场景中添加 2D 图像,之后需使用 addChild 方法将其添加到场景中。

static Sprite* create(const std::string &filename);

参数说明

  • filename:包含路径的图像文件名,例如 "scene1/monster.png"

返回值

返回自动释放的 Sprite 对象。创建后,Sprite 的尺寸大小与图像相同,且偏移被置为 (0, 0)

运行程序后,虽能看到图片显示,但位置可能不对,这就涉及到“锚点”的概念。锚点类似于定位点,每个通过 addChild 方法添加的节点都有一个锚点,默认情况下为 (0.5, 0.5)。可以使用 s->setAnchorPoint(Point(0, 0)); 方法设置锚点,具体用法可查阅官方 API:http://cn.cocos2d-x.org/doc/cocos2d-x-3.0/d8/de9/groupspritenodes.html#gac1be6ca229d92a1a145fda8a7eece771

3、Cocos2d-x 之 Director、Scene、Layer

从上面的分析可知,程序初始化时会初始化一些变量,第一行是初始化 Director,它可类比为导演。在 Cocos2d-x - 3.0x 引擎中,采用节点树形结构管理游戏对象。一个游戏可划分为不同的场景,一个场景又可分为不同的层,一个层可拥有任意个可见的游戏节点。Director 是整个引擎的核心,负责管理游戏场景的转换、游戏的暂停等,就像真正的导演一样。整个项目只有一个 Director 对象,通过 getInstance 方法初始化创建。

Scene 是游戏的场景,通过初始化函数创建。在创建场景的函数 createScene 中,会包含创建一个层(Layer)。这三个对象存在密切的逻辑关系。

开发游戏时,首先要创建 Director 对象,设置游戏的各种参数;然后为游戏创建不同的场景,即大的背景、平台等;在此基础上创建 Layer 对象,并将所需的游戏元素(通过 addChild 方法添加的节点)放在层上。

4、Cocos2d-x 是如何呈现图形的

由于 applicationDidFinishLaunching() 是程序的入口,项目会自动生成一些创建场景的代码。为了深入了解 Cocos2d-x 呈现图形的原理,我们可以注释掉自动生成的代码,自行编写。

bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLView::create("My Game");
director->setOpenGLView(glview);
}

// turn on display FPS
director->setDisplayStats(true);

// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);

// create a scene. it's an autorelease object
Scene *scene = Scene::create();        // 创建一个场景
Layer *layer = Layer::create();        // 创建一个层
scene->addChild(layer);                // 在场景中添加一个层
Sprite *s = Sprite::create("dota2.jpg");  // 创建一个 2D 图像元素
s->setAnchorPoint(Point(0, 0));         // 设置锚点
layer->addChild(s);                    // 将节点加入层中

// run
director->runWithScene(scene);

return true;
}

代码中的具体功能已添加注释。

5、LOG 控件

LOG 控件类似于 printf 函数,是一个用于输出信息的 API。

6、MessageBox 控件

MessageBox 控件的功能与 MFC 中的类似,都是用于显示弹窗信息,具体使用方法可查阅官网文档。

补充说明

Size size = Director::getInstance()->getVisibleSize();  // 获取屏幕可见区域的大小

这句话很实用,可用于获取当前屏幕可见区域的大小尺寸。

7、LabelTTF 文本标签控件

使用 LabelTTF 文本标签控件的步骤与使用其他标签基本相同,以下是示例代码:

bool HelloWorld::init() {
// 1. super init first
if ( !Layer::init() ) {
return false;
}

Size size = Director::getInstance()->getVisibleSize();  // 获取屏幕可见区域的大小
LabelTTF *label = LabelTTF::create();
label->setString("hello xuran");  // 设置文本标签内容
label->setFontSize(36);           // 设置文字大小
label->setPosition(size.width/2, size.height/2); // 设置位置
addChild(label);

return true;
}

8、TextFieldTTF 控件的使用

TextFieldTTF 控件用于在场景中添加文本输入框,但添加后需要启动输入法才能使用键盘输入。

bool HelloWorld::init() {
// 1. super init first
if ( !Layer::init() ) {
return false;
}

Size size = Director::getInstance()->getVisibleSize();  // 获取屏幕可见区域的大小
TextFieldTTF *tf = TextFieldTTF::textFieldWithPlaceHolder("Please input words","宋体",36); // 根据各项参数创建一个文本编辑框
tf->setPosition(size.width/2, size.height/2);           // 设定其位置在屏幕中间
addChild(tf);

auto listener = EventListenerTouchOneByOne::create();   // 设立一个事件监听器
listener->onTouchBegan = [tf](Touch *t, Event *event) {
if(tf->getBoundingBox().containsPoint(t->getLocation())) {  // 获取触摸点并且判断触摸点是否包含在文本编辑框内
tf->attachWithIME();  // 为这个控件启用输入法
} else {
tf->detachWithIME();
}
return false;
};

Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, tf); // 利用导演添加一个对事件的监听器
return true;
}

9、自定义一个类

如果想在界面中添加 2D 图像,且不想在 init 函数中使用 Sprite 的方式添加,而是实现一些自定义功能,就需要自定义一个类。由于要使用自己创建的类在场景中添加 2D 图像节点,因此需要继承 Sprite 类,因为该类提供了很多实用的功能。

以下是自定义 ball 类的示例代码:

ball.h

#pragma once
#include <iostream>
#include "cocos2d.h"
using namespace cocos2d;

class ball: public Sprite {
public:
virtual bool init();
static ball* create() {
ball* b = new ball();
b->init();
b->autorelease();
return b;
}
};

ball.cpp

#include "ball.h"

bool ball::init() {
initWithFile("ball.png");
return true;
}

在场景类的 init 函数中使用

auto b = ball::create();
b->setPosition(200, 200);
addChild(b);

通过自定义类,可以实现之前使用 Sprite 的功能,还能在此基础上进行扩展。

10、Menu 控件的使用

Menu 是菜单控件,MenuItem 是菜单项,菜单是多个菜单项的集合。可以创建文字版或图片版的菜单项,但 Menu 集合只接受 MenuItem 作为子元素。

auto menu = Menu::create(MenuItemImage::create("5.png", "6.png", [](Object *obj) {
log("menu item touched");
}), NULL);
addChild(menu);

上述代码创建了一个菜单控件,并使用 MenuItemImage::create 创建了一个图片菜单项,指定了选择菜单项前后的图片,以及选中菜单项后的回调函数。

作者信息

boke

boke

共发布了 1025 篇文章