一.Cocos2d-x引擎特性

现代化的 C++ API
立足于 C++ 同时支持 JavaScript/Lua 作为开发语言
可以跨平台部署, 支持 iOS、Android、Windows、macOS 和 Linux
可以在 PC 端完成游戏的测试,最终发布到移动端
完善的游戏功能支持,包含精灵、动作、动画、粒子特效、场景转换、事件、文件 IO、数据持久化、骨骼动画、3D


二.环境配置

要求:
Windows 7+,
VS 2015+
python2.7

JDK
SDK
NDK(可选)


三.cocos命令配置

1.cocos命令配置

Cocos2d-x 带有一个命令行工具:cocos 这是一个跨平台的工具,你可以用它创建项目、运行项目、发布项目。命令行工具适用于所有 Cocos2d-x 支持的平台,包括:iOS、Android、Mac、Linux、Windows、Web。不用 IDE,只用命令行,你就能完成所有的工作!

1.行引擎源码根目录的 setup.py
python setup.py

2.测试

cocos -v
Python 2.7.10
cocos2d-x-3.16
Cocos Console 2.3

2.cocos命令使用

  • 1.项目创建

cocos new MyGame -p com.MyCompany.MyGame -l cpp -d ~/MyCompany

  • 2.项目编译(程序从源码到二进制程序,有一个编译环节)

cocos compile . -p android -m release

  • 3.项目运行

cocos run . -p android -m release

  • 4.项目发布

cocos deploy -s c:\MyCompany\MyGame -p android -m release


四.日志输出

log("This would be outputted to the console");

string s = "My variable";
log("string is %s", s);

double dd = 42;
log("double is %f", dd);

int i = 6;
log("integer is %d", i);

float f = 2.0f;
log("float is %f", f);

五.基本功能

1.Director导演

Cocos2d-x 使用导演的概念,Director 任务是控制场景替换和转换。
Director是一个共享的单例对象,可以在代码中的任何地方调用。

2.Scene场景

场景(Scene) 是一个容器,容纳游戏中的各个元素,如精灵,标签,节点对象。它负责着游戏的运行逻辑,以帧为单位渲染内容。
1.场景创建

class MyScene : public cocos2d::Scene
{
public:
	static cocos2d::Scene* createScene();
	virtual bool init();

	// 实现crete静态方法
	CREATE_FUNC(StartScene);
};

//创建
auto myScene = MyScene ::create();

2.场景切换

//加载第一个场景
Director::getInstance()->runWithScene(myScene);

//切换场景
Director::getInstance()->replaceScene(myScene);

//叠加场景
Director::getInstance()->pushScene(myScene);

//释放场景
Director::getInstance()->popScene(myScene);

场景图
场景图(Scene Graph)是一种安排场景内对象的数据结构,它把场景内所有的 节点(Node) 都包含在一个 树(tree) 上。
Cocos2d-x 使用 中序遍历,先遍历左子树,然后根节点,最后是右子树。中序遍历下图的节点,能得到 A, B, C, D, E, F, G, H, I 这样的序列。

场景图

3.Layer层

Layer代表层,一般常做Scene的子容器,可以添加Sprite,相当于精灵的面板容器。

4.Sprite精灵

精灵是您在屏幕上移动的对象,它能被控制;

可以使用一张图像来创建精灵,PNG, JPEG, TIFF, WebP, 这几个格式都可以。当然也可以是图集

使用图片
auto mySprite = Sprite::create("mysprite.png");
使用图集

1.创建图集
Texture Packer工具创建并导出plist+png图集

2.加载图集

auto spritecache = SpriteFrameCache::getInstance();
spritecache->addSpriteFramesWithFile("sprites.plist");

3.创建精灵

auto mysprite = Sprite::createWithSpriteFrameName("mysprite.png");
精灵的控制
1.锚点
mySprite->setAnchorPoint(0.5, 0.5);
2.位置
mySprite->setPosition(Vec2(100, 200));
3.旋转
mySprite->setRotation(20.0f);
4.缩放
mySprite->setScale(2.0);
mySprite->setScaleX(2.0);
mySprite->setScaleY(2.0);
5.倾斜
mySprite->setSkewX(20.0f);//水平倾斜
mySprite->setSkewY(20.0f);//数直倾斜
6.颜色
mySprite->setColor(Color3B::WHITE);
mySprite->setColor(Color3B(255, 255, 255));
7.透明度
mySprite->setOpacity(30);

5.Action动作

动作(Action)通过改变一个 Node 对象的属性,让它表现出某种动作。动作对象能实时的改变 Node 的属性,任何一个对象只要它是 Node 的子类都能被改变。
1.单一动作

//从当前位置到目标位置
auto moveTo = MoveTo::create(2, Vec2(50, 10));
mySprite1->runAction(moveTo);
//从目标位置到当前位置
auto moveBy = MoveBy::create(2, Vec2(20,0));
mySprite2->runAction(moveBy);

2.动作序列和并列
还可以创建一个动作 序列(Sequence) 和Swan(并列)

auto mySprite = Node::create();

auto moveTo1 = MoveTo::create(2, Vec2(50,10));
auto moveBy1 = MoveBy::create(2, Vec2(100,10));
auto moveTo2 = MoveTo::create(2, Vec2(150,10));

mySprite->runAction(Sequence::create(moveTo1, moveBy1,moveTo2, nullptr));
//或者
mySprite->runAction(Spawn::create(moveTo1, moveBy1, moveTo2, nullptr));

六.UI组件

UI 代表用户界面,是 User Interface 的缩写,界面组件有标签,按钮,菜单,滑动条等

1.标签(Label)

//BMFont
auto myLabel = Label::createWithBMFont("bitmapRed.fnt", "Your Text");
//TTF
auto myLabel = Label::createWithTTF("Your Text", "Marker Felt.ttf", 24);
//SystemFont
auto myLabel = Label::createWithSystemFont("My Label Text", "Arial", 16);
//阴影效果
myLabel->enableShadow();
//描边效果
myLabel->enableOutline(Color4B::WHITE, 1));
//发光效果
myLabel->enableGlow(Color4B::YELLOW);

2.菜单(Menu)

//图片菜单
auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

//文字菜单
auto startItem = MenuItemText::create("StartGame",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

//menu总菜单
auto menu = Menu::create(startItem, closeItem, NULL);
this->addChild(menu, 1);

//Lambda写法
auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
[&](Ref* sender){
    // your code here
});

3.按钮(Button)

#include "ui/CocosGUI.h"。
auto button = Button::create("normal_image.png", "selected_image.png", "disabled_image.png");
button->setTitleText("Button Text");
button->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
        switch (type)
        {
                case ui::Widget::TouchEventType::BEGAN:
                        break;
                case ui::Widget::TouchEventType::ENDED:
                        std::cout << "Button 1 clicked" << std::endl;
                        break;
                default:
                        break;
        }
});

4.复选框(CheckBox)(Toggle开关)

#include "ui/CocosGUI.h"

auto checkbox = CheckBox::create("check_box_normal.png",
                                 "check_box_normal_press.png",
                                 "check_box_active.png",
                                 "check_box_normal_disable.png",
                                 "check_box_active_disable.png");

checkbox->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
        switch (type)
        {
                case ui::Widget::TouchEventType::BEGAN:
                        break;
                case ui::Widget::TouchEventType::ENDED:
                        std::cout << "checkbox 1 clicked" << std::endl;
                        break;
                default:
                        break;
        }
});

this->addChild(checkbox);

5.进度条(LoadingBar)

#include "ui/CocosGUI.h"
//创建进度条
auto loadingBar = LoadingBar::create("LoadingBarFile.png");
loadingBar->setDirection(LoadingBar::Direction::RIGHT);
//设置进度
loadingBar->setPercent(25);
//add节点
this->addChild(loadingBar);

6.文本框(TextField)

#include "ui/CocosGUI.h"

auto textField = TextField::create("","Arial",30);
textField->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
     std::cout << "editing a TextField" << std::endl;
});

this->addChild(textField);

七.监听事件

1.五种类型

EventListenerTouch - 响应触摸事件

EventListenerKeyboard - 响应键盘事件

EventListenerAcceleration - 响应加速度事件

EventListenMouse - 响应鼠标事件

EventListenerCustom - 响应自定义事件

2.事件的吞没(可做遮罩)

listener1->setSwallowTouches(true);
listener1->onTouchBegan = [](Touch* touch, Event* event){
    // your code
    return true;
};

3.触摸事件

让我们先了解一下什么是触摸事件,当你触摸移动设备的屏幕时,设备感受到被触摸,了解到被触摸的位置,同时取得触摸到的内容,然后你的触摸被回答。 这就是触摸事件。

//创建触摸
auto listener1 = EventListenerTouchOneByOne::create();
// 触摸开始
listener1->onTouchBegan = [](Touch* touch, Event* event){
    // your code
    Vec2 point = touch->getLocation();//获取点击位置
    return true; // if you are consuming it
};
// 触摸滑动
listener1->onTouchMoved = [](Touch* touch, Event* event){
    // your code
};
// 触摸结束
listener1->onTouchEnded = [=](Touch* touch, Event* event){
    // your code
};
// 添加监听(最重要的一步)
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);

4.鼠标事件

创建鼠标事件监听器:

//创建事件
_mouseListener = EventListenerMouse::create();
//设置不同监听
_mouseListener->onMouseMove = CC_CALLBACK_1(MouseTest::onMouseMove, this);
_mouseListener->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp, this);
_mouseListener->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown, this);

//绑定监听(最重要一步)
_eventDispatcher->addEventListenerWithSceneGraphPriority(_mouseListener, this);

//回调函数实现(也可以用匿名函数/Lambda)
void MouseTest::onMouseDown(Event *event){
	EventMouse* em = (EventMouse*)event;
	em->getLocation();//获取鼠标位置
}
void MouseTest::onMouseUp(Event *event){}
void MouseTest::onMouseMove(Event *event){}

5.键盘事件

对于桌面游戏,一般需要通过键盘做一些游戏内的控制,这时你就需要监听键盘事件。

//创建事件
auto listener = EventListenerKeyboard::create();
listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed, this);
listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased, this);
//添加监听
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

//实现回调函数
void KeyboardTest::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event){}

void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event){}

6.Update事件

如果需要持续的处理某个事件,那么可以开启一个update

//开启update
this->scheduleUpdate();
void Test::update(float delta)
{}

八.物理引擎

当你的需求很简单时,就不要使用物理引擎。比如只需要确定两个对象是否有碰撞,结合使用节点对象的 update 函数和 Rect 对象的 containsPoint(),intersectsRect() 方法可能就足够了。例如:

void update(float dt)
{
  auto p = touch->getLocation();
  auto rect1 = this->getBoundingBox();
  auto rect2 = this->getBoundingBox();
  if(rect1.containsPoint(p))
  {
      // do something, intersection
  }
  if(rect1.intersectsRect(rect2))
  {
      // do something, intersection
  }
}

1.刚体碰撞

如你要开发一个游戏,一个场景有 100 个精灵对象,需要判断它们互相是否有碰撞,如果使用上诉方法那将非常复杂,同时性能消耗还会严重影响 CPU 的使用率和游戏运行的帧率,这游戏根本没法玩。
这个时候就需要物理引擎了。

/*创建物理场景*/
auto scene = Scene::createWithPhysics();
//显示物理引擎调试界面 --- 有红框
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
//可把自己的类定义为Layer
auto layer = MyScene::create();
scene->addChild(layer);


/*创建边框测试*/
//创建一个物理世界, 大小和屏幕的尺寸相同, 使用默认材质, debug框的宽度为3个像素
auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);
auto edgeShape = Node::create();//创建一个碰撞图形
edgeShape->setPhysicsBody(body);//将图形和刚刚创建的世界绑定
edgeShape->setPosition(visibleSize.width / 2, visibleSize.height / 2);//设置图形的位置在屏幕正中间
this->addChild(edgeShape);


/*创建静态刚体精灵*/
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(center);
this->addChild(sprite);
//添加静态的刚体
auto physicsBody = PhysicsBody::createBox(sprite->getContentSize(),
PhysicsMaterial(0.1f, 1.0f, 0.0f));
physicsBody->setDynamic(false);
//设置碰撞层
physicsBody->setCategoryBitmask(8);//种类
physicsBody->setCollisionBitmask(16);//碰撞
physicsBody->setContactTestBitmask(16);//接触
//把刚体赋给精灵
sprite->addComponent(physicsBody);


/*创建动态刚体精灵*/
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(center);
this->addChild(sprite);
//添加静态的刚体
auto physicsBody = PhysicsBody::createBox(sprite->getContentSize(),
PhysicsMaterial(0.1f, 1.0f, 0.0f));
physicsBody->setGravityEnable(false);
//设置碰撞层
physicsBody->setCategoryBitmask(16);//种类
physicsBody->setCollisionBitmask(8);//碰撞
physicsBody->setContactTestBitmask(8);//接触
//把刚体赋给精灵
sprite->addComponent(physicsBody);


/*添加碰撞事件*/
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = [](PhysicsContact& contact) {
	log("OnCollision");
	//auto nodeA = contact.getShapeA()->getBody()->getNode();
	//auto nodeB = contact.getShapeB()->getBody()->getNode();
	return true;
};
//绑定监听事件
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);

2.查询

  • 1.点查询
  • 2.射线查询

九.音乐和音效

你的游戏肯定会需要音乐和音效!Cocos2d-x 提供了一个 SimpleAudioEngine 类支持游戏内的音乐和音效。它可以被用来增加背景音乐,控制游戏音效。
SimpleAudioEngine 是一个共享的单例对象,

#include "SimpleAudioEngine.h"
using namespace CocosDenshion;

// 播放背景音乐
auto audio = SimpleAudioEngine::getInstance();
audio->playBackgroundMusic("mymusic.mp3", loop);
// 暂停/停止/恢复 背景音乐
audio->pauseBackgroundMusic();
audio->stopBackgroundMusic();
audio->resumeBackgroundMusic();

//播放音效
audio->playEffect("myEffect.mp3", false, 1.0f, 1.0f, 1.0f);
// 暂停/停止/恢复 音效
audio->pauseEffect();audio->stopEffect();audio->resumeEffect();
// 暂停/停止/恢复 所有音效
audio->pauseAllEffects();audio->stopAllEffects();audio->resumeAllEffects();
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐