手游开发_手游开发全教程 - CSDN
  • 手游行业的爆发,让很多人对这个高流水的捞金行业趋之若鹜,其中有刚毕业的小青年,也有半路出家转行进来的,不论怎样对于手游行业来说他们都是“新人”,所以基础知识就变得尤为重要了。本文将介绍游戏的一般开发...

    手游行业的爆发,让很多人对这个高流水的捞金行业趋之若鹜,其中有刚毕业的小青年,也有半路出家转行进来的,不论怎样对于手游行业来说他们都是“新人”,所以基础知识就变得尤为重要了。本文将介绍游戏的一般开发流程,包括筹备、原型、发布和迭代。

    新手入门必读:一款手游的开发流程是怎样的?

    1.筹备阶段:筹建团队,确定项目的基本方向。

    2.原型阶段:实现一个游戏原型,发布Alpha测试版,以验证和调整预定的方向。

    3.发布阶段:发布游戏的Beta测试版本,供内部封闭测试,做上线前最后的准备。

    4.迭代阶段:完成对Beta测试版的修改,上线后按迭代周期,持续开发和调优产品。

    在这些阶段中,我们都必须注意开发流程中的一些重要因数:

    角色:定义一些角色,规定其工作权力和责任,避免过度讨论或盲进

    交付物件标准:每个角色都必须按照一定标准来交付工作成果,避免在长长的工作链条中出现很多误差。

    工作方法细节:由于游戏开发是一个涉及多个专业的复杂过程,所以这个过程中有一些工作方法,是必须要遵守的,否则将会严重降低开发效率。

    作为一个完整的游戏开发团队(不包含运营团队),整体的结构应该大致如下:

    新手入门必读:一款手游的开发流程是怎样的?

    筹备阶段

    角色定义

    投资人:根据市场状况和投资预期,提出商业目标和项目邀约,和制作人讨论并审核确定《产品方向》,制作《投资计划》,按计划安排资金投放,并承担投资后果。

    制作人:根据投资人的商业目标,整理和组织市场调查数据和《竞品资料》,制订《产品方向》。根据《投资计划》组建核心团队。在某些项目里,投资人和制作人是同一个人。

    核心团队:一般由制作人和主程,主策,主美组成,有些时候还包括项目经理。在某项项目里,制作人可能由核心团队里的任何一个人兼任。

    项目经理:负责制订工作计划,监督进度,安排各种资源。初期可能会有很多秘书工作需要担任。在某些项目里,项目经理可能由核心团队中任何一个人兼任。

    交付物件

    《投资计划》:由时间、金额、项目进度检查标准,这三列组成的一个表格。需要附带上修改日志和完成记录。

    《产品方向》:一个具体的文档,记录了产品概念所依据的市场状况(数据)、竞品的情况(数据);也记录了项目产品的基本情况:游戏的题材、游戏的玩法、游戏收费方法的基本概念,以及市场推广、运营的基本思路。

    《竞品资料》:罗列所有主要的竞争对手产品的情况,包括产品市场数据,开发方案(如能搜集到),评测资料,用户反馈等。需要由制作人持续更新关注,随时整理添加。

    重点注意

    产品概念讨论方法

    针对用户特性:游戏产品形态非常丰富,细节也很多,所以在讨论任何设计的时候,都必须按照既定的用户画像来做标准判断,避免大而全或者钻牛角尖。在各种“调查报告”无效的情况下,邀请几个目标用户作直接沟通,往往能获得最真实、最有效的情报,不用过于担心“代表性”不够,因为共性往往是比较明确的部分。

    针对竞品:在用户、市场情报不够充分的时候,竞争对手能提供最直接的产品信息。通过分析竞争对手的产品,特别是跟踪竞争产品的变化,就能猜出用户和市场的反馈。就算本产品的竞争对手不多,方向相似度不高,只要是目标用户群体接近,也可以通过竞争产品的用户感受来了解用户心理。切记闭门造车,不接触市场风潮。

    不应该深入的部分:在筹备阶段,容易陷入头脑风暴,所以我们不应该深入讨论产品的开发过程、开发工具、开发人员。对于产品的细节,也不宜过细,但应该找出一些简单明确的概念来代替,如“经过XX修改的竞品A”这样就很好。

    团队缺人对策

    招聘渠道:首选熟人朋友圈,其次毕业生和培训机构,最后是网上投递简历。由于现在的培训机构一般都需要签就业协议,所以对于创业团队,小型公司来说可以作为一个比较稳定的人员来源。大型公司最好就是各种高校的招聘会了。猎头也可以考虑,但是对候选人需要仔细甄别。

    选择简单的工作方法:缺人的情况下,往往是缺牛人。所以一定要选择简单的工作方法,各种高大上的流程,一定要在有IT技术保障下实施,不要直接推行而不顾实际情况,这些可能有问题的方法包括:定期汇报制度、全自动化项目管理、没有足够储备的技术开发方案等等。

    培训准备:根据初期可能到职的人员,进行基础能力的培训,比如SVN的使用,BUG跟踪系统的使用,基础的开发技术、美术、策划文档标准。这些培训都是需要多次进行,所以应该先准备好培训资料,避免新成员入职措手不及。时间控制

    会议:筹备阶段大概有一半的时间是在做沟通,因此会议时间需要特别控制。要严格遵守议题议程。如果有遗留问题,应该有专人搜集整理并且跟进,而不是在会上去解决。因为会上提的方案,往往没有自己在认真思考的环境更完善。另外就是避免“挨个报告”那种没有明确议题的会议。这种沟通了解放到其他时间,少部分人沟通会更清楚。

    招聘期限:根据经验,核心团队具备的情况下,要组建到项目正式启动的团队,基本需要3个月左右。假如接近3个月都没有什么进展,应该和投资人反映,并研究解决方法。一般最简单的就是提高工资和雇佣猎头。

    原型(Alpha)阶段

    角色定义

    主策:提出产品原型的概念,交付《项目总体设计》,并协助原型开发,突出产品特点。

    主程:选择技术方案,定义美术、策划资源的技术标准。搭建开发环境,编写产品原型。在客户端开发方面,和美术同事合作,调整原型效果以达到测试的目的。

    主美:选择美术风格,在策划和技术的共同讨论下,确定各美术组件的基本技术标准,如大小、尺寸、容量。并且确定美术资源的格式。

    项目经理:有些团队由制作人、或者主策兼任。此阶段在明确游戏原型后,产品、技术、美术人员都会需要各自开发一些内容,然后再整合到一起。因此项目经理应该负责组织大家共享这些信息,一起讨论和评审各阶段产品,确保各环节不脱节。

    交付物件

    《项目总体设计》:规定了游戏的题材、玩法、收费模式。确定游戏的重点乐趣和表现特点。列出游戏的长期开发计划所需要的系统、关卡、内容纲要。作为后续策划工作的总需求列表。

    《美术风格指导》:以实例原画图来规定整体美术风格。

    《美术资源格式标准》:对游戏原型的美术资源格式,做出标准规定,包括美术文件的格式、尺寸、精度标准、命名、SVN路径规则等。

    开发环境:SVN服务器地址、BUG跟踪系统地址、IDE选择产品和版本、开发和测试的内网服务器、演示用外网服务器。

    《技术方案选型方案》:开发游戏所用的客户端和服务器端引擎、框架版本;程序的基本模块代码结构;项目文件目录规范;测试和CI方案;技术难点的预设解决方案。

    可运行的原型产品(DEMO):突出表现游戏核心玩法和美术风格的一个程序,可以是一个单独的游戏关卡。

    重点注意

    原型开发阶段,主要目的是验证产品的基本面问题:题材和玩法的融合是否合适,美术风格和技术实现是否能达到策划的初始目标,有没有一些难以解决的基本障碍。需要特别注意的,开发原型所需要耗费的资源制作和逻辑编写时间,因为这反应了后期游戏持续更新所需要消耗的成本。

    另外,由于游戏原型的制作,也带出了个制作环节的沟通问题,所以必须注意从一开始就积累和订立各工序的交付标准,如策划案应该包含图量表、测试方案;需要预先沟通美术草图并签名;美术资源格式需要确定;游戏原型的测试环境设置。——这些标准和接口往往会变动,但是需要预先明确这些接口流程。

    发布(Beta)阶段

    角色定义

    技术开发团队:

    客户端开发:开发和优化客户端代码和单元测试用例、文档,完善客户端程序打包、发布的CI流程

    服务器端开发:开发服务器端代码和单元测试用例、文档,维护项目数据库,安装部署测试环境

    测试开发:维护和管理CI系统,监督运行单元测试用例,开发专项测试如性能测试、自动化冒烟测试。

    交付物件

    新手入门必读:一款手游的开发流程是怎样的?

    《策划需求文档》:重点说明要达到的产品目标,使用的主要设计手段

    《策划案》:产品使用流程图,GUI草图,须配置的游戏数据项目,美术图量表以及风格参考

    《草图》:美术风格参考,UI构图

    《技术设计方案》:代码模块命名以及职责,代码结构模式及关系,重点技术问题解决方法

    《美术资源格式》:文件名和路径规则、文件格式、精度、尺寸或其他更细节内容

    《游戏数据格式》:库名、表名、字段解析、字段内容结构

    《Bug报告单》:策划案ID、重现步骤、现象

    重点注意

    此阶段是建立稳定完整的版本开发流程最重要的阶段。关键点是各交付件标准的严格遵守和流程监控。项目经理须组织对于流程、标准的讨论和确定,并且监督这些规定的执行。由于每个游戏都不一样,所以这些流程和标准都会有所差异,项目经理要随时应对不同的策划案,即时组织大家建立流程标准。另外需要准备发布的工作,包括宣传资料,测试环境,运维工具等工作,也需要花时间准备。——在发布前至少安排一周时间来做发布前的准备,和运营、运维、客服人员做好沟通和交接准备。

    迭代阶段

    角色定义

    1)开发团队:依照迭代标准开发迭代所需内容。

    2)运维团队:

    运营人员:负责推广、发行工作,提供技术资料给运维人员做产品部署,关注产品数据和运营情况。反馈意见给开发团队。

    客服人员:辅助游戏推广,提供玩家咨询、故障报告、投诉处理、事故安抚等工作,需要运营人员和开发团队进行持续的信息共享。

    运维人员:提供游戏的部署和监控工作,开发管理运维部署工具。准备硬件资源和运行环境。有些运维工作由开发团队中的服务器端程序员一起分担。

    运营开发人员:开发“GM系统”给客服人员使用;开发“数据统计报表”和“活动系统”、“官网”等系统给运营人员使用;某些游戏团队由服务器端程序员兼任。

    交付物件

    《版本发布计划》:每个版本开始开发前,都需要编写此计划,列明本版本内需要开发的内容,预计时间,以及开发设计人员名单。此计划需要提交给运营人员,提早准备《运营计划》中的推广活动和安排推广资源。

    《版本发布说明》:每个版本进入内测后,由开发团队编写后,提供给运营人员,包含本版本的所有在产品上的变更细节。以及这些版本内容的开发成员。供运营人员培训客服掌握,以及运营人员自己做测试,用以作为《运营计划》的材料。

    《运营计划》:根据每个版本,运营人员提交此文档,包括运营活动内容和所需的推广资源和资金支持。以及需要包括此次运营预计要达到的商业效果和衡量手段。

    《产品部署、升级方案》:由开发人员提供给运维人员的技术部署方案。包括如何部署安装进程,设置CDN或DNS,运行SQL或者修改配置文件。某些团队会开发自己的产品部署工具,如Chef这类软件,用以自动化处理运维工作。

    《产品统计需求》:由运营人员提交给运营开发人员,定义统计报表的格式和统计周期,描述每个表头的含义。运营开发人员根据此需求文档,开发统计程序,自动定期反馈数据报表给运营人员。

    重点注意

    一般游戏的持续更新,需要遵循一个版本列车的设定:

    新手入门必读:一款手游的开发流程是怎样的?

    由于开发的内容有长有短,所以开发过程中的代码必定要维护多套版本分支,这需要在SVN上做严格的定义:

    新手入门必读:一款手游的开发流程是怎样的?

    展开全文
  • 手游开发环境搭建

    2018-09-04 16:51:31
    一. 下载安装jdk,并设置好环境变量 http://www.oracle.com/technetwork/java/javase/downloads/index.html   二. 下载安装Intellij Idea,注意选择 Ultimate Edition idea终极版  ...   三....

    一. 下载安装jdk,并设置好环境变量

    http://www.oracle.com/technetwork/java/javase/downloads/index.html

     

    二. 下载安装Intellij Idea,注意选择 Ultimate Edition idea终极版 

    http://www.jetbrains.com/idea/download/

     

    三. 下载安装CocosEditor插件

    http://plugins.jetbrains.com/plugin/7433?pr=idea

    把下载的插件解压到idea13的plugins目录下,如: C:\Program Files\JetBrains\IntelliJ IDEA 13.1.3\plugins

    此插件不支持windowsXP系统(错误信息: CreateProcess error=193, %1 ??????Ч?? Win32 ??ó),但可以编译
    调试执行需要安装 window7/window8系统

    四. 创建cocos2d-js工程,注意第一次配置不要先创建cocos2d-android
    1. 点击 create new project ,进入创建工程界面,如果我们发现了Cocos2dx,说明我们插件安装成功;选择cocos2dx-js,给工程命名和指定位置,完成后进入主界面。
    2. 点击主界面右上角倒数第二个按钮打开Project Structure设置框,选择左边的SDKs选项,再点上方绿色的“+”号键,选择JDK,然后设置到JDK的安装目录。确认后再次点击上方绿色的“+”号键,选择I
    ntellij platform plugin sdk选项并配置好。
    3. 点击右上角倒数第六个按钮,先择EditConfiguartions...打开Run/Debug Configuartions设置框,点左上角绿色的“+”号键,
    选择Cocos2dx-JS,设置Project Name,并选择Project SDK为之前配置的JDK。
    4. 编译项目,如果弹出Project Structure设置框,确认Project Sdk选择了jdk,然后重新编译,可以看到输出目录下产生了ccbi的文件.

    五. 配置cocos2d-android项目
    1. File-->Open...-->选择Android项目,注意:不要File-import
    2. 点击主界面右上角倒数第二个按钮打开Project Structure设置框,选择左边的Android SDK选项,再点上方绿色的“+”号键,然后设置到Android SDK目录。
    3. 打开Project Structure设置框,Project Sdk设置为Android SDK
    4. 在cocos2dx-js项目中编译好场景,并把生成文件更新到android项目,即可编译出apk文件。

    展开全文
  • Cocos2d-x 3.X手游开发实例详解(最新最简Cocos2d-x手机游戏开发学习方法,以热门游戏2048、卡牌为例,完整再现手游的开发过程,实例丰富,代码完备,Cocos2d-x作者之一林顺和泰然网创始人杨雍力荐) 于浩洋 著  ...

    Cocos2d-x 3.X手游开发实例详解(最新最简Cocos2d-x手机游戏开发学习方法,以热门游戏2048、卡牌为例,完整再现手游的开发过程,实例丰富,代码完备,Cocos2d-x作者之一林顺和泰然网创始人杨雍力荐

    于浩洋 著  

    ISBN 978-7-121-23998-4

    2014年9月出版

    定价:59.00元

    356页

    16开

    编辑推荐

    以Cocos2d-x V3.0为框架全面讲解手游开发的知识和方法

    以热门游戏2048、卡牌为例,完整再现手游的开发过程

    Cocos2d-x作者之一林顺和泰然网创始人杨雍力荐

    知识点深入浅出,实例丰富,代码完备

    线上交流平台,及时答疑解惑

    内容提要

    《Cocos2d-x 3.X手游开发实例详解》以Cocos2d-xV3.0 系列版本为框架,通过实例讲解手机游戏的开发知识和方法,着重通过实例提高读者的开发动手能力。涉及的内容包括:环境搭建、交叉编译以及打包部署;Cocos2d-x数据类型和基本概念的使用,如场景、导演、精灵等;使用Cocos2d-x 创建用户界面,如文本、菜单、滚动框等基本控件,以及一些扩展控件的使用;使用Cocos2d-x 创建动作,比如让精灵移动、跳跃、旋转,以及如何创建按顺序或同时进行的动作;使用Cocos2d-x 播放、停止、暂停、继续播放背景音乐和音效;Cocos2d-x 使用的触摸事件机制;在游戏中存储数据的几种方式;使用HTTP、Sockets、WebSockets 进行网络编程;在游戏中使用物理引擎Box2D、使用瓷砖地图、使用CocosBuilder 制作游戏界面等;Cocos2d-x 中的纹理和动画。最后通过两个完整的游戏开发实例讲解使用Cocos2d-x 开发游戏的全过程。

    《Cocos2d-x 3.X手游开发实例详解》实例丰富,代码完备,知识点清晰简洁。《Cocos2d-x 3.X手游开发实例详解》所有实例均提供完整代码下载,书后附有代码清单概要,非常方便读者查找使用。此外作者还将Cocos2d-x 3.X 各版本间的区别用实例做了详细说明,且将在博客不断更新。

    《Cocos2d-x 3.X手游开发实例详解》适合对Cocos2d-x感兴趣及有志于学习和从事移动平台游戏开发的读者阅读参考。

    目录

    第1章  准备     1

    1.1  Cocos2d-x简介     1

    1.2  Cocos2d-x架构和目录结构     6

    1.3  环境搭建     7

    1.3.1  Windows开发环境搭建     7

    1.3.2  Mac开发环境搭建     11

    1.3.3  创建新项目     12

    1.3.4  在Android上调试项目     14

    1.3.5  打包APK文件     22

    第2章  Cocos2d-x常用数据和方法     23

    2.1  C++数据类型     23

    2.2  Cocos2d-x封装的数据类型     24

    2.2.1  布尔型Bool的使用     24

    2.2.2  整型Integer的使用     25

    2.2.3  浮点型Double、Float的使用     25

    2.2.4  字符串String的使用     25

    2.2.5  数组Array的使用     26

    2.2.6  点Point的使用     27

    2.2.7  尺寸Size的使用     28

    2.2.8  矩形Rect的使用     29

    2.2.9  字典Dictionary的使用     31

    2.3  常用宏定义     32

    2.3.1  数学相关宏的使用     32

    2.3.2  断言宏CCAsset的使用     33

    2.3.3  数组遍历宏CCARRAY_FOREACH和CCARRAY_FOREACH_REVERSE的使用     33

    2.3.4  字典遍历宏CCDICT_FOREACH的使用     35

    2.3.5  对象创建方法宏CREATE_FUNC的使用     36

    2.3.6  属性定义宏CC_PROPERTY的使用     37

    2.3.7  命名空间宏     39

    2.4  Cocos2d-x中的坐标和坐标系     39

    2.4.1  OpenGL坐标系和屏幕坐标系     39

    2.4.2  锚点和位置的使用     40

    2.4.3  节点坐标系和世界坐标系的相互转换     42

    第3章  Cocos2d-x核心概念     45

    3.1  基础节点     46

    3.1.1  Node简介     46

    3.1.2  Node应用举例之移除节点     47

    3.2  相机     47

    3.2.1  相机简介     47

    3.2.2  使用CCCamera循环缩放点     48

    3.3  导演     49

    3.3.1  导演Director简介     49

    3.3.2  Director常用功能举例     50

    3.4  场景     51

    3.4.1  场景定义     51

    3.4.2  创建显示战斗场景     52

    3.4.3  动态切换多个场景     53

    3.5  布景     56

    3.5.1  布景定义     56

    3.5.2  使用Layer模拟Windows Phone主界面     57

    3.6  精灵     59

    第4章  Cocos2d-x用户界面     61

    4.1  文本渲染     61

    4.1.1  制作fnt格式字体     62

    4.1.2  使用LabelBMFont显示文本     66

    4.1.3  使用LabelTTF显示文本     67

    4.1.4  使用LabelAtlas显示文本     70

    4.2  菜单     71

    4.2.1  菜单和菜单项的简单使用     72

    4.2.2  使用菜单制作游戏菜单功能     74

    4.3  滚动框     80

    4.3.1  使用ScrollView显示多页内容     80

    4.3.2  监听ScrollView的滚动和缩放事件     82

    4.3.3  使用TableView展示多页内容     83

    4.3.4  触摸TableView里的菜单来滚动TableView   86

    4.4  扩展控件     87

    4.4.1  滑动条控件ControlSlider  87

    4.4.2  开关控件ControlSwitch  90

    4.4.3  取色器控件ControlColourPicker  92

    4.4.4  电位计控件ControlPotentiometer  94

    4.4.5  步进器控件ControlStepper  95

    4.4.6  按钮控件ControlButton  96

    4.4.7  Scale9Sprite  99

    4.5  使用编辑框制作用户登录界面     100

    第5章  Cocos2d-x动作     105

    5.1  动作分类     105

    5.2  瞬时动作     106

    5.2.1  使用FlipX/FlipY实现X/Y翻转     106

    5.2.2  使用Hide、Show实现隐藏和显示     108

    5.3  延时动作     109

    5.3.1  使用MoveTo或者MoveBy实现移动     109

    5.3.2  使用RotateTo和RotateBy实现旋转     110

    5.3.3  使用JumpTo和JumpBy实现跳跃     113

    5.3.4  使用ScaleTo和ScaleBy实现缩放     114

    5.3.5  使用SkewTo和SkewBy实现倾斜变形     115

    5.3.6  使用CardinalSplineBy和CardinalSplineTo实现曲线运动     117

    5.3.7  使用FadeIn和FadeOut实现渐隐渐出     119

    5.4  联合动作     120

    5.4.1  按先后顺序执行动作     120

    5.4.2  同时执行动作     121

    5.4.3  逆向执行动作     122

    5.4.4  多次重复执行动作     123

    5.4.5  延时执行动作     124

    第6章  音频处理     125

    6.1  音频处理类SimpleAudioEngine  125

    6.2  添加控制背景音乐     126

    6.2.1  播放背景音乐并调整音量     126

    6.2.2  停止播放背景音乐     128

    6.2.3  暂停播放背景音乐     128

    6.2.4  继续播放背景音乐     128

    6.3  添加控制音乐效果     129

    6.3.1  播放音乐     129

    6.3.2  停止播放音乐     131

    6.3.3  暂停播放音乐     131

    6.3.4  继续播放音乐     131

    6.3.5  停止、暂停、继续播放所有音乐     132

    6.4  Cocos2d-x支持的音频格式     133

    第7章  Cocos2d-x瓷砖地图     135

    7.1  什么是瓷砖地图     135

    7.2  使用Tiled制作瓷砖地图     137

    7.2.1  安装Tiled  137

    7.2.2  制作地图     138

    7.3  在游戏中使用瓷砖地图     140

    7.3.1  使用TMXTiledMap把瓷砖地图加载到游戏中     140

    7.3.2  拖曳TMX地图     141

    7.3.3  在TMX地图中添加并移动精灵     142

    7.3.4  读写TMX地图中的图层和瓷砖     143

    第8章  Cocos2d-x中的事件机制     146

    8.1  事件和事件调度     147

    8.2  触摸事件     149

    8.2.1  单点触摸事件的类和方法     149

    8.2.2  单击屏幕移动精灵     150

    8.2.3  拖动精灵移动     152

    8.2.4  修改监听器的优先级     154

    8.2.5  多点触摸事件     156

    8.2.6  使用多点触摸实现缩放     157

    8.3  鼠标事件     159

    8.4  键盘事件     159

    8.4.1  键盘事件介绍     159

    8.4.2  实例:把键盘输入内容显示在屏幕中     160

    8.5  加速计     161

    8.5.1  加速计介绍     161

    8.5.2  实例:利用加速计控制小球移动     162

    第9章  Cocos2d-x本地数据存储     165

    9.1  使用UserDefault存储数据     165

    9.1.1  UserDefault介绍     165

    9.1.2  使用UserDefault存储修改数据     167

    9.2  文件     169

    9.2.1  文件处理类FileUtils  169

    9.2.2  判断文件是否存在     169

    9.2.3  设置文件别名     170

    9.2.4  获取文件完整路径     172

    9.2.5  设置文件搜索路径     174

    9.2.6  根据分辨率调用不同的资源     175

    9.2.7  向文件中写入数据     176

    9.2.8  从文件中读取数据     179

    9.2.9  把数据写入plist文件     180

    9.2.10  从plist文件读取数据     182

    9.3  SQLite存储     183

    9.3.1  SQLite简介     183

    9.3.2  可视化管理工具SQLiteStudio  185

    9.3.3  使用SQLiteStudio添加数据库     186

    9.3.4  使用SQLiteStudio添加表和数据     188

    9.3.5  使用C语言接口操作SQLite数据库     190

    9.3.6  不使用回调查询SQLite数据库     194

    第10章  网络编程     197

    10.1  HTTP实现网络通信     198

    10.1.1  HTTP通信简介及常用类     198

    10.1.2  GET方式通信     200

    10.1.3  POST方式通信     203

    10.2  Socket实现网络通信     204

    10.2.1  Socket简介     204

    10.2.2  在Cocos2d-x中使用Socket  205

    10.3  WebSocket实现网络通信     209

    10.3.1  WebSocket简介     209

    10.3.2  在Cocos2d-x中使用WebSocket  210

    第11章  物理引擎Box2D   215

    11.1  Box2D简介     216

    11.2  创建Box2D的HelloWorld项目     217

    11.2.1  创建一个世界     217

    11.2.2  创建一个地面物体     217

    11.2.3  创建一个动态物体     219

    11.2.4  模拟(Box2D的)世界     219

    11.2.5  清理工作     221

    11.3  世界b2World  221

    11.3.1  b2World简介     221

    11.3.2  世界常用功能     222

    11.4  物体b2Body  225

    11.4.1  b2Body简介     225

    11.4.2  物体定义     226

    11.4.3  创建物体     228

    11.4.4  使用物体     229

    11.5  固定装置b2FixtureDef 231

    11.5.1  b2FixtureDef简介     231

    11.5.2  创建b2FixtureDef 231

    11.6  关节     234

    11.6.1  关节简介     234

    11.6.2  关节定义     235

    11.6.3  创建关节     235

    11.6.4  关节类型和使用关节     236

    11.7  接触     242

    11.7.1  接触简介     242

    11.7.2  接触监听器     243

    11.7.3  接触筛选     244

    第12章  纹理和动画     246

    12.1  渲染和修改纹理     246

    12.1.1  纹理类Texture2D   247

    12.1.2  Cocos2d-x支持的纹理格式     249

    12.1.3  Cocos2d-x支持的最大纹理尺寸     249

    12.1.4  使用RenderTexture保存截屏     250

    12.1.5  图片抗锯齿处理方式     251

    12.1.6  使用图片缓存     253

    12.1.7  制作游戏加载场景     254

    12.1.8  使用TexturePacker制作Sprite Sheet  256

    12.2  动画     258

    12.2.1  帧动画     258

    12.2.2  使用帧动画实现英雄打斗     259

    12.2.3  Sprite Sheet动画     266

    12.2.4  骨骼动画     268

    12.2.5  使用CocoStudio制作骨骼动画     269

    12.2.6  在项目中调用CocoStudio制作的骨骼动画     273

    第13章  使用Cocos2d-x制作2048休闲游戏     275

    13.1  准备工作     275

    13.2  使用CocoStudio制作UI界面     276

    13.3  编写逻辑代码     279

    13.3.1  把UI界面添加到游戏界面中     279

    13.3.2  添加获取分数控件并设置分数     281

    13.3.3  添加数字方块类     281

    13.3.4  初始化游戏数据     282

    13.3.5  添加按钮功能     284

    13.3.6  添加事件监听     285

    13.3.7  实现方块上下左右移动     287

    13.3.8  添加新的数字块     290

    13.3.9  判断游戏是否结束     291

    13.3.10  添加游戏介绍界面     293

    第14章  使用Cocos2d-x制作水浒卡牌游戏     294

    14.1  准备工作     294

    14.2  定义游戏数据结构和存储单例     295

    14.3  添加登录界面     299

    14.4  添加游戏主场景     305

    14.5  添加游戏首页     307

    14.6  添加英雄卡牌列表界面     311

    14.7  添加战斗流程     314

    14.8  添加战斗界面     319

    14.9  终结     323

    附录A  实例代码清单说明     324

    附录B  Cocos2d-x 3.X主要版本间的区别     328

    精彩节摘

    14.7  添加战斗流程

    战斗是卡牌游戏的灵魂,有了喜欢的英雄,给英雄装备一套好的装备,这时不拿出来用用多没意思啊!战斗让你的英雄久经沙场,变得更强更伟大。该游戏中的战斗流程是,单击战争菜单,首先进入世界地图,如图14-5所示,单击世界地图上的某个势力范围,进入该势力范围的推图,再单击其中一个推图进入战斗场景。

    世界地图通过GameMapLayer实现。在GameMapLayer初始化中,添加一个ScrollView,用来滚动显示隐藏的地图:

    ui::ScrollView* dragPanel = ui::ScrollView::create();

    设置dragPanel的大小为窗口大小:

    Size widgetSize =Director::getInstance()->getWinSize();

    dragPanel->setSize(widgetSize);

    设置dragPanel的内容大小为640×1920:

     Size backgroundSize =Size(640,1920);

    dragPanel->setInnerContainerSize(backgroundSize);

    设置位置添加到场景中:

    dragPanel->setPosition(ccp((widgetSize.width -backgroundSize.width) / 2, (widgetSize.height - backgroundSize.height) / 2 +
    (backgroundSize.height - dragPanel->getContentSize().height) / 2));

     

    m_pLayer->addChild(dragPanel);

    世界地图是用CocosStudio制作的UI,这里省略详细的制作过程,因为上一个实例已经详细讲解了CocosStudio怎制作UI。我们把UI添加到dragPanel中:

    Layout* map_root =dynamic_cast<Layout*>(GUIReader::shareReader()->widgetFromJsonFile("GameMapLayer_1.json"));

    dragPanel->addChild(map_root);

    然后定义一个数组,代表势力范围的名称:

    string str[21] ={"yananfu","shijiachun","shimiao","yezhulin","changzhou","hunxian","erlongsan","qingzhou","jiangzhou","liangsan","zhujiazhuang","beijing","chengtou","dongpingfu","dongjing","liangsan","jizhou","shuzhou","hangzhou","guanfu"};

    通过一个for循环遍历UI地图中的Button,并为Button添加名称和回调函数:

    for (unsigned int i = 0; i<20; ++i)

        {

            Button* button =(Button*)(map_root->getChildByTag(i));

    button->setTitleFontSize(32);

    button->setTitleColor(Color3B(255,0,0));

    button->setTitleText(str[i].c_str());

    button->addTouchEventListener(this,toucheventselector(GameMapLayer::buttonTouchEvent));

    }

    在回调函数buttonTouchEvent中,先获取单击Button的tag和现在的等级:

    voidGameMapLayer::buttonTouchEvent(Ref *pSender, TouchEventTypetype)

    {

        Size winSize=Director::getInstance()->getWinSize();

        Sprite*bg=Sprite::create("tipbg.png");

        Button*pHome=(Button*)pSender;

    int tag=pHome->getTag();

    int level=GameData::shareGameData()->mlevel;

    switch (type)

        {

    case TOUCH_EVENT_BEGAN:

    break;

     

    case TOUCH_EVENT_MOVED:

    break;

     

    case TOUCH_EVENT_ENDED:

                ....进行操作....

    break;

    case TOUCH_EVENT_CANCELED:

    break;

     

    default:

    break;

        }

    }

    然后在TOUCH_EVENT_ENDED中判断等级是否大于等于tag*5-10,如果是就进入推图场景:

    if(level>=tag*5-10)

               {

    FightLayer *info=new FightLayer(tag);

    addChild(info);

                }

    这时,运行程序,单击世界地图中最上面的势力,进入推图场景,如图14-6所示。

    作者简介

    于浩洋:曾就职于阿里巴巴、人人网,从事多年互联网产品开发工作。守望科技工作室创始人,我博轻游科技有限责任公司CTO,参与主导多款卡牌手游的开发与发行,有丰富的手游开发经验。

    媒体评论

    手游是个很有前景的行业,同时也是个竞争异常激烈的行业。为了在竞争中立于不败之地,必须有可靠先进的技术和技术人才。此书以Cocos2d-x 3.0为基础,从入门知识到高级进阶,详细讲解了手游开发的十几个大模块,每个大模块又包含了许多小的知识点,是提高技术水平不可多得的一本书。

    林顺

    触控科技高级技术总监,Cocos2d-js作者

    本书是由从业多年的开发者于浩洋所著,多年的互联网巨头从业经验使得作者形成了比较扎实的知识体系。书中对基础知识娓娓道来,同时全书包括多个实例讲解。大量的实例,让所有知识深入浅出,不论你是有从业经验的中级开发者还是初次使用Cocos2d-x的小白用户,本书都是不错的选择。

    杨雍

    泰然网创始人,Cocos2d-x技术推广总监

    前言

    记得第一次接触移动互联网是在2008年左右,当时互联网应用相当普及,市场竞争进入红海,绝大多数人认为移动互联将成为下一个增长点,是很大的蓝海,社会将进入3G时代。大到三大运营商和一线互联网公司,小到小公司和个人开发者都想进入移动互联,从3G大蛋糕中分到一块利益。转眼几年过去,正如当时预料的那样,移动互联已经深入人们的生活当中,4G也悄悄来临。在移动互联的发展过程中,苹果公司起到了不可磨灭的作用,因为它发布了能承载移动互联功能的新概念智能手机iPhone。于是乎,诞生了一大批移动应用和移动游戏的开发商和个人开发者。其中以《疯狂的小鸟》为代表的第一批手机游戏进入人们的视线并大获成功,之后手机游戏以比雨后春笋还疯狂很多倍的速度成长起来。各种类型的游戏出现在市场中,例如《我叫MT》《大掌门》《找你妹》及腾讯的天天游戏系列。

    在手机游戏快速成长的过程中,手机游戏开发框架也跟着发展起来,其中最著名的就是Cocos2d家族,Cocos2d-iphone、Cocos2d-js、Cocos2d-java等,其中Cocos2d-iphone使用数最多。但是Cocos2d-iphone是用Objective-C开发的,只能用于开发iPhone平台的游戏,如果想发布到Android平台,就要使用另外一种语言,几乎重写所有代码。于是,中国有位叫王哲的“大神”,使用C++重新实现了一遍Cocos2d-iphone的API,使用C++开发的游戏不仅效率高,也能发布到iOS、Android、in、Linux等多个平台,真正实现了编写一次、多平台运行的目的。

    Cocos2d-x 3.0系列统一修改了类和接口(比如把类前面的CC去掉),使代码更规范、更美观。3.0系列重写了纹理渲染方式,不再会产生成倍消耗内存的情况,使游戏运行效率更高、更稳定。本书以Cocos2d-x 3.0版本为基础,记录整理了笔者在学习和使用Cocos2d-x中遇到的问题和常用功能,以实践为主,着重提高读者的动手开发能力,让读者从入门手游的菜鸟成为游戏开发界的大神。

    本书的主要内容如下。

    第1章介绍Cocos2d-x的优缺点和目录结构,本书案例需要的环境搭建、交叉编译以及打包部署。

    第2章讲解了Cocos2d-x中常用的数据类型和方法及一些宏定义。

    第3章讲解了Cocos2d-x的基本概念,即基础节点Node、相机、导演、场景、布景、精灵。

    接着由浅入深,第4章讲解了如何使用Cocos2d-x创建用户界面,如文本、菜单、滚动框等基本控件,以及一些扩展控件,如取色器、计步器、复选框等。

    之后笔者用很多篇幅在第5章讲解了使用Cocos2d-x创建动作的方式,因为动作在游戏中是必不可少的重中之重,内容包括移动、跳跃、旋转等简单动作,以及按顺序执行或同时执行的复杂动作。

    音乐在游戏中也不可或缺,好的音效给人耳目一新的感觉,本书第6章讲解了使用Cocos2d-x播放、停止、暂停、继续播放背景音乐和音效。

    第7章介绍了瓷砖地图相关的内容,包括瓷砖地图的概念、如何制作瓷砖地图,如何在游戏中使用、操作瓷砖地图等。

    第8章讲解了Cocos2d-x中的事件机制,包括触摸事件、鼠标事件、键盘事件,以触摸事件为主要内容。智能手机大多数都是触摸屏,要监听用户的触摸行为,然后调用相应的行为动作,Cocos2d-x提供了一套触摸事件机制,并且3.0系统重写了该机制,使监听用户触摸行为更加方便快捷,同时Cocos2d-x还支持多点触摸机制,增加玩家与手机的交互乐趣。

    除此之外,进行游戏时还产生很多数据,这些数据有时需要保存下来以便下次使用,所以第9章介绍了多种保存数据的方式,比如UsderDefault、Plist、本地数据库SQLite等。

    当开发网络游戏时,客户端要不断地跟服务端进行数据交换,第10章讲解了如何使用HTTP、Sockets、WebSockets进行网络编程。

    第11章介绍了物理引擎,它可以使游戏更加接近现实世界,给玩家更真实的体验。

    第12章讲解了纹理和动画,介绍了纹理的渲染方式并提供了几个提高渲染效率的方法。动画部分讲解了如何在游戏中播放帧动画、plist动画和骨骼动画。书中还穿插介绍了一些工具的使用方法,比如使用bitmap font generator制作自定义字体,使用TiledMap Editor制作编辑瓷砖地图,使用SQLiteStudio管理SQLite数据库,使用CocoStudio制作编辑UI、动画、场景等。

    第13章讲解了休闲游戏2048的完整开发过程,核心内容包括使用CocoStudio制作UI界面,UI界面与逻辑代码的交互,使用UserDefault存取游戏数据,数字方块移动、合并的逻辑等。

    第14章讲解了水浒卡牌游戏的完整开发过程,挑选了其中几个典型的功能进行了详细讲解,包括登录界面、公共菜单、游戏首页、英雄列表、地图、推图和战斗界面等。本章内容对于游戏开发人员具有很高的参考价值。

    本书所有实例代码在附录A中有详细说明,读者可到博文视点网站下载,地址:www.broadview.com.cn/23998。

    附录B详细介绍了Cocos2d-x 3.X主要版本间的区别,用实例详细说明各个功能点的使用方法。

    最后衷心感谢读者的支持,如果有问题或想法可以到博客上留言交流,我的博客是http://blog.watchtech.net。

     

    于浩洋


    展开全文
  • Unity3D手游开发实践

    2018-04-29 10:58:53
    这是一个问题、资源管理、性能优化、异常与Crash、适配与兼容、调试及开发工具、项目运营。1.架构设计好的架构利用大规模项目的多人团队开发和代码管理,也利用查找错误和后期维护。框架的选择:需要根据团队...

    本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身。虽然基于Unity3D,很多东西同样适用于Cocos。本文从以下10大点进行阐述:架构设计、原生插件/平台交互、版本与补丁、用脚本,还是不用?这是一个问题、资源管理、性能优化、异常与Crash、适配与兼容、调试及开发工具、项目运营。


    1.架构设计

    好的架构利用大规模项目的多人团队开发和代码管理,也利用查找错误和后期维护。

    • 框架的选择:需要根据团队、项目来进行选择,没有最好的框架,只有最合适的框架。
    • 框架的使用:统一的框架能规范大家的行为,互相之间可以比较平滑切换,可维护性大大提升。除此之外,还能代码解耦。例如StrangeIOC是一个超轻量级和高度可扩展的控制反转(IoC)框架,专门为C#和Unity编写。已知公司内部使用StrangeIOC框架的游戏有:腾讯桌球欢乐麻将植物大战僵尸Online[https://github.com/strangeioc/strangeioc](https://github.com/strangeioc/strangeioc)

    依赖注入(Dependency Injection,简称DI),是一个重要的面向对象编程的法则来削减计算机程序的耦合问题。依赖注入还有一个名字叫做控制反转(Inversion of Control,英文缩写为IoC)。依赖注入是这样一个过程:由于某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点。在程序运行过程中,客户类不直接实例化具体服务类实例,而是客户类的运行上下文环境专门组件负责实例化服务类,然后将其注入到客户类中,保证客户类的正常运行。即对象在被创建的时候,由一个运行上下文环境或专门组件将其所依赖的服务类对象的引用传递给它。也可以说,依赖被注入到对象中。所以,控制反转是,关于一个对象如何获取他所依赖的对象的引用,这个责任的反转


    StrangeIOC采用MVCS(数据模型 Model,展示视图 View,逻辑控制 Controller,服务Service)结构,通过消息/信号进行交互和通信。整个MVCS框架跟flash的robotlegs基本一致,(忽略语言不一样)详细的参考[http://www.cnblogs.com/skynet/archive/2012/03/21/2410042.html](http://www.cnblogs.com/skynet/archive/2012/03/21/2410042.html)

    • 数据模型 Model:主要负责数据的存储和基本数据处理
    • 展示视图 View:主要负责UI界面展示和动画表现的处理
    • 逻辑控制 Controller:主要负责业务逻辑处理,
    • 服务Service:主要负责独立的网络收发请求等的一些功能。
    • 消息/信号:通过消息/信号去解耦Model、View、Controller、Service这四种模块,他们之间通过消息/信号进行交互。
    • 绑定器Binder:负责绑定消息处理、接口与实例对象、View与Mediator的对应关系。
    • MVCS Context:可以理解为MVC各个模块存在的上下文,负责MVC绑定和实例的创建工作。

    腾讯桌球客户端项目框架

    1.2代码目录的组织:一般客户端用得比较多的MVC框架,怎么划分目录?

    先按业务功能划分,再按照MVC来划分。"蛋糕心语"就是使用的这种方式。
    先按MVC划分,再按照业务功能划分。"D9"、"宝宝斗场"、"魔法花园"、"腾讯桌球"、"欢乐麻将"使用的这种方式。


    根据使用习惯,可以自行选择。个人推荐"先按业务功能划分,再按照 MVC 来划分",使得模块更聚焦(高内聚),第二种方式用多了发现随着项目的运营模块增多,没有第一种那么好维护。
    Unity项目目录的组织:结合Unity规定的一些特殊的用途的文件夹,我们建议Unity项目文件夹组织方式如下。


    其中,Plugins支持Plugins/{Platform}这样的命名规范:

    • Plugins/x86
    • Plugins/x86_64
    • Plugins/Android
    • Plugins/iOS

    如果存在Plugins/{Platform},则加载Plugins/{Platform}目录下的文件,否则加载Plugins目录下的,也就是说,如果存在{Platform}目录,Plugins根目录下的DLL是不会加载的。
    另外,资源组织采用分文件夹存储"成品资源"及"原料资源"的方式处理:防止无关资源参与打包,RawResource即原始资源,Resource即成品资源。当然并不限于RawResource这种形式,其他Unity规定的特殊文件夹都可以这样,例如Raw Standard Assets。

    1.2公司组件

    • msdk(sns、支付midas、推送灯塔、监控Bugly)
    • apollo
    • apollo voice
    • xlua

    目前我们的腾讯桌球、四国军棋都接入了apollo,但是如果服务器不采用apollo框架,不建议客户端接apollo,而是直接接msdk减少二次封装信息的丢失和带来的错误,方便以后升级维护,并且减少导入无用的代码。

    1.3第三方插件选型

    • NGUI
    • DoTween
    • GIF
    • GAF
    • VectrosityScripts
    • PoolManager
    • Mad Level Manger

    2.原生插件/平台交互

    虽然大多时候使用Unity3D进行游戏开发时,只需要使用C#进行逻辑编写。但有时候不可避免的需要使用和编写原生插件,例如一些第三方插件只提供C/C++原生插件、复用已有的C/C++模块等。有一些功能是Unity3D实现不了,必须要调用Android/iOS原生接口,比如获取手机的硬件信息(UnityEngine.SystemInfo没有提供的部分)、调用系统的原生弹窗、手机震动等等

    2.1C/C++插件

    编写和使用原生插件的几个关键点:

    • 创建C/C++原生插件
      • 导出接口必须是C ABI-compatible函数
      • 函数调用约定
    • 在C#中标识C/C++的函数并调用
      • 标识 DLL 中的函数。至少指定函数的名称和包含该函数的 DLL 的名称。
      • 创建用于容纳 DLL 函数的类。可以使用现有类,为每一非托管函数创建单独的类,或者创建包含一组相关的非托管函数的一个类。
      • 在托管代码中创建原型。使用DllImportAttribute标识 DLL 和函数。 用staticextern修饰符标记方法。
        • 调用 DLL 函数。像处理其他任何托管方法一样调用托管类上的方法。
    • 在C#中创建回调函数,C/C++调用C#回调函数
      • 创建托管回调函数。
      • 创建一个委托,并将其作为参数传递给 C/C++函数。平台调用会自动将委托转换为常见的回调格式。
      • 确保在回调函数完成其工作之前,垃圾回收器不会回收委托。

    那么C#与原生插件之间是如何实现互相调用的呢?在弄清楚这个问题之前,我们先看下C#代码(.NET上的程序)的执行的过程:(更详细一点的介绍可以参见我之前写的博客:http://www.cnblogs.com/skynet/archive/2010/05/17/1737028.html

    • 将源码编译为托管模块;
    • 将托管模块组合为程序集;
    • 加载公共语言运行时CLR;
    • 执行程序集代码。
      注:CLR(公共语言运行时,Common Language Runtime)和Java虚拟机一样也是一个运行时环境,它负责资源管理(内存分配和垃圾收集),并保证应用和底层操作系统之间必要的分离。
      为了提高平台的可靠性,以及为了达到面向事务的电子商务应用所要求的稳定性级别,CLR还要负责其他一些任务,比如监视程序的运行。按照.NET的说法,在CLR监视之下运行的程序属于"托管"(managed)代码,而不在CLR之下、直接在裸机上运行的应用或者组件属于"非托管"(unmanaged)的代码

    这几个过程我总结为下图:



    图 .NET上的程序运行

    回调函数是托管代码C#中的定义的函数,对回调函数的调用,实现从非托管C/C++代码中调用托管C#代码。那么C/C++是如何调用C#的呢?大致分为2步,可以用下图表示:


    • 将回调函数指针注册到非托管C/C++代码中(C#中回调函数指委托delegate)
    • 调用注册过的托管C#函数指针

    相比较托管调用非托管,回调函数方式稍微复杂一些。回调函数非常适合重复执行的任务、异步调用等情况下使用
    由上面的介绍可以知道CLR提供了C#程序运行的环境,与非托管代码的C/C++交互调用也由它来完成。CLR提供两种用于与非托管C/C++代码进行交互的机制:

    • 平台调用(Platform Invoke,简称PInvoke或者P/Invoke),它使托管代码能够调用从非托管DLL中导出的函数。
    • COM 互操作,它使托管代码能够通过接口与组件对象模型 (COM) 对象交互。考虑跨平台性,Unity3D不使用这种方式。

    平台调用依赖于元数据在运行时查找导出的函数并封送(Marshal)其参数。 下图显示了这一过程。


    注意:

    1. 除涉及回调函数时以外,平台调用方法调用从托管代码流向非托管代码,而绝不会以相反方向流动。 虽然平台调用的调用只能从托管代码流向非托管代码,但是数据仍然可以作为输入参数或输出参数在两个方向流动
    2. 图中DLL表示动态库,Windows平台指.dll文件、Linux/Android指.so文件、Mac OS X指.dylib/framework文件、iOS中只能使用.a。后文都使用DLL代指,并且DLL使用C/C++编写

    当"平台调用"调用非托管函数时,它将依次执行以下操作:

    • 查找包含该函数的DLL。
    • 将该DLL加载到内存中。
      查找函数在内存中的地址并将其参数推到堆栈上,以封送所需的数据(参数)。

      注意
      只在第一次调用函数时,才会查找和加载 DLL 并查找函数在内存中的地址。iOS中使用的是.a已经静态打包到最终执行文件中。

    • 将控制权转移给非托管函数。

    2.2Android插件

    Java同样提供了这样一个扩展机制JNI(Java Native Interface),能够与C/C++互相通信。

    注:

    • JNI wiki-https://en.wikipedia.org/wiki/Java_Native_Interface,这里不深入介绍JNI,有兴趣的可以自行去研究。如果你还不知道JNI也不用怕,就像Unity3D使用C/C++库一样,用起来还是比较简单的,只需要知道这个东西即可。并且Unity3D对C/C++桥接器这块做了封装,提供AndroidJNI/AndroidJNIHelper/AndroidJavaObject/AndroidJavaClass/AndroidJavaProxy方便使用等,具体使用后面在介绍。JNI提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互,保证本地代码能工作在任何Java 虚拟机环境下。"
    • 作为知识扩展,提一下Android Java虚拟机。Android的Java虚拟机有2个,最开始是Dalvik,后面Google在Android 4.4系统新增一种应用运行模式ART。ART与Dalvik 之间的主要区别是其具有提前 (AOT) 编译模式。 根据 AOT 概念,设备安装应用时,DEX 字节代码转换仅进行一次。 相比于 Dalvik,这样可实现真正的优势 ,因为 Dalvik 的即时 (JIT) 编译方法需要在每次运行应用时都进行代码转换。下文中用Java虚拟机代指Dalvik/ART。

    C#/Java都可以和C/C++通信,那么通过编写一个C/C++模块作为桥接,就使得C#与Java通信成为了可能,如下图所示:


    注:C/C++桥接器本身跟Unity3D没有直接关系,不属于Android和Unity3D,图中放在Unity3D中是为了代指libunity.so中实现的桥接器以表示真实的情况。

    通过JNI既可以用于Java代码调用C/C++代码,也可用于C/C++代码与Java(Dalvik/ART虚拟机)的交互。JNI定义了2个关键概念/结构:JavaVMJNIENVJavaVM提供虚拟机创建、销毁等操作,Java中一个进程可以创建多个虚拟机,但是Android一个进程只能有一个虚拟机JNIENV是线程相关的,对应的是JavaVM中的当前线程的JNI环境,只有附加(attach)到JavaVM的线程才有JNIENV指针,通过JNIEVN指针可以获取JNI功能,否则不能够调用JNI函数。


    C/C++要访问的Java代码,必须要能访问到Java虚拟机,获取虚拟机有2中方法:

    • 在加载动态链接库的时候,JVM会调用JNI_OnLoad(JavaVM jvm, void reserved),第一个参数会传入JavaVM指针。
    • 在C/C++中调用JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)创建JavaVM指针。

    所以,我们只需要在编写C/C++桥接器so的时候定义**JNI_OnLoad(JavaVM jvm, voidreserved)方法即可,然后把JavaVM指针保存起来作为上下文使用
    获取到JavaVM之后,还不能直接拿到JNI函数去获取Java代码,必须通过线程关联的JNIENV指针去获取。所以,作为一个好的开发习惯在每次获取一个线程的JNI相关功能时,先调用AttachCurrentThread();又或者
    每次通过JavaVM指针获取当前的JNIENV:java_vm->GetEnv((void)&jni_env, version),一定是已经附加到JavaVM的线程。通过JNIENV可以获取到Java的代码,例如你想在本地代码中访问一个对象的字段(field),你可以像下面这样做:

    • 对于类,使用jni_env->FindClass获得类对象的引用
    • 对于字段,使用jni_env->GetFieldId获得字段ID
    • 使用对应的方法(例如jni_env->GetIntField)获取字段的值

    类似地,要调用一个方法,你step1.得获得一个类对象的引用obj,step2.是方法methodID。这些ID通常是指向运行时内部数据结构。查找到它们需要些字符串比较,但一旦你实际去执行它们获得字段或者做方法调用是非常快的。step3.调用jni_env->CallVoidMethodV(obj, methodID, args)
    从上面的示例代码,我们可以看出使用原始的JNI方式去与Android(Java)插件交互是多的繁琐,要自己做太多的事情,并且为了性能需要自己考虑缓存查询到的方法ID,字段ID等等。幸运的是,Unity3D已经为我们封装好了这些,并且考虑了性能优化。Unity3D主要提供了一下2个级别的封装来帮助高效编写代码:


    注:Unity3D中对应的C/C++桥接器包含在libunity.so中。

    • Level 1:AndroidJNI、AndroidJNIHelper,原始的封装相当于我们上面自己编写的C# Wrapper。AndroidJNIHelper 和AndroidJNI自动完成了很多任务(指找到类定义,构造方法等),并且使用缓存使调用java速度更快。AndroidJavaObject和AndroidJavaClass基于AndroidJNIHelper 和AndroidJNI创建,但在处理自动完成部分也有很多自己的逻辑,这些类也有静态的版本,用来访问java类的静态成员。更详细接口参考帮助文档:http://docs.unity3d.com/ScriptReference/AndroidJNI.htmlhttp://docs.unity3d.com/ScriptReference/AndroidJNIHelper.html
    • Level 2:AndroidJavaObject、AndroidJavaClass、AndroidJavaProxy,这个3个类是基于Level1的封装提供了更高层级的封装使用起来更简单,这个在第三部分详细介绍。

    2.3iOS插件

    iOS编写插件比Android要简单很多,因为Objective-C也是 C-compatible的,完全兼容标准C语言。这些就可以非常简单的包一层 extern "c"{},用C语言封装调用iOS功能,暴露给Unity3D调用。并且可以跟原生C/C++库一样编成.a插件。C#与iOS(Objective-C)通信的原理跟C/C++完全一样:


    除此之外,Unity iOS支持插件自动集成方式。所有位于Asset/Plugings/iOS文件夹中后缀名为.m , .mm , .c , .cpp的文件都将自动并入到已生成的Xcode项目中。然而,最终编进执行文件中。后缀为.h的文件不能被包含在Xcode的项目树中,但他们将出现在目标文件系统中,从而使.m/.mm/.c/.cpp文件编译。这样编写iOS插件,除了需要对iOS Objective-C有一定了解之外,与C/C++插件没有差异,反而更简单。

    3.版本与补丁

    任何游戏(端游、手游)都应该提供游戏内更新的途径。一般游戏分为全量更新/整包更新、增量更新、资源更新。

    • 全量
      android游戏内完整安装包下载(ios跳转到AppStore下载)
    • 增量:主要指android省流量更新
      • 可以使用bsdiff生成patch包
      • 应用宝也提供增量更新sdk可供接入
    • 资源
      Unity3D通过使用AssetBundle即可实现动态更新资源的功能。

    手游在实现这块时需要注意的几点:

    • 游戏发布出一定要提供游戏内更新的途径。即使是删掉测试,保不准这期间需要进行资源或者BUG修复更新。很多玩家并不知道如何更新,而且Android手机应用分发平台多样,分发平台本身也不会跟官方同步更新(特别是小的分发平台)。
    • 更新功能要提供强制更新、非强制更新配置化选项,并指定哪些版本可以不强更,哪些版本必须强更。
    • 当游戏提供非强制更新功能之后,现网一定会存在多个版本。如果需要针对不同版本做不同的更新,例如配置文件A针对1.0.0.1修改了一项,针对1.0.0.2修改了另一项,2个版本需要分别更新对应的修改,需要自己实现更新策略IIPS不提供这个功能。当需要复杂的更新策略,推荐自己编写更新服务器和客户端逻辑,不使用iips组件(其实自己实现也很简单)。

    没有运营经验的人会选择二进制,认为二进制安全、更小,这对端游/手游外网只存在一个版本的游戏适合,对一般不强升版本的手游并不适合,反而会对更新和维护带来很大的麻烦。

    • 配置使用XML或者JSON等文本格式,更利于多版本的兼容和更新。最开始腾讯桌球客户端使用的二进制格式(由excel转换而来),但是随着运营配置格式需要增加字段,这样老版本程序就解析不了新的二进制数据,给兼容和更新带来了很大的麻烦。这样就要求上面提到的针对不同步做不同更新,又或者配置一开始就预留好足够的扩展项,其实不管怎么预留扩展也很难跟上需求的变化,而且一开始会把配置表复杂化但是其实只有一张或者几张才会变更结构。
    • iOS版本的送审版本需要连接特定的包含新内容的服务器,现网服务器还不包含新内容。送审通过之后,上架游戏现网服务器会进行更新,iOS版本需要连接现网服务器而非送审服务器,但是这期间又不能修改客户度,这个切换需要通过服务器下发开关进行控制。例如通过指定送审的iOS游戏版本号,客户端判断本地版本号是否为送审版本,如果是连接送审服务器,否则连接现网服务器。

    4.用脚本,还是不用?这是一个问题

    方便更新,减少Crash(特别是使用C++的cocos引擎)

    通过上面一节【版本与补丁】知道要实现代码更新是非常困难的,正式这个原因客户端开发的压力是比较大的,如果出现了比较严重的BUG必须发强制更新版本,使用脚本可以解决这个问题。
    由于Unity3D手游更新成本比较大,而且目前腾讯桌球要求不能强制更新,这导致新版本的活动覆盖率提升比较慢、出现问题之后难以修复。针对这个情况,考虑引入lua进行活动开发,后续发布活动及修复bug只需要发布lua资源,进行资源更新即可,大大降低了发布和修复问题的成本。
    可选方案还有使用Html5进行活动开发,目前游戏中已经预埋了Html5活动入口,并且已经用来发过"玩家调查"、"腾讯棋牌宣传"等。但是与lua对比,不能做到与Unity3D的深度融合,体验不如使用lua,例如不能操作游戏中的ui、不能完成复杂界面的制作、不能复用已有的功能、玩家付费充值跟已有的也会有差异

    游戏脚本之王——Lua

    在公司内部魔方比较喜欢用lua,火隐忍者(手游)unity+ulua,全民水浒cocos2d-x+lua等等都有使用lua进行开发。我们可以使用公司内部的xlua组件,也可以使用ulua[http://ulua.org/]、UniLua[https://github.com/xebecnan/UniLua]等等。

    5.资源管理

    5.1资源管理器

    • 业务不要直接使用引擎或者系统原生接口,而是封装一个资源管理器负责:资源加载、卸载
    • 兼容Resource.Load与AssetBundle资源互相变更需求,开发期间使用Resource.Load方式而不必打AB包效率更高
    • 加载资源时,不管是同步加载还是异步加载,最好是使用异步编码方式(回调函数或者消息通知机制)。如果哪一天资源由本地加载改为从服务器按需加载,而游戏中的逻辑都是同步方式编码的,改起来将非常痛苦。其实异步编码方式很简单,不比同步方式复杂。

    5.2资源类型

    • 图片/纹理(对性能、包体影响最大因素)
    • 音频
      • 背景音乐,腾讯桌球使用.ogg/.mp3
      • 音效,腾讯桌球使用.wav
    • 数据
      • 文本
      • 二进制
    • 动画/特效

    5.3图片-文件格式与纹理格式

    • 常用的图像文件格式有BMP,TGA,JPG,GIF,PNG等;
    • 常用的纹理格式有R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8, A8R8G8B8等。

    文件格式是图像为了存储信息而使用的对信息的特殊编码方式,它存储在磁盘中,或者内存中,但是并不能被GPU所识别,因为以向量计算见长的GPU对于这些复杂的计算无能为力。这些文件格式当被游戏读入后,还是需要经过CPU解压成R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8, A8R8G8B8等像素格式,再传送到GPU端进行使用。
    纹理格式是能被GPU所识别的像素格式,能被快速寻址并采样。举个例子,DDS文件是游戏开发中常用的文件格式,它内部可以包含A4R4G4B4的纹理格式,也可以包含A8R8G8B8的纹理格式,甚至可以包含DXT1的纹理格式。在这里DDS文件有点容器的意味。OpenGL ES 2.0支持以上提到的R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8,A8R8G8B8等纹理格式,其中 R5G6B5,A4R4G4B4,A1R5G5B5每个像素占用2个字节(BYTE),R8G8B8每个像素占用3个字节,A8R8G8B8每个像素占用 4个字节。
    基于OpenGL ES的压缩纹理有常见的如下几种实现:

    1. ETC1(Ericsson texture compression),ETC1格式是OpenGL ES图形标准的一部分,并且被所有的Android设备所支持。
    2. PVRTC (PowerVR texture compression),支持的GPU为Imagination Technologies的PowerVR SGX系列。
    3. ATITC (ATI texture compression),支持的GPU为Qualcomm的Adreno系列。
    4. S3TC (S3 texture compression),也被称为DXTC,在PC上广泛被使用,但是在移动设备上还是属于新鲜事物。支持的GPU为NVIDIA Tegra系列。

    5.4资源工具

    有了规范就可以做工具检查,从源头到打包

    • 资源导入检查
    • 资源打包检查

    6.性能优化

    掉帧主要针对GPU和CPU做分析;内存占用大主要针对美术资源,音效,配置表,缓存等分析;卡顿也需要对GPU和CPU峰值分析,另外IO或者GC也易导致。


    6.1工欲善其事,必先利其器

    • Unity Profiler
    • XCode instruments
    • Qualcomm Adreno Profiler
    • NVIDIA PerfHUD ES Tegra

    6.2CPU:最佳原则减少计算

    • 复用,UIScrollView Item复用,避免频繁创建销毁对象
    • 缓存,例如Transform
    • 运算裁剪,例如碰撞检测裁剪
      • 粗略碰撞检测(划分空间——二分/四叉树/八叉树/网格等,降低碰撞检测的数量)
      • 精确碰撞检测(检查候选碰撞结果,进而确定对象是否真实发生碰撞)
      • 休眠机制:避免模拟静止的球
    • 逻辑帧与渲染帧分离
    • 分帧处理
    • 异步/多线程处理

    6.3GPU:最佳原则减少渲染

    • 纹理压缩
    • 批处理减少DrawCall(unity-Static Batching和Dynamic Batching,cocos SpriteBatchNode)
    • 减少无效/不必要绘制:屏幕外的裁剪,Flash脏矩阵算法,
    • LOD/特效分档
    • NGUI动静分离(UIPanel.LateUpdate的消耗)
    • 控制角色骨骼数、模型面数/顶点数
    • 降帧,并非所有场景都需要60帧(腾讯桌球游戏场景60帧,其他场景30帧;天天酷跑,在开始游戏前,FPS被限制为30,游戏开始之后FPS才为60。天天飞车的FPS为30,但是当用户一段时间不点击界面后,FPS自动降)

    6.4内存:最佳原则减少内存分配/碎片、及时释放

    • 纹理压缩-Android ETC1、iOS PVRTC 4bpp、windows DXT5
    • 对象池-PoolManager
    • 合并空闲图集
    • UI九宫格
    • 删除不用的脚本(也会占用内存)

    6.5IO:最佳原则减少/异步io

    • 资源异步/多线程加载
    • 预加载
    • 文件压缩
    • 合理规划资源合并打包,并非texturepacker打包成大图集一定好,会增加文件io时间

    6.6网络:其实也是IO的一种

    使用单线程——共用UI线程,通过事件/UI循环驱动;还是多线程——单独的网络线程?

    • 单线程:由游戏循环(事件)驱动,单线程模式比使用多线程模式开发、维护简单很多,但是性能比多线程要差一些,所以在网络IO的时候,需要注意别阻塞到游戏循环。说明,如果网络IO不复杂的情况下,推荐使用该模式。
      • 在UI线程中,别调用可能阻塞的网络函数,优先考虑非阻塞IO
      • 这是网络开发者经常犯的错误之一。比如:做一个简单如 gethostbyname() 的调用,这个操作在小范围中不会存在任何问题,但是在有些情况中现实世界的玩家却会因此阻塞数分钟之久!如果你在 GUI 线程中调用这样一个函数,对于用户来说,在函数阻塞时,GUI 一直都处于 frozen 或者 hanged 状态,这从用户体验的角度是绝对不允许的。
    • 多线程:单独的网络线程,使用独立的网络线程有一个非常明显的好处,主线程可以将脏活、累活交给网络线程做使得UI更流畅,例如消息的编解码、加解密工作,这些都是非常耗时的。但是使用多线程,给开发和维护带来一定成本,并且如果没有一定的经验写出来的网络库不那么稳定,容易出错,甚至导致游戏崩溃。下面是几点注意事项:
      • 千万千万别在网络线程中,回调主线程(UI线程)的回调函数。而是网络线程将数据准备好,让主线程主动去取,亦或者说网络线程将网络数据作为一个事件驱动主线程去取。当年我在用Cocos2d-x + Lua做魔法花园的手机demo时,就采用的多线程模式,最初在网络线程直接调用主线程回调函数,经常会导致莫名其妙的Crash。因为网络线程中没有渲染所必须的opengl上下文,会导致渲染出问题而Crash。

    6.6包大小

    • 使用压缩格式的纹理/音频
    • 尽量不要使用System.Xml而使用较小的Mono.Xml
    • 启用Stripping来减小库的大小
    • Unity strip level(strip by byte code)
    • Unity3D输出APK,取消X86架构
    • iOS Xcode strip开启

    6.7耗电

    下面影响耗电的几个因素和影响度摘自公司内部的一篇文章。


    7.异常与Crash

    7.1防御式编程

    • 非法的输入中保护你的程序
      • 检查每一输入参数
      • 检查来自外部的数据/资源
    • 断言
    • 错误处理
    • 隔栏
      防不胜防,不管如何防御总有失手的时候,这就需要异常捕获和上报。

    7.2异常捕获


    由于很多错误并不是发生在开发工作者调试阶段,而是在用户或测试工作者使用阶段;这就需要相关代码维护工作者对于程序异常捕获收集现场信息。异常与Crash的监控和上报,这里不介绍Bugly的使用,按照apollo或者msdk的文档接入即可,没有太多可以说的。这里主要透过Bugly介绍手游的几类异常的捕获和分析。

    Unity3D C#层异常捕获

    相比比较简单使用:

    code>Application.RegisterLogCallback/Application.RegisterLogCallbackThreaded

    注册回调函数/在一个新的线程中调用委托。特别注意:保证项目中只有一个Application.RegisterLogCallback注册回调,否则后面注册的会覆盖前面注册的回调!回调函数中stackTrace参数包异常调用栈。

    publicvoidHandleLog(stringlogString, stringstackTrace, LogType type){if(logString == null|| logString.StartsWith(cLogPrefix)){return;}ELogLevel level = ELogLevel.Verbose;switch(type){caseLogType.Exception:level = ELogLevel.Error;break;default:return;}if(stackTrace != null){Print(level, ELogTag.UnityLog, logString + "\n"+ stackTrace);}else{Print(level, ELogTag.UnityLog, logString);}}

    Android Java层异常捕获

    try…catch显式的捕获异常一般是不引起游戏Crash的,它又称为编译时异常,即在编译阶段被处理的异常。编译器会强制程序处理所有的Checked异常,因为Java认为这类异常都是可以被处理(修复)的。如果没有try…catch这个异常,则编译出错,错误提示类似于"Unhandled exception type xxxxx"。
    UnChecked异常又称为运行时异常,由于没有相应的try…catch处理该异常对象,所以Java运行环境将会终止,程序将退出,也就是我们所说的Crash。那为什么不会加在try…catch呢?

    • 无法将所有的代码都加上try…catch
    • UnChecked异常通常都是较为严重的异常,或者说已经破坏了运行环境的。比如内存地址,即使我们try…catch住了,也不能明确知道如何处理该异常,才能保证程序接下来的运行是正确的。

    Uncaught异常会导致应用程序崩溃。那么当崩溃了,我们是否可以做些什么呢,就像Application.RegisterLogCallback注册回调打印日志、上报服务器、弹窗提示用户?Java提供了一个接口给我们,可以完成这些,这就是UncaughtExceptionHandler,该接口含有一个纯虚函数:

    public abstract void uncaughtException (Thread thread, Throwableex)

    Uncaught异常发生时会终止线程,此时,系统便会通知UncaughtExceptionHandler,告诉它被终止的线程以及对应的异常,然后便会调用uncaughtException函数。如果该handler没有被显式设置,则会调用对应线程组的默认handler。如果我们要捕获该异常,必须实现我们自己的handler,并通过以下函数进行设置:
    public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler)

    特别注意:多次调用setDefaultUncaughtExceptionHandler设置handler,后面注册的会覆盖前面注册的,以最后一次为准。实现自定义的handler,只需要继承UncaughtExceptionHandler该接口,并实现uncaughtException方法即可。
    static class MyCrashHandler implements UncaughtExceptionHandler{  

    
    @Override  
    public  void uncaughtException(Thread thread, finalThrowable throwable) { 
    // Deal this exception  
    }

    }
    在任何线程中,都可以通过setDefaultUncaughtExceptionHandler来设置handler,但在Android应用程序中,全局的Application和Activity、Service都同属于UI主线程,线程名称默认为"main"。所以,在Application中应该为UI主线程添加UncaughtExceptionHandler,这样整个程序中的Activity、Service中出现的UncaughtException事件都可以被处理。
    捕获Exception之后,我们还需要知道崩溃堆栈的信息,这样有助于我们分析崩溃的原因,查找代码的Bug。异常对象的printStackTrace方法用于打印异常的堆栈信息,根据printStackTrace方法的输出结果,我们可以找到异常的源头,并跟踪到异常一路触发的过程。

    public static String getStackTraceInfo(finalThrowable throwable) {  
    
        String trace = "";
        try{  
            Writer writer = newStringWriter();
            PrintWriter pw = newPrintWriter(writer);
            throwable.printStackTrace(pw);
            trace = writer.toString();
            pw.close();
        } catch(Exception e) {
            return"";
        }
        return trace;
    }

    Android Native Crash

    前面我们知道可以编写和使用C/C++原生插件,除非C++使用try...catch捕获异常,否则一般会直接crash,通过捕获信号进行处理。

    iOS 异常捕获

    跟Android、Unity类似,iOS也提供NSSetUncaughtExceptionHandler 来做异常处理。

    #import "CatchCrash.h"
    @implementation CatchCrash
    voiduncaughtExceptionHandler(NSException *exception)
    {
    // 异常的堆栈信息
    NSArray *stackArray = [exception callStackSymbols];
    // 出现异常的原因
    NSString *reason = [exception reason];
    // 异常名称
    NSString *name = [exception name];
    NSString *exceptionInfo = [NSString stringWithFormat:@"Exception reason:%@\nException name:%@\nException stack:%@",name, reason, stackArray];
    NSLog(@"%@", exceptionInfo);
    NSMutableArray *tmpArr = [NSMutableArray arrayWithArray:stackArray];
    [tmpArr insertObject:reason atIndex:0];
    [exceptionInfo writeToFile:[NSString stringWithFormat:@"%@/Documents/error.log",NSHomeDirectory()]  atomically:YES encoding:NSUTF8StringEncoding error:nil];
    }
    @end

    但是内存访问错误、重复释放等错误引起崩溃就无能为力了,因为这种错误它抛出的是信号,所以还必须要专门做信号处理。

    windows crash

    同样windows提供SetUnhandledExceptionFilter函数,设置最高一级的异常处理函数,当程序出现任何未处理的异常,都会触发你设置的函数里,然后在异常处理函数中获取程序异常时的调用堆栈、内存信息、线程信息等。

    8.适配与兼容

    8.1UI适配

    • 锚点(UIAnchor、UIWidgetAnchor属性)
    • NGUI UIRoot统一设置缩放比例
    • UIStretch

    8.2兼容

    • shader兼容:例如if语句有的机型支持不好,Google nexus 6在shader中使用了if就会crash
    • 字体兼容:android复杂的环境,有的手机厂商和rom会对字体进行优化,去掉android默认字体,如果不打包字体会不现实中文字

    9.调试及开发工具

    9.1日志及跟踪

    事实证明,打印日志(printf调试法)是非常有效的方法。一个好用的日志调试,必备以下几个功能:

    • 日志面板/控制台,格式化输出
    • 冗长级别(verbosity level):ERROR、WARN、INFO、DEBUG
    • 频道(channel):按功能等进行模块划分,如网络频道只接收/显示网络模块的消息,频道建议使用枚举进行命名。
    • 日志同时会输出到日志文件
    • 日志上报(iOS屏蔽文档目录,出了问题也拿不到日志)

    9.2调试用绘图工具

    调试绘图用工具指开发及调试期间为了可视化的绘图用工具,如腾讯桌球开发调试时会使用VectrosityScripts可视化球桌的物理模型(实际碰撞线)帮助调试。这类工具可以节省大量时间及快速定位问题。通常调试用绘图工具包含:

    • 支持绘制基本图形,如直线、球体、点、坐标轴、包围盒等
    • 支持自定义配置,如颜色、粒度(线的粗细/球体半径/点的大小)等

    9.3游戏内置菜单/作弊工具

    在开发调试期间提供游戏进行中的一些配置选项及作弊工具,以方便调试和提高效率。例如腾讯桌球游戏中提供:

    • 游戏内物理引擎参数调整菜单;
    • 修改签到奖励领取天数等作弊工具

    注意游戏内的所有开发调试用的工具,都需要通过编译宏开关,保证发布版本不会把工具代码包含进去

    9.4Unity扩展

    Untiy引擎提供了非常强大的编辑器扩展功能,基于Unity Editor可以实现非常多的功能。公司内部、外部都有非常的开源扩展可用
    公司外部,如GitHub上的:
    UnityEditor-MiniExtension
    Unity-Resource-Checker
    UnityEditorHelper
    MissingReferencesUnity
    Unity3D-ExtendedEditor

    公司内部:
    TUTBeautyUnityUnityDependencyBy

    10.项目运营

    自动构建

    • 版本号——主版本号.特性版本号.修正版本号.构建版本号
      • [构建版本号]应用分发平台升级判断基准
    • 自动构建
      • Android
      • iOS — XUPorter

    公司内部接入SODA即可,建议搭建自己的构建机,开发期间每日N Build排队会死人的,另外也可以搭建自己的搭建构建平台

    统计上报

    • Tlog上报
    • 玩家转化关键步骤统计(重要)
    • Ping统计上报
    • 游戏业务的统计上报(例如桌球球局相关的统计上报)
    • 灯塔自定义上报

    运营模板

    • 配置化
    • 服务器动态下发
    • CDN拉取图片并缓存

    上线前的checklist

    项目要点说明指标
    灯塔上报1. 灯塔自带统计信息 2. 自定义信息上报灯塔里面包含很多统计数据,需要检查是否ok1. 版本/渠道分布 2. 使用频率统计 3. 留存统计(1天留存、3天留存、7天留存、14天留存) 4. 用户结构统计(有效用户、沉默用户、流失用户、回流用户、升级用户、新增用户) 5. 硬件统计(机型+版本、分辨率、操作系统、内存、cpu、gpu) 6. Crash统计(Crash版本、Crash硬件、Crash次数等)等等
    信鸽推送能够针对单个玩家,所有玩家推送消息  
    米大师支付正常支付  
    安全组件1. TSS组件接入 2. 隐藏内部符号表:C++开发的代码使用strip编绎选项,抹除程序的符号 3. 关键数据加密,如影子变量+异或加密算法项根据安全中心提供的文档完成所有接入安全组件,并通过安全中心的验收
    稳定性crash率用户crash率:发生CRASH的用户数/使用用户数;启动crash率:启动5S内发生crash用户数/使用用户数低于3%
    弱网络 断线重连考虑,缓存消息,重发机制等等客户端的核心场景必须有断线重连机制,并在有网络抖动、延时、丢包的网络场景下,客户端需达到以下要求:一. 不能出现以下现象:1、游戏中不能出现收支不等、客户端卡死/崩溃等异常情况;2、游戏核心功能(如登录、单局、支付等)不能有导致游戏无法正常进行的UI、交互问题;3、不能有损害玩家利益或可被玩家额外获利的问题;4、需要有合理的重连机制,避免每次重连都返回到登录界面。二. 需要对延时的情况有相应的提示
    兼容性  通过适配测试
    游戏更新1. 整包更新;2. 增量更新 特别说明:iOS送审版本支持连特定环境,与正式环境区别开,需要通过服务器开关控制
    性能内存、CPU、帧率、流量、安装包大小 【内存占用要求】Android平台:在对应档次客户端最低配置以上,均需满足以下内存消耗指标(PSS):
    1. 档机型指标:最高PSS<=300MB (PSS高于这个标准会影响28%用户的体验,约1800万)
    2. 档机型指标:最高PSS<=200MB(PSS高于这个标准会影响45%用户的体验,约3000万)
    3. 档机型指标:最高PSS<=150MB(PSS高于这个标准会影响27%用户的体验,约1800万)
    iOS平台:在对应档次客户端最低配置以上,均需满足以下内存消耗指标(PSS):
    1. 档机型指标:消耗内存(real mem)不大于250MB(高于这个标准会影响53%用户的体验,约1900万)
    2. 档机型指标:消耗内存(real mem)不大于200MB(高于这个标准会影响47%用户的体验,约1700万)
    【CPU占用要求】Android平台:CPU占用(90%)小于60% iOS平台:CPU占用(90%)小于80%
    【帧率要求】
    1. 档机型(CPU为四核1.4GHZ,RAM为2G)或以上机型:游戏核心玩法中,最小FPS应不小于25帧/秒 
    2. 档机型(CPU为两核1.1GH,RAM为768M)或以上机型:游戏核心玩法中,最小FPS应不小于25帧/秒 
    3. 档机型(CPU为1GHZ,RAM为768M)或以上机型:游戏核心玩法中,最小FPS应不小于18帧/秒
    【流量消耗要求】游戏核心玩法流量消耗情况(非一次性消耗)应满足以下条件:
    1. 对于分局的游戏场景,单局消耗流量不超过200KB 
    2. 对于不分局游戏场景或流量与局时有关的场景,10分钟消耗流量不超过500KB
     
    展开全文
  • 寒冬里的肥鸦瑟瑟发抖,这个冬天里基本上听到的都是各个行业里此起彼伏的抽冷气的声音,好在游戏版本号的重新发放让人感觉到了一点温暖。 最好的御寒手段就是提升自己,很多互联网大佬在这种环境下指出萌新就应该...

    寒冬里的肥鸦瑟瑟发抖,这个冬天里基本上听到的都是各个行业里此起彼伏的抽冷气的声音,好在游戏版本号的重新发放让人感觉到了一点温暖。

    最好的御寒手段就是提升自己,很多互联网大佬在这种环境下指出萌新就应该好好学习,提升自己才是最好的过冬方式。不吝给萌新灌输了许多有价值的理念,其中让肥鸦觉得很想跟大家很想分享的是:建立知识体系。

    一个完整且正确的知识体系对于一个开发者的指导意义来说绝对是无可比拟的,可以说是其重要性是战略意义的。确定好的知识体系会让开发者学习过程中少走很多弯路,集中精力在自己的领域里深耕细作。

    肥鸦这段时间稍微粗浅地总结了一下U3D手游开发的知识体系,并决心按着这个方向坚定不移的走下去。不多啰嗦,直接上思维导图(XMind制作)了。

    此处声明一下:肥鸦也只是摸着石头过河,有任何地方错误缺漏的,请狠狠地提出来吧,啊!

      

    U3D手游的开发,unity作为核心,要熟悉使用unity是不用多说最起码的吧,而算法与数据结构,设计模式这些放诸四海皆准的好东西,同时也是很多大厂的基本要求,不可以不察。

    c#自不用多说,语言是基石,语言是最基本最好用的工具。lua做脚本语言来说最大的好处是应用广泛,很多游戏的脚本语言都是用的lua,并且其语法较为简单。也可以按照自己的实际选择python啥的。

    3D图形学,涉及到数学,几何学等等,很复杂,肥鸦自己也是懵懵懂懂在学,也是重要的游戏开发知识点,要考的,划起来。

    数据库,MySQL由于其简单好用,轻便小巧,便宜(很多人可以免费使用它)而越来越受到人们的喜爱,成为各个大厂小厂的首选。

    ps:游戏引擎unity最为重要,虽然占的篇幅很小,但实际unity要用思维导图说清楚一页下来可能不够,后面把unity的知识点总结一下,展开说说,同时还有算法数据结构。

    展开全文
  • 谨以此文献给与我同样有创业...我相信像我一样的程序员一定大有人在,一个人、一身技术、一腔热血,想要涉足手游领域,却不清楚会投入多少。 所以,我把自己的这次游戏开发过程,完整记下来,给与我同样的
  • 【 玩转 LeanCloud 】开发者经验分享:作为一个通过 LeanCloud 入门后端开发的小白,一年多的开发历程让我收获满满。多个项目也在 LeanCloud 可靠的服务支撑下取得了不错的发展,其中用户量最大的项目的云引擎每分钟...
  • 下面我们就一起来看看手游开发中你需要了解的开发语言知识吧。 目前智能手机平台分为苹果手机iOS以及安卓系统两大类型。不同的平台开发语言的选择也是不同。很多人都说相较于安卓系统而言IOS系统的稳定性以及安全性...
  • 原文地址:Unity手游开发札记——布料系统原理浅析和在Unity手游中的应用0. 前言项目技术测试结束之后,各种美术效果提升的需求逐渐成为后续开发的重点,角色效果部分的提升目标之一便是在角色选择/展示界面为玩家...
  • 首先作为一篇VR手游开发笔记,第一章和VR没有任何关系,单纯讲环境配置 本章主要讲述怎样从零开始搭建android手机游戏开发环境,只用一台windows系统的PC机,将第一个示例工程成功运行在android虚拟机上。与单纯的...
  •  如果你想投身于当然热火的手游开发大潮中来,那么第一件事就是选择游戏引擎。因为游戏引擎大大的提高了我们的的开发效率,比如跨平台,以及游戏中物理引擎与粒子系统的封装,所以选择一款好的游戏引擎对于游戏的...
  • 在学习cocos2dx的过程中参考球球大作战手游开发的一款练手游戏,前后断断续续用了两个多月的时间。使用的cocos2d-x版本为3.8.1,游戏支持联网实时对战功能,服务端使用python 2.7.5开发,客户端和服务端使用...
  • 欢迎加入Unity业内qq交流群:956187480 qq扫描二维码加群 本文从以下10大点进行阐述: 1.架构设计 ...1、架构设计好的架构利用大规模项目的多人团队开发和代码管理,也利用查找错误和后期维护...
  • 手游开发分辨率

    2017-09-23 10:26:56
    1334 * 750
  • 随着JavaScript结合HTML5开发越来越受欢迎,很多浏览器支持的新功能正被用户使用,与此同时,许多新的游戏正在使用JavaScript进行开发。 基于JavaScript开发的游戏是唯一一个能够跨桌面,Web和移动三种平台的。今天...
  • 前言现在很多手游都有虚拟按钮–尤其是那些需要操作高的。那么我们也要紧跟时代步伐,开发一个虚拟按钮插件。难点解释1、首先绝对要先熟悉一下pixi。 2、要计算一下手指触摸拖动摇杆的角度–小学数学要过关,假如是...
  • 无论是和Adobe关系亲密的Starling还是时下手游开发正火的cocos2d都可以使用它打包的素材。而且其输出的格式远远不止支持这两种开发模式。 它的好处和使用方法不必多说,网络上的资源已经很多了。我只说一点印象深刻...
  • 引擎简介:Unity3D是由Unity Technologies开发的一个跨平台的专业3D游戏引擎,可发布游戏至Windows、Mac、Wii、iPhone和Android平台。也可以利用Unity web playe或flash插件发布网页游戏 授权方式:闭源,基础版本...
  • 1.查询招聘网站对于Unity开发工程师的要求,C#熟练,LUA用于热更新,C++ 或 其他后端语言了解,熟悉Unity架构,了解常用算法和数据结构。 2.确认自己目前已拥有的技能和需要掌握的技能,核心需求点目前是LUA的使用...
  • Unity的资源打包,如果要做完美,其实是很复杂的.那么为什么资源要打包呢,因为我们要做资源更新.没办法啊. 在我看来,完美的资源打包至少有以下几个方面要处理好: 1) 资源分类设计合理....2) 灵活的文件打包结构....
1 2 3 4 5 ... 20
收藏数 33,336
精华内容 13,334
关键字:

手游开发