网站建设综合实训心得,温州专业做网站,漯河做网站的,江门网站建设维护常用链接
Cocos2d-x 用户手册
参考书目
《Cocos2d-X游戏开发实战精解》 《我所理解的Cocos2d-x》 《Effective C》中文版第三版
环境搭建
macOS 10.15.6 Xcode 11.5 cocos2d-x 3.17.2 cmake 3.17.3
创建工程
采用cocos2d-x 3.17版本可直接通过cocos console创建#xf…常用链接
Cocos2d-x 用户手册
参考书目
《Cocos2d-X游戏开发实战精解》 《我所理解的Cocos2d-x》 《Effective C》中文版第三版
环境搭建
macOS 10.15.6 Xcode 11.5 cocos2d-x 3.17.2 cmake 3.17.3
创建工程
采用cocos2d-x 3.17版本可直接通过cocos console创建4.0版本需要额外通过cmake生成.xcodeproj文件。
cocos new 工程名 -p com.cocos2dx.工程名 -l cpp -d 目录名/Users/xxx架构分析
目录分析 Classes存放逻辑代码Resource存放资源文件 C文件由.hpp声明和.cpp定义及初始化组成
AppDelegate.h
#ifndef _APP_DELEGATE_H_ // 宏定义 保证头文件不需要多次编译
#define _APP_DELEGATE_H_#include cocos2d.hclass AppDelegate : private cocos2d::Application
{
public:AppDelegate(); // 构造virtual ~AppDelegate(); // 虚析构virtual void initGLContextAttrs(); // 初始化openGL参数virtual bool applicationDidFinishLaunching(); // 应用进入virtual void applicationDidEnterBackground(); // 应用中途退入后台virtual void applicationWillEnterForeground(); // 应用中途来电// 虚析构函数能够保证当用一个基类的指针删除一个派生类的对象时派生类的析构函数会被调用// 虚函数被继承后仍然是虚拟函数可以省略掉关键字“virtual”
};#endif // _APP_DELEGATE_H_
AppDelegate.cpp
#include AppDelegate.h
#include MainScene.hUSING_NS_CC;
// visiableSize
static cocos2d::Size designResolutionSize cocos2d::Size(1386, 640);
static cocos2d::Size smallResolutionSize cocos2d::Size(480, 320);
static cocos2d::Size mediumResolutionSize cocos2d::Size(1024, 768);
static cocos2d::Size largeResolutionSize cocos2d::Size(2048, 1536);AppDelegate::AppDelegate()
{
}AppDelegate::~AppDelegate()
{
}void AppDelegate::initGLContextAttrs()
{// set OpenGL context attributes: red, green, blue, alpha, depth, stencil, multisamplesCountGLContextAttrs glContextAttrs {8, 8, 8, 8, 24, 8, 0};GLView::setGLContextAttrs(glContextAttrs);
}bool AppDelegate::applicationDidFinishLaunching() {auto director Director::getInstance();auto glview director-getOpenGLView();if(!glview) {director-setOpenGLView(glview);}// 显示演示信息director-setDisplayStats(true);// 设置帧率director-setAnimationInterval(1.0f / 60);// designResolutionSize 设计分辨率大小glview-setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::FIXED_WIDTH);// frameSize 手机分辨率大小auto frameSize glview-getFrameSize();// 适配策略if (frameSize.height mediumResolutionSize.height) {director-setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));} else if (frameSize.height smallResolutionSize.height) {director-setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));} else {director-setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));}// 创建场景auto mainScene MainScene::createScene();// 导演类调度场景director-runWithScene(mainScene);return true;
}void AppDelegate::applicationDidEnterBackground() {Director::getInstance()-stopAnimation();
}
void AppDelegate::applicationWillEnterForeground() {Director::getInstance()-startAnimation();
}MainScene.hpp
#ifndef __MAIN_SCENE_H__
#define __MAIN_SCENE_H__#include cocos2d.h
// 继承Scene
class MainScene : public cocos2d::Scene
{
public:static cocos2d::Scene* createScene(); // 静态用于获取场景对象virtual bool init() override; // 初始化场景CREATE_FUNC(MainScene); //
};#endif // __HELLOWORLD_SCENE_H__MainScene.cpp
#include MainScene.hUSING_NS_CC; // 等同于 using namespace cocos2d
Scene* HelloWorld::createScene()
{auto scene Scene::create(); // 创建一个Scene对象auto layer MainScene::create(); // 创建一个MainScene对象scene-addChild(layer); // 将layer加入到场景中return scene;
}bool mainScene::init()
{if ( !Scene::init() ){return false;}// 在这里添加逻辑代码return true;
}层的生命周期函数
bool init() // 初始化层调用
void onEnter() // 进入层时调用
void onEnterTransitionDidFinish() // 进入层且过渡动画结束时调用
void onEixt() // 退出层时调用
void onEixtTransitionDidStart() // 退出层且开始过渡动画时调用
void cleanup() // 层对象被清除时调用场景文件
// .h文件
#ifndef __SET_SCENE__
#define __SET_SCENE__#include cocos2d.hclass SetScene : public cocos2d::Scene
{
public:static cocos2d::Scene* createScene();virtual bool init();CREATE_FUNC(SetScene);
private:int volume 50;
};
#endif
--------------------------------------------------------------------------------------
// .cpp文件
#includeSetScene.hUSING_NS_CC;Scene* SetScene::createScene() { return SetScene::create(); }
bool SetScene::init()
{if (!Scene::init()){return false;}auto visibleSize Director::getInstance()-getVisibleSize();Vec2 origin Director::getInstance()-getVisibleOrigin();
}普通文件
// .h文件
#ifndef _PROP_H_
#define _PROP_H_
#include cocos2d.hUSING_NS_CC;class Prop : public Entity {
public:Prop();~Prop();CREATE_FUNC(Prop);virtual bool init();
};
#endif;
--------------------------------------------------------------------------------------
// .cpp文件
#include prop.hProp::Prop() {}
Prop::~Prop() {}
bool Prop::init() { return true; }
void Prop::createProp(float _x, float _y) {this-x x;this-y y;}
}
--------------------------------------------------------------------------------------
// 实例化
Prop* props Prop::create();
props-createProp(10, 20);二段构造
// 二段构造的宏函数其中(std::nothrow)当new失败后强制返回指针而非try-catch异常
#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \__TYPE__ *pRet new(std::nothrow) __TYPE__(); \if (pRet pRet-init()) \{ \pRet-autorelease(); \return pRet; \} \else \{ \delete pRet; \pRet nullptr; \return nullptr; \} \
}二段构造并非经典23种设计模式之一按照cocos2d-x创始人王哲对于为什么要设计成二段构建的看法 其实我们设计二段构造时首先考虑其优势而非兼容cocos2d-iphone。初始化时会遇到图片资源不存在等异常而C构造函数无返回值只能用try-catch来处理异常启用try-catch会使编译后二进制文件大不少故需要init返回bool值。Symbian, Bada SDKobjc的alloc init也都是二阶段构造。 我们暂且接受非兼容cocos2d-iphone这个理由反正我不信。按我个人的理解既然C现在已经愿意支持try-catch了说明C本身已经不在乎这些二进制文件的体量问题了更不用说对于java、C#等一些语言来说异常已是必备的特性。而且既然C都决定支持异常还为了这些老版本的技术提供(std::nothrow)强制返回指针自然也表明了并不推荐返回指针了。 所以实际上对于cocos来说已经不需要采用二段构建来实例化一个类了只是没有人在愿意调整框架底层cocos的每个内置类诸如Sprite、Button等都是采用的二段构建。所以对于开发者来说需要用的地方自然是要用的自己写的类可用可不用。不过cocos在实现二段构建的同时已经实现了简化版的垃圾回收机制可以省去new/delete操作所以还是能够简化一些操作的。 常用功能
UI布局
Layer的锚点默认为左下角其他Node的锚点默认为中心 Layer要设置锚点必须先layerTest-setIgnoreAnchorPointForPosition(false); 锚点不等于原点
切换场景
// include ShopScene.hpp
Director::getInstance()-replaceScene(ShopScene::createScene());通过图集加载图片
// 使用texture package将美术提供的tps文件转化为plist和pvr.czz文件
ZipUtils::setPvrEncryptionKey() // plist-czz需要md5秘钥解码
SpriteFrameCache *sfc SpriteFrameCache::getInstance(); // 定义SpriteFrameCache
sfc-addSpriteFrameWithFile(xxx.plist); // 调用实例方法addSpriteFrameWithFile()auto mainBg Sprite::createWithSpritesFrameName(xxx.png); // 使用图集加载图片添加Button
// include ui/CocosGUI.h
auto btn cocos2d::ui::Button::create();
btn-loadTextures(xxx_normal.png, xxx_pressed.png, , cocos2d::ui::Widget::TextureResType::PLIST);
btn-setPosition(Vec2(20, 100));
this-addChild(btn);添加文本
auto label Label::createWithTTF(Hello World, fonts/Marker Felt.ttf, 24);
auto label2 Label::createWithSystemFont(Hello World, Arial, 24);
label-setPosition(Vec2(20, 100));
this-addChild(label);添加事件
// 方法一设置监听器由_eventDispatcher派发事件。需要注意的是在添加到多个对象时需要使用clone()方法。
auto listener EventListenerTouchOneByOne::create();listener-setSwallowTouches(true);listener-onTouchBegan [](Touch *touch, Event* event) {// 自己实现事件区域检测默认全屏可触发auto target static_castSprite*(event-getCurrentTarget());//获取到你点击的对象具体是哪个精灵Point locationInNode target-convertTouchToNodeSpace(touch);//获取到点击位置在你这个对象的相对位置Size size target-getContentSize();//对象内容大小在后面用来判断是否点中了某对象的区域Rect rect Rect(0, 0, size.width, size.height);//包含这个对象的矩形区域if (rect.containsPoint(locationInNode))//矩形局域检测点是否在矩形内部{printf(点到了图片);Director::getInstance()-replaceScene(HelloWorld::createScene());return true;}return false;};_eventDispatcher-addEventListenerWithSceneGraphPriority(listener, btn);// 方法二直接通过对象挂载事件监听器
btn-addTouchEventListener([](Ref* sender, cocos2d::ui::Widget::TouchEventType type){switch (type){default:break;case ui::Widget::TouchEventType::BEGAN:break;case ui::Widget::TouchEventType::ENDED:break;}
});
// []默认不捕获任何变量
// []默认以值捕获所有变量
// []默认以引用捕获所有变量
// [x]仅以值捕获x其它变量不捕获添加菜单
// 1. 创建标签
auto volumeHigherLab Label::createWithTTF(, fonts/Marker Felt.ttf, 150);
auto volumeLowerLab Label::createWithTTF(-, fonts/Marker Felt.ttf, 150);
// 2. 创建菜单项
auto volumeHigherMenu MenuItemLabel::create(volumeHigherLab, CC_CALLBACK_1(SetScene::menuCloseCallbackVolumeHigher, this));
auto volumeLowerMenu MenuItemLabel::create(volumeLowerLab, CC_CALLBACK_1(SetScene::menuCloseCallbackVolumeLower, this));
// 3. 创建菜单
MenuHigherVolume Menu::create(volumeHigherMenu, NULL);
MenuLowerVolume Menu::create(volumeLowerMenu, NULL);
// 4. 设置位置并添加到场景中
MenuHigherVolume-setPosition(850, 250);
MenuLowerVolume-setPosition(960, 260);
this-addChild(MenuHigherVolume, 1);
this-addChild(MenuLowerVolume, 1);
添加动画
// 绕y轴旋转180,5s
auto* rotateBy RotateBy::create(5.0f, Vec3(0, 180, 0));
// 定义回调函数
auto* callFun CallFunc::create(CC_CALLBACK_0(MainScene::rotateFun, this));
// 定义动画序列
auto* sequence Sequence::create(rotateBy, callFun, NULL);
sprite-runAction(sequence);添加定时器
// 在init()中进行调用
scheduleUpdate(); // 重写Update(float dt)方法
schedule(schedule_selector(MainScene::myUpdate), 0.2f); // 自定义方法读取XML文件
// #include tinyxml2/tinyxml2.h
auto doc new tinyxml2::XMLDocument();
doc-Parse(FileUtils::getInstance()-getStringFromFile(data.xml).c_str()); // 调用解析函数
auto root doc-RootElement(); // 从根节点开始查找
for (auto e root-FirstChildElement(); e ! NULL; e e-NextSiblingElement()) {for (auto attr e-FirstAttribute(); attr ! NULL; attr attr-Next()) {printf(%s %s\n, attr-Name(), attr-Value());}读取json文件
// #include json/document.h
rapidjson::Document d;
d.Parse0(FileUtils::getInstance()-getStringFromFile(data.json).c_str()); // 调用解析函数 0默认解析方式
printf(%s,d[0][name].GetString());读取本地存储
UserDefault::getInstance()-getIntegerForKey(int); // 设置key
UserDefault::getInstance()-setIntegerForKey(int, 999); // 读取key
printf(saved file path is %s\n, UserDefault::getInstance()-getXMLFilePath().c_str()); // 存储路径
网络编程
弱联网CURL库 强联网socket
音频控制
// 声明 .h
CocosDenshion::SimpleAudioEngine* audio;
// 定义 .cpp
audio CocosDenshion::SimpleAudioEngine::getInstance();
if (!audio-isBackgroundMusicPlaying())audio-playBackgroundMusic(xxx.mp3, true);骨骼动画
// #include cocostudio/CocoStudio.h
// using namespace cocostudio;
// 引入骨骼动画文件保证plist和json在同一个目录下
ArmatureDataManager::getInstance()-addArmatureFileInfo(ani_mainshop.ExportJson);
auto armature Armature::create(ani_mainshop);
armature-getAnimation()-playWithIndex(1); // 按照Animation的index添加动画
armature-setPosition(Vec2(0, 0));
mainShopCarBg-addChild(armature, 1);游戏控制
CCScheduler* defaultScheduler CCDirector::sharedDirector()-getScheduler();
defaultScheduler-setTimeScale(2.0f); // 全局加速
defaultScheduler-pauseTarget(this); // 暂停游戏
defaultScheduler-resumeTarget(this); // 恢复游戏开发经验
最小化在编写代码前需要了解的信息 不是解决任何问题都要从头做起 框架只是让你规范地去开发 设计模式是学习OOP的最佳模板