一.前言
之前有机会接触了cocos2d-js(cocos2d-x的一个分支)相关的技能,这儿就做一个回忆和解说,会从cocos2d-x的历史架构再到cocos2d-js和2d-x的差异开端,一起也介绍下之前cocos项目的整体结构和运用到的中心知识点,也便利自己后续回忆,现在,cocos官方现在大力引荐的是cocos creator,由于之前在做项目时候cocos creator不是非常成熟,加上js语法简练和跨渠道支撑等原因,再到项目中的游戏模块不是很复杂择终究了就挑选运用cocos2d-js分支来开发。
假如在现阶段要开发一个cocos 游戏,大力引荐运用cocos creator,这个也是cocos官方大力引荐的,cocos2d-x引擎的更新速度已怠慢,cocos2d-js已经不再更新了,creator 已经是未来开发cocos游戏的必选的工具和趋势,cocos creator 和cocos2d-x 是彻底不同的两个东西,包含引擎架构和开发流程是彻底不相同的,creator这儿不再多说,我这边仍是要介绍下cocos2d-x相关的技能知识。
二.cocos2d-x 介绍
cocos2d-x是什么
Cocos2d-x 是 MIT 许可证下发布的一款功用强大的开源游戏引擎。
答应开发人员运用 C++、Javascript 及 Lua 三种言语来进行游戏开发。
支撑一切常见渠道,包含 iOS、Android、Windows、macOS、Linux。
引擎特性
- 现代化的 C++ API
- 立足于 C++ 一起支撑 JavaScript/Lua 作为开发言语
- 能够跨渠道部署, 支撑 iOS、Android、Windows、macOS 和 Linux
- 能够在 PC 端完结游戏的测验,终究发布到移动端
- 完善的游戏功用支撑,包含精灵、动作、动画、粒子特效、场景转化、事件、文件 IO、数据持久化、骨骼动画、3D
商场占有
Cocos2d-x 用户不只包含个人开发者和游戏开发爱好者,还包含许多知名大公司如 Zynga、Wooga、Gamevil、Glu、GREE、Konami、TinyCo、HandyGames、IGG 及 Disney Mobile 等。
运用 Cocos2d-x 开发的许多游戏占据苹果运用商店和谷歌运用商店排行榜,一起许多公司如触控、谷歌、微软、ARM,英特尔及黑莓的工程师在 Cocos2d-x 范畴也非常活跃。
在我国,每一年的手游榜单大作,Cocos2d-x 从未缺席,商场份额占 50% 以上,游戏品类掩盖从轻度休闲,热火棋牌,到横版,SLG,重度 MMO 等市道全品类。一些以 Cocos2d-x 为基础开宣布的游戏如下:
游戏引擎是一种特殊的软件,它供给游戏开发时需求的常见功用;引擎会供给许多组件,运用这些组件能缩短开发时间,让游戏开发变得更简单;专业引擎通常会能比自制引擎表现出更好的性能。游戏引擎通常会包含烘托器,2D/3D 图形元素,磕碰检测,物理引擎,声音,操控器支撑,动画等部分。
Cocos2d-x 便是这样的一个游戏引擎,它供给了许多易于运用的组件,有着更好的性能,还一起支撑移动端和桌面端。Cocos2d-x 经过封装底层图形接口供给了易用的API,降低了游戏开发的门槛,让运用者能够专注于开发游戏,而不必关注底层的技能细节。更重要的是 Cocos2d-x 是一个彻底开源的游戏引擎,这就答应您在游戏开发过程中依据实际需求,定制化引擎的功用,假如您想要一个功用但又不知如何修改,提出这个需求,全世界的开发者能够一起为您完结。
cocos2d-x的几个基本中心概念
导演
Cocos2d-x 运用导演的概念,这个导演和电影制造过程中的导演相同!导演操控电影制造流程,辅导团队完结各项使命。在运用 Cocos2d-x 开发游戏的过程中,你能够以为自己是履行制片人,告知导演(Director)该怎样办!一个常见的Director使命是操控场景替换和转化。Director是一个共享的单例目标,能够在代码中的任何地方调用。
如下 Director就负责场景的转化:
场景(Scene)
在游戏开发过程中,你或许需求一个主菜单,几个关卡和一个完毕场景。如何组织一切这些分隔的部分?运用场景(Scene)!当你想到喜欢的电影时,你能观察到它是被分化为不同场景或不同故事线。现在咱们对游戏开发运用这个相同的思维过程,你应该很容易就能想出几个场景。
场景图(Scene Graph)是一种组织场景内目标的数据结构,它把场景内一切的节点 (Node)都包含在一个树 (tree)上。(场景图尽管叫做”图”,但实际运用一个树结构来表示)。
分化这个场景,看一下它有哪些元素,这些终究会被烘托为一个树。
精灵(Sprite)
一切的游戏都有精灵(Sprite)目标,精灵是您在屏幕上移动的目标,它能被操控。你喜欢玩的游戏中主角或许便是一个精灵,我知道你在想是不是每个图形目标都是一个精灵,不是的,为什么? 假如你能操控它,它才是一个精灵,假如无法操控,那就仅仅一个节点(Node)。
看下面的图片,咱们来指出一下,哪个是精灵(Sprite),哪个是节点(Node)。
动作(Action)
创立一个场景,在场景里面添加精灵仅仅完结一个游戏的第一步,接下来咱们要处理的问题便是,怎样让精灵动起来。动作(Action)便是用来处理这个问题的,它能够让精灵在场景中移动,如从一个点移动到别的一个点。你还能够创立一个动作序列(Sequence),让精灵按照这个序列做接连的动作,在动作过程中你能够改变精灵的方位,旋转视点,缩放比例等等。
序列(Sequence)
能在屏幕上移动精灵,是制造一个游戏所需的一切,是吗?不是的,至少要考虑一下如何履行多个Action。Cocos2d-x 经过序列(Sequence)来支撑这种需求。
顾名思义,序列便是多个动作按照特定次序的一个摆放,当然反向履行这个序列也是能够的,Cocos2d-x 能很便利的完结这项工作。
如下是一个经过序列操控精灵移动的例子:
当然远远不止这些,除此之外还有物理引擎的支撑(例如磕碰查看重力等)、音视频模块如(音乐音效支撑等模块)具体能够查看官方文档
docs.cocos.com/cocos2d-x/m…
Cocos2d引擎家族介绍
cocos2d架构图
Cocos2d-JS是Cocos2d-x中的JavaScript版别,是Cocos2d-HTML5的延伸,官方对根据Web引擎的H5版别和根据Native的C++版别进行了整合,并在API层供给了一致的JavaScript API,使得Cocos开发更加容易
由于之前选用的是cocos2d-js,以下会偏重解说js相关内容
二.快速开发一个cocos2d-js项目
项目结构
文件目录介绍
- framework
- cocos2d-html5 网页端的工程目录
- cocos2d-x cocos引擎代码目录
- runtime-src
runtime-src
-
Classes 是navtive 的app入口文件
-
proj.xxx 针对 iOS 安卓 Mac 等渠道的工程目录
-
Index.html是网页端的发动文件,假如仅仅发布客户端能够忽略
-
main.js 是 cocos2d-js的发动入口文件,相当于 iOS 中工程的main文件
-
manifest.webapp 是一些描绘信息一般用不到
- project.json 是装备项目资源的中心文件 首要包含后续js类文件的引用
- res 一切用到资源的文件目录(图片 音频 字体 动画资源等等)
- src
也便是js代码的目录 这个文件夹下有一个resource.js 文件 项目中用到的资源文件需求在此文件中引用方可加载
以上为整个工程的文件目录功用介绍
开发工具
由于cocos2d-js 是根据js来开发的,那么关于编辑器就需求用到js相关开发工具,引荐webstrom 或者 vscode ,别的假如需求用到原生相关的功用,比如iOS 相关的,那么就需求用到xcode,假如是安卓就要用Android studio。
环境建立&生成工程
github.com/cocos2d/coc…
这儿拿3.17.2版别为例,下载完结后目录如下
cocos2d-x.org/filedown/co…
Setup.py为环境装备脚本,由于现在此版别脚本python 要求 2.x 版别 ,我这边就不去演示了,由于我电脑是python 3.x ,有爱好的能够自己去装置一个2.x 测验。
官方的目录下有关于js的demo 示例 目录在 js-tests里面,有爱好的能够逐一研究下官方demo
装置完结环境 经过 cocos new 快速生成工程模板
cocos **new** -**l** js ProjectName
模板如下
模板中心源码介绍
拿iOS 工程举例解说
能够看到 和 iOS 新建工程类似,差异在于cocos 项目是在发动生命周期做了cocos引擎的初始化并且加载了一个GLView来烘托
cocos2d::Application *app = cocos2d::Application::getInstance();
// Initialize the GLView attributes
app->initGLContextAttrs();
cocos2d::GLViewImpl::convertAttrs();
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
// Use RootViewController to manage CCEAGLView
_viewController = [[RootViewController alloc]init];
_viewController.wantsFullScreenLayout = YES;
// Set RootViewController to window
if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
// warning: addSubView doesn't work on iOS6
[window addSubview: _viewController.view];
}
else
{
// use this method on ios6
[window setRootViewController:_viewController];
}
[window makeKeyAndVisible];
[[UIApplication sharedApplication] setStatusBarHidden:true];
// IMPORTANT: Setting the GLView should be done after creating the RootViewController
cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView((__bridge void *)_viewController.view);
cocos2d::Director::getInstance()->setOpenGLView(glview);
//run the cocos2d-x game scene
app->run();
return YES;
}
此外initGLContextAttrs是cocos 的初始化中心办法,也便是发动js相关模块的初始化办法,中心办法都在AppDelegate.cpp类里面
一起能够看到applicationDidFinishLaunching 中的 ScriptingCore::getInstance()->runScript(“main.js”); 即为发动js模块的入口类
App前后台切换暂停 重启游戏都是经过原生调用cocos引擎来完结的
这儿main.js 运行起来后 就开端了游戏的初始化流程了,我这儿拿我之前做的项目来展现
//load resources
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new SXTHomePageScene());
}, this);
即为第一个页面场景的类,在场景加载之前能够自定义的处理一些工作,如预加载资源,做屏幕适配等初始化等,后边我会详细讲下我之前项目的整体结构和大概功用点。
实战项目功用介绍
我这边会结合我之前做的项目 介绍下 cocos2d-js相关的开发 以及 cocos和 na交互能技能,包含cocos2d-js 功用代码结构等,以及 cocos 中心概念动画等。
我这边拿部分功用举例
cocos2d-js项目结构
我这边不详细介绍游戏完结,首要说下项目模块的功用整理和结构
游戏模块
游戏网络恳求
首要经过Api 完结游戏事务网络恳求处理
一致经过Network 类完结网络恳求处理
Cocos2d-js 网络恳求用的是 cc.loader.getXMLHttpRequest() ,此类首要是封装post 和get办法和事务清晰的一些状态码以及加密解密数据的逻辑
代码如下
- 恳求参数处理
- 设置参数相关编码和预处理等
- 真正的恳求逻辑
- 错误超时的处理
游戏部分功用模块
游戏模块运用 layer scene 和script 来分层
Layer 首要做ui的布局和交互逻辑
Scene 来做场景的切换和游戏逻辑处理 每个场景都会用一个layer来处理中心逻辑
Script 便是对一些自定义精灵 的封装
场景的切换一致封装了route
游戏列表页面
列表页面运用的是ccui.ScrollView 完结的
游戏写字模块
1.概括制作
首先运用了一个开源的笔画数据,这个数据是每个文字的每一笔画的点,中心制作笔画概括的部分代码
//制作概括
makePath: function (strokeStr) {
let strokeCommands = strokeStr.split(" ");
let offset = GC.h - this._Offset_y * this.getStrokeYRatio();
let lastPos = cc.p;
let outlineColor = cc.color(221, 113, 60);
let counter = 0;
while (counter < strokeCommands.length) {
let commend = strokeCommands[counter];
if (commend == "M") {
let x = this.scalePointX(strokeCommands[counter + 1]);
let y = this.scalePointY(strokeCommands[counter + 2]);
this._m_drawNode.drawDot(cc.p(x, offset - y), 0, outlineColor);
lastPos = cc.p(x, offset - y);
counter += 3;
}
if (commend == "Q") {
let x1 = this.scalePointX(strokeCommands[counter + 1]);
let y1 = this.scalePointY(strokeCommands[counter + 2]);
let x2 = this.scalePointX(strokeCommands[counter + 3]);
let y2 = this.scalePointY(strokeCommands[counter + 4]);
this._m_drawNode.drawQuadBezier(lastPos, cc.p(x1, offset - y1), cc.p(x2, offset - y2), 50, 1, outlineColor);
lastPos = cc.p(x2, offset - y2);
counter += 5;
}
if (commend == "C") {
let control1x = this.scalePointX(strokeCommands[counter + 1]);
let control1y = this.scalePointY(strokeCommands[counter + 2]);
let control2x = this.scalePointX(strokeCommands[counter + 3]);
let control2y = this.scalePointY(strokeCommands[counter + 4]);
let destinationX = this.scalePointX(strokeCommands[counter + 5]);
let destinationY = this.scalePointY(strokeCommands[counter + 6]);
this._m_drawNode.drawCubicBezier(lastPos, cc.p(control1x, offset - control1y), cc.p(control2x, offset - control2y), cc.p(destinationX, offset - destinationY), 50, 1, outlineColor);
lastPos = cc.p(destinationX, offset - destinationY);
counter += 7;
}
if (commend == "L") {
let x = this.scalePointX(strokeCommands[counter + 1]);
let y = this.scalePointY(strokeCommands[counter + 2]);
this._m_drawNode.drawSegment(lastPos, cc.p(x, offset - y), 1, outlineColor);
lastPos = cc.p(x, offset - y);
counter += 3;
}
if (commend == "Z") {
break;
}
}
},
2.画笔处理
经过自定义一个精灵元素,完结拖拽逻辑进行笔画制作
onTouchBegan : function (touch, event) {
this. _enableTouch = true;
var target = event.getCurrentTarget();
if (false == target._enableMoved){
return;
}
if (!target.isTouchInRect(touch)){
return false
}
target._callback();
return true;
},
onTouchMoved : function (touch, event) {
var pos = touch.getLocation();
var target = event.getCurrentTarget();
var delta = touch.getDelta();
var point = target.parent.convertToNodeSpace(cc.p(target.x,target.y));
target.setPosition(cc.p(target.x+delta.x,target.y+delta.y));
target._callback();
},
在layer层经过移动的坐标点和 之前制作出来目标点的方位进行磕碰检测cc.rectContainsPoint,假如制作出的目标点终究一个被吃掉视为完结写字。
游戏场景模块
首要有打地鼠,推箱子,朗诵,连线等10几种小游戏。
1.游戏音频播映
短音频
//播映
this.audioId =audio.playEffect(res);
audio.setEffectsVolume(1);
//停止
cc.audioEngine.stopEffect(audioID)
长音频
用的ccui.VideoPlayer()
有些场景cocos的播映器不太好用,就经过原生封装了一个播映器,经过jsb调用完结,这儿iOS 是单独用的iOS avplayer播映器,安卓用的cocos体系的,其实体系底层也是用的原生播映器。
原生模块
首要做语音评测 ,分享才能,登录才能 付出才能 以及一些竖屏用户学习数据展现列表页面等等。
原生游戏交互模块
1.中心调用是经过jsb.reflection完结的
2.这儿也处理了一下多办法调用原生,并且需求原生回来处理的逻辑
比如获取用户信息是异步的,会把js办法目标传递到native,终究端上处理完结回调到callbackmannager,经过传递生成的时间戳作比照找到回调
3.端上其实便是一个类办法完结
三.官方学习资料
docs.cocos.com/cocos2d-x/m…
docs.cocos.com/cocos2d-x/m…
总结:
以上为我在项目实战中的一些记录,有爱好能够自己去测验学习,希望也能对我们有一定的协助,一起也是自己对过去的一个扼要总结。