转自:https://blog.csdn.net/operhero1990/article/details/51482734

目前已经历了两款游戏的制作。而两款游戏的新手引导,都是由我来完成的。因此,想写篇文章记录制作新手引导过程中的一些心得。

一、新手引导的分类
从触发方式上,引导分为强制引导和非强制引导。现在国产游戏上来就是一大段的强制引导,强制玩家点击某一区域来熟悉游戏。强制引导过程中,玩家没有多余的操作选择。这种方式虽然受到了很多的诟病,但依然大行其道,这背后的市场数据分析暂且不予讨论吧。而非强制指引,是根据游戏进度和剧情需要,触发不同的引导。再我看来,非强制指引,只不过是由某种特殊事件触发了一段强制指引行为而已。所以,强制指引是实质,非强制指引只是再次基础上做了灵活运用。

在来看看强制指引。大体上可以分为对白和指引点击两种情况。对白用于介绍剧情,指引点击则指引玩家具体操作。由于项目使用的是cocos引擎,且游戏逻辑使用lua脚本编写,因此下面将以cocos-lua方式距离说明。

二、新手引导的实现
如何构建一套完整的新手引导系统呢?最终要的就是为策划构建一张新手引导表格,再以此表格为依据,实现一个管理类guideMgr以及相应的表现UI(假设我们按上节提到的对白和指引的分类方式,则需要分别实现guideDlg和guideOper)。

<表格>

那一张新手引导表格需要哪些内容呢?这就需要设想新手引导会遇到哪些问题:

1、同步服务器?告诉服务器我完成到了哪一步,一次来获得相应奖励或判断完成新手引导

2、重启游戏后继续引导?因各种原因重启游戏后,需要从上次中断处继续引导,第一个问题解决了,这个问题也好解决

3、游戏随机性大,如何确保引导不出问题?因为新手引导需要确保流程的通畅,以为游戏中的偶然因素需要排除。可能需要做一些特殊的处理,比如构建一些虚拟数据来取缔原来的游戏随机数据

4、如何指引特定界面的特定按钮?如何确定上一步指引打开了指定界面,并且当前指引了特定的按钮

带着以上问题,我们来设计引导表格:

指引id。id有两个作用,第一个是用于客户端与服务器的同步,第二个是方便客户端使用id做特殊处理。这是为了解决问题1、2、3。

类型变量type。他的作用是指明这是什么指引类型(对白or操作指引)

指引所在场景ui。解决问题4。

指引按钮widget。解决问题4。

是否同步sync。解决问题1。

当然表格里还可以有其它内容,比如显示的图片路劲,文字内容以及面对各种复杂情况的需求(实际解决问题的时候,自行扩充吧)

假设我们需要指引玩家签到,正常流程是在主场景或主UI(MainScene)上点击签到按钮(btnSign),签到界面(SignUI)打开后,点击签到(btnOK),最后关闭签到界面(btnClose)。注意,如果玩家在1002步点击了签到按钮,这时候他退出了游戏,重进游戏后,应当判断他完成了签到指引而跳过1003步。所以1002步上传给服务器的同步id应该是1004。这样,重启游戏时,客户端从服务器获得同步id1004,从1004继续指引。

<guideMgr>
guideMgr首先需要同步服务器指引信息。通过syncFromServer(id)来同步从服务器发来的信息(在进入游戏时执行),syncToServer(id)来向服务器同步信息。

其次,guideMgr需要知道指定界面是否打开(由于某些界面需要网络返回,因此不是及时打开,这时候指引应该被挂起,直到等到特定界面)。如果你的游戏中有UIMgr,那这件事情就相当好办。当通过UIMgr创建一个界面时,调用guideMgr.addUI(uiname, uiInstance)方法,通知guideMgr你所需要的界面已经打开。通过UIMgr关闭界面时,调用guideMgr.removeUI(uiname)来删除记录。

其次,guideMgr提供方法stepEx()供外部调用。当指引所在场景的指引按钮被点击时,主动调用guideMgr.stepEx(),告诉guideMgr我完成这一步指引啦,快点开始下一步吧!

local guideMgr = {}
local isGuiding -- 是否开启指引
local isSearchingUI -- 等待指引的场景打开,进行指引
local uis -- 打开的界面集合
local guideIndex = 1 -- 指引的顺序索引
local guideInfo -- 当前引导信息local function startCurGuide()if guideInfo and uis[guideInfo.ui] then isSearchingUI = falseif guideInfo.guideType == 1 thenUIMgr:showUI("UI_guideDlg", guideInfo)elseif guideInfo.guideType == 2 thenUIMgr:showEx("UI_guideOper", guideInfo, uis[guideInfo.ui])end elseisSearchingUI = trueend
endlocal function finishCurGuide()if guideInfo.guideType == 1 thenUIMgr:removeUI("UI_guideDlg")elseif guideInfo.guideType == 2 thenif uis["UI_guideOper"] thenuis["UI_guideOper"]:onEnd()UIMgr:removeUI("UI_guideOper")endendif guideInfo.sync ~= -1 thenFramework.Uti:SendMsg("cSyncGuide " .. guideInfo.sync)end
endfunction guideMgr.init()guideIndex = 1isGuiding = falseisSearchingUI = falseuis = {}guideInfo = nil
end-- 添加当前打开的所有UI界面
function guideMgr.addUI(uiname,uiInstance)uis[uiname] = uiInstanceif isSearchingUI thenstartCurGuide()end
end-- 移除关闭的界面
function guideMgr.removeUI(uiname,ui)if uis[uiname] thenuis[uiname] = nilend
end-- 同步服务器数据
function guideMgr.syncFromServer(idx)-- 没有同步数据则从第一部开始指引if idx == -1 thenguideInfo = game.data["Guide"][1]elsefor i = 1,#game.data["Guide"] doif idx == game.data["Guide"][i].id thenguideInfo = game.data["Guide"][i]guideIndex = ibreakendendendif guideInfo == nil thenisGuiding = falseuis = {}returnendguideMgr.run()
end-- 重进游戏后,一些断开的步骤需要重新打开之前的界面
function guideMgr.restartCheck()end-- 开始新手引导
function guideMgr.run()isGuiding = trueguideMgr.restartCheck()startCurGuide()
endfunction guideMgr.stepEx()if isGuiding == false thenreturn endfinishCurGuide()if guideIndex < #game.data["Guide"] thenguideIndex = guideIndex + 1guideInfo = game.data["Guide"][guideIndex]startCurGuide()return endFramework.Uti:SendMsg("cSyncGuide over")isGuiding = falseisSearchingUI = falseguideInfo = nil
end-- 是否进行新手引导
function guideMgr.isGuiding()return isGuiding
end-- 获取当前引导信息
function guideMgr.getInfo()return guideInfo
endreturn guideMgr

以上就是guideMgr部分的代码,其中startCurGuide()依据类型分别创造不同的指引UI(guideDlg or guideOper)
<guideDlg>
这部分暂略吧,无法就是现实一些图片和一些文字,点击屏幕任意位置就结束现实,调用guideMgr.stepEx()进入下一步

<guideOper>
在guideMgr的startCurGuide()方法中,创建了guideOper,并将指引信息(表中当前指引行数据)和需指引界面实力uiInstance传递给guideOper。uiInstance需要实现三个方法,uiInstance.onGuideBegin(id)、uiInstance.onWidgetTouched(id, touchEvent)、uiInstance.onGuideEnd(id),实现指引前的数据初始化(如果需要),点击操作的响应(需要相应地方调用guideMgr.stepEx()结束这一步的指引),指引完成后的处理(如果需要)。这部分也不打算贴代码了,因为实际游戏中,有些特殊情况需要特殊处理(比如有点击指引,也有拖拽指引。有高亮点击区域的美术需求,有指引特效等等),实际代码比较杂。guideOper是遮罩在游戏层之上的,他的底层baffleLayer会吞噬点击事件(让玩家不会乱点),并且依据需要指引的widget,初始化touchLayer大小与位置。

当touchLayer接收到点击事件后,会调用uiInstance.onWidgetTouched函数来向下传递点击事件。

源码实现比较简单,这里提供一段有用的代码,就是让点击区域高亮,其余地方用半透明黑色蒙版遮罩,先看效果

再上代码:

local function highlightWidget(widget)local clip = cc.ClippingNode:create()clip:setAnchorPoint(0, 0)clip:setPosition(0,0)clip:setName("guideClip")clip:setInverted(true)clip:setAlphaThreshold(0)self.uiInstance.csbNode:getParent():addChild(clip)local layerBg = cc.LayerColor:create(cc.c4b(0, 0, 0, 150))clip:addChild(layerBg)local stencil = widget:clone()local ach = widget:getAnchorPoint()local p1 = widget:convertToWorldSpace(cc.p(0,0))stencil:setAnchorPoint(cc.p(0,0))stencil:setPosition(p1)clip:setStencil(stencil)clip:setInverted(true)clip:setAlphaThreshold(0.0)
end

看下cocos裁剪节点的知识就懂啦!
先写这么多,实际过程中,还有许多特殊情况需要处理。这里只是实现一套通用的基本框架。后续可能会继续补充~

谈谈游戏中新手引导是如何制作的相关推荐

  1. 谈谈游戏中的帮派设计

    帮派,指帮伙派别,多指一大群人组成的群体.旧时多指因同乡.同行关系而结成的小团体. 游戏中的帮派跟现实中的帮派差不多,只不过成员不在是现实中的人,而是线下玩家在线上的虚拟化身,帮派在网络游戏中对玩家的 ...

  2. [Unity3D]手机3D游戏开发:FPS射击游戏中瞄准镜CrossHair的制作

    学习Unity脚本推荐:Unity3D官网索引 首先创建脚本文件用来初始化瞄准镜,脚本CrossHairGUI源码如下: var crosshair = SwitchGUI(); var locati ...

  3. Unity-3D捕鱼达人小游戏开发 —— 游戏中精灵动画的制作

    创建好的精灵动画拖进归类空项目之后一定要修改z轴,还有order in layer,从1开始依次增加5,越珍贵的鱼值越大 拖入右边保存预制体,删除左边的精灵动画 将鱼.鱼死亡.子弹的精灵动画全做成预制 ...

  4. Unity制作游戏中的场景

    Unity制作游戏中的场景 1.2.3  场景 在Unity中,场景(Scene)就是游戏开发者制作游戏时,所使用的游戏场景.它是一个三维空间,对应的三维坐标轴分别是X轴.Y轴和Z轴本文选自Unity ...

  5. 谈谈VR游戏中的性能优化

    VR游戏相对传统游戏,个人认为主要有三个方面的不同:玩法设计,输入方式,性能压力.今天就来谈一下VR游戏中的性能优化. 为什么VR游戏的性能压力很大? ·主要有三个因素的影响:高帧率,高分辨率,画两遍 ...

  6. 开放世界游戏中的大地图的实现——内容制作篇

    https://www.gameres.com/304464.html 开放世界游戏中的大地图的实现--程序技术篇 二.内容制作篇:设计和创造(Content Design & Creatio ...

  7. Unity3D游戏开发之在uGUI中使用不规则精灵制作按钮

      各位朋友大家好,欢迎关注我的博客,我的博客地址是http://www.qinyuanpei.com.最近因为受到工作上业务因素影响,所以博主在Unity引擎上的研究有所停滞.虽然目前的工作内容和U ...

  8. 电子游戏设计与制作 第六章 游戏中的人工智能

    文章目录 1 游戏人工智能发展 2 游戏AI技术的分类 确定型AI算法 行为型AI算法 3 智能体agent与基本感官系统 Agent基本感官系统 智能体感官系统组成 智能体感官系统设计 4 路径规划 ...

  9. 我的世界服务器如何制作武器,我的世界2B2T服务器玩家都会去做的7件事 第1件是游戏中的禁忌...

    原标题:我的世界2B2T服务器玩家都会去做的7件事 第1件是游戏中的禁忌 2B2T,一个黑暗和野蛮的服务器. 即便如此,2B2T的玩家们也依旧有着很多.与正常的服务器不同,2B2T要面临的敌人不是生物 ...

最新文章

  1. 百度AI生态方法论升级,AI开放平台深入7大细分领域
  2. 搜索 —— 深搜的剪枝技巧
  3. win10 + Terminal + WSL+ oh-my-zsh 配置漂亮实用的windows终端及配置ubuntu不加.exe打开windows程序
  4. 后台产品基本功:RBAC权限后台角色与权限设计
  5. linux文件名变量,文件名通配符、变量以及管道知识点的总结
  6. IT架构的本质--我的五点感悟
  7. 密码攻击之基于字典和彩虹表的密码攻击
  8. 关键词组合工具_SEO学习:如何挖掘行业关键词?关键词挖掘策略和工具推荐
  9. 微信公众号发送模板消息
  10. 2021公路水运工程试验检测考试大纲
  11. word文档压缩图片
  12. Go原生插件使用问题全解析
  13. k8s service nodeport
  14. html5中abbr,HTML 5 abbr 标签 - HTML 参考手册
  15. 在C中将二进制转换为十进制
  16. linux下运行eureka,Linux服务器重启后eureka报错
  17. 自定义圆环形进度条实现
  18. IB 物理真题: 比潜热、理想气体
  19. 三十二位计算机游戏推荐,这32种课间游戏不重样,总有一款适合您和学生!| 推荐收藏...
  20. 自我怀疑是叛徒。害怕尝试导致我们丢了本可以打赢的仗

热门文章

  1. java中this有什么用?
  2. 软件需求文档格式的标准写法
  3. Pycharm 设置
  4. 比较器Comparator
  5. php 正则匹配中文汉字
  6. R语言dplyr包group_by函数、quantile函数、summarise函数计算dataframe数据中指定数值数据列在每个分组中的多个分位数值
  7. wuc-tab标签点击不了_王者荣耀百里玄策原初追逐者怎么领取?百里玄策新皮肤领取不了...
  8. 嵌入式入门-交叉编译、bootloader、kernel、根文件系统关系
  9. 好久不见!~小编带给大家古老的vue搭配kityMinder使用方法
  10. Hack The Box Starting Point 渗透测试入门靶场 TIER 1 - Responder