精华内容
下载资源
问答
  • 给宝宝做一个cocos免费游戏-Node树和场景制作给宝宝做一个cocos免费游戏前言一、通用场景转换介绍二、map类场景1.构想2.建立Node树(2)双击mainMap场景,在层级管理器窗口建立以下Node树3.为相应的Node添加代码、...

    给宝宝做一个cocos免费游戏

    第一章 背景和开发框架介绍
    第二章 Node树和场景制作
    第三章 UI、地图和关卡文本制作
    第四章 摇杆、按键和角色动画制作
    第五章 敌人和AI制作
    第六章 角色和敌人行为互动脚本制作
    第七章 游戏打包、发布和调试


    前言

    前面做了开始动画,今天利用闲散时间做一下场景管理。场景主要包括Node树如何分布和场景切换管理。按照我们构想的世界观,应该是实验室可以执行超时空跳跃作为map类场景,按照不同任务跳跃到相应的场景应该就是冒险和战斗场景,实验室需要建设和推动主剧情就作为建设类场景。下面从通用场景转换方法和场景Node树搭建来介绍。


    一、通用场景转换介绍

    cocos creator使用cc.director.loadScene方法加载和切换不同场景,参考java类的用法,我们都把重复调用的方法写到canvasjs.js上,后面通过require(‘canvasjs.js’)来实例化和使用里面定义的方法、属性等。

        loadAndGotoScene:function(sname){
            cc.director.preloadScene(sname,function(e){
               //load完回调函数
               cc.director.loadScene(sname);
            });
        },
    

    二、场景Node树搭建

    1.构想

    场景切换需要界面来点击互动吧,高级点搞一个角色供玩家控制然后接触传送口来触发场景转换。毕竟剧情是时空管理局,就把时空跳跃实验室作为地图中转站。让主角在这里选择不同的章节开干。

    2.建立Node树

    (1)打开上一次建立的cocos项目,新建一个“mainMap”的Scene

    在这里插入图片描述
    顺便双击login场景文件,也把上一个login场景的点击任意键开始代码写一下,点击后load到我们mainMap场景
    在这里插入图片描述

    (2)双击mainMap场景,在层级管理器窗口建立以下Node树

    新建的操作都是在层级管理器:Canvas——右击创建节点——…
    其中:
    mapNode-空节点;UI-空节点;joystick/bg-sprite精灵;bt1~5-button按键;itemsScrollView-scrollview;equipmet-空节点,子对象head等为Sprite精灵节点;
    在这里插入图片描述
    后面做小地图或者更多功能会相应添加和删除node,可以右击复制mainMap场景文件,然后粘贴下来,作为后面其他场景使用(省点时间)

    3.为相应的Node添加代码、碰撞等组件

    3.1 设置“组”

    任选一个node,在属性检查器窗口找到GROUP-点击编辑按键
    在这里插入图片描述
    添加分组和允许碰撞设置如下:
    在这里插入图片描述
    保存后退回到node界面,设置UI的group为UI,这样就不会跟其他碰撞也能单独UIcamera查看
    在这里插入图片描述

    3.2 摄像头设置

    (1)点击Main Camera,在属性检查窗口设置如下(不显示UI组)
    在这里插入图片描述

    (2)添加多一个camera命名“UICamera”,设置如下,后面给角色添加镜头跟随,UI组件就不会由于摄像头移动产生位移离开摄像头范围了
    在这里插入图片描述
    这里说说原理:Main Camera不显示UI,故负责显示UI之外的内容;UICamera只显示UI,因为它本身不移动,故它显示的UI组的物体都是固定不动的,加上UICamera在main camera渲染后,所以UI都是在固定在屏幕中变成手柄按键

    3.3 mapNode节点

    mapNode的类型是一个空节点,后面制作map时候会详细介绍,作为副本不断添加Sprite作为map的对象,从而形成地图和场景进入口。这里在全局的canvasjs.js添加loadMapObj方法,把mapNode的对象写入json(请见这篇文章的项目文件),进入场景马上加载json以形成地图
    在Canvas节点添加canvasjs.js脚本组件,然后拖动prefab预制体到js定义的属性方便预加载和实例化(prefab怎么制作放到下一章)
    在这里插入图片描述

    json:
    {
    "mapobj" : [
    {"sname":"mainMap","type":"floor", "name":"fl0","posx":"0","posy":"100","rotation":"0"},
    {"sname":"mainMap","type":"wall",  "name":"wl0","posx":"100","posy":"-100","rotation":"0"},
    {"sname":"mainMap","type":"tree",  "name":"tr0","posx":"0","posy":"-100","rotation":"30"},
    {"sname":"mainMap","type":"box",   "name":"bo0","posx":"200","posy":"0","rotation":"0"},
    {"sname":"mainMap","type":"enemis","name":"en1","posx":"300","posy":"100","rotation":"0"},
    {"sname":"mainMap","type":"water", "name":"wt0","posx":"300","posy":"300","rotation":"0"}
    ],
    }
    js代码:
       loadMapObj: function (e) {
          var scenename = cc.director.getScene().name;
          var url = 'json/main';//resources/json/..
          cc.loader.loadRes(url, cc.RawAsset, function (err, res) {
              if (!err) {
                  var rs = res.json.mapobj;//loop
                  for (var i = 0; i < rs.length; i++) {
                      if (rs[i].sname == scenename && rs[i].type) {
                          //    cc.log(rs[i].name);
                          var obj;
                          switch (rs[i].type) {
                              case 'floor':
                                  obj = cc.instantiate(this.floor);//prefab预制体
                                  break;
                              case 'tree':
                                  obj = cc.instantiate(this.tree);
                                  break;
                              case 'stone':
                                  obj = cc.instantiate(this.stone);
                                  break;
                              case 'box':
                                  obj = cc.instantiate(this.box);
                                  break;
                              case 'water':
                                  obj = cc.instantiate(this.water);
                                  break;
                              case 'wall':
                                  obj = cc.instantiate(this.wall);
                                  break;
                              case 'enemis':
                                  obj = cc.instantiate(this.enemis);
                                  break;
                              case 'trigger':
                                  obj = cc.instantiate(this.trigger);
                                  break;
                          }
                          if (obj) {
                              //  obj.getComponent(cc.spriteFrame).spriteFrame = '';  
                              obj.name = rs[i].name;
                              obj.angle = - rs[i].rotation;//方向
                              obj.parent = this.mainmap;
                              obj.setPosition(cc.v3(rs[i].posx, rs[i].posy, 0));//位置 注意是否需要转换世界坐标 []字符串位数,不准
                          }
                      }
                  }
                  //
              } else { cc.log(err); }            //异步 往往会执行后面之后再回调函数
          });
          // cc.log(rs);
      },
    

    3.4 joystick/bg节点

    用于控制player的移动,按照角度运算来控制角色的移动。后面章节配代码详谈


    3.5 botton节点

    (1)动作类button:可以定义一个带参数的函数,后面跟player角色动作制作一起介绍
    (2)界面交互类button:控制显示/隐藏NODE

      onShowHide:function(e,customerData){
        var uiobj = cc.find('Canvas').getChildByName('UI');//只能在UI生效
        var obj  = uiobj.getChildByName(customerData);
        if(obj){
          obj.active = obj.active ? false:true;
        }
      },
    

    3.6 scrollview节点(items)

    一般使用scrollview作为物品栏。后面制作游戏物品写代码时候介绍
    在这里插入图片描述

    3.7 其他Sprite节点

    Sprite节点是用的最多的节点,一般使用来绑定icon等,然后添加碰撞、js脚本组件,使用起来不难。
    在这里插入图片描述

    总结

    今天先完成基本的场景搭建,也顺带简单介绍下botton、sprite、scrollview等我们游戏用的组件,后面继续制作UI、地图、关卡文本等。cocos项目文件和代码上传到我的博客下载资源中,欢迎下载

    展开全文
  • 使用地图编辑器构建游戏场景

    千次阅读 2018-06-10 16:56:58
        地图编辑器在游戏开发的前期扮演着非常重要的角色,它的主要功能就是用来制作游戏地图。     地图编辑器可以使用原生引擎所支持的语言来编写,比如 C...类似于《大富翁》类的游戏,需要做一个斜 45 度...

        地图编辑器在游戏开发的前期扮演着非常重要的角色,它的主要功能就是用来制作游戏地图

        地图编辑器可以使用原生引擎所支持的语言来编写,比如 C/C++;也可以使用引擎加嵌入脚本语言的方式来进行编写,比如 Lua 等。但是现在,一些成熟的游戏引擎都会自带地图编辑器。

    地图编辑器的种类

        由于游戏类型的不同,地图编辑器也不相同。类似于《大富翁》类的游戏,需要做一个斜 45 度角的地图编辑器。

        如果是俯视角度的游戏,地图编辑器的视角呈现方式也类似斜 45 度角的游戏。这两种编辑器制作地图的方式极其类似,唯一不同的是,斜 45 度角是用菱形的地图块拼接而成,俯视视角是用矩形的地图块拼接而成的
    这里写图片描述

        做一个横版卷轴游戏,就需要在地图编辑器内摆放横版的地图。如果地图是重复地图,类似《超级玛丽》,那就需要程序员重复贴图,而不需要在地图编辑器重复编辑相同的地图。
    这里写图片描述
        3D 游戏就会有 3D 地图编辑器,比如《魔兽争霸》编辑器,就是一个 3D 视角。地图编辑器的种类不同,保存的地图类型和文件结构也不一样。有些地图编辑器保存的是图片和位置,而有一些保存的却是一个脚本文件,方便直接载入游戏程序。

    了解地图编辑器的编写过程的重要性

        编写地图编辑器,能让你更好地了解游戏引擎 。在编写地图编辑器的过程中,除了音乐模块暂时不会被用到外,利用引擎编写的地图编辑器、地图资源的载入代码、保存代码等等,都会被用在正式的游戏中。

        编写地图编辑器的过程,可以优化游戏开发流程。 程序员之间会讨论关于资源载入、游戏内容加载和读取这些基础问题,并将最基础的流程完整地梳理一遍。在游戏正式开始开发之前,把这些流程梳理一遍,能极大提升开发过程中的流畅性。

        编写地图编辑器的过程,涉及 UI、按钮和键盘事件的使用。地图编辑器开发完毕后,主要是给美术人员使用,所以 UI 的点击、鼠标键盘事件是必不可少的。在地图编辑器中运用 UI、按钮、键盘事件后,在正式游戏开发中,这些代码可以直接移植到游戏代码中使用。

        编写地图编辑器的过程,能起到团队磨合的作用。 在编写的过程中,你会接触到策划、美术等很多人的意见,程序员之间也会对引擎的应用有很多的讨论(这一点在腾讯的游戏开发团队中体现的淋漓尽致,感兴趣的可以去看腾讯王者荣耀团队的游戏创作过程)。

        开发地图编辑器的过程可以帮助开发人员了解引擎、优化开发流程、测试 bug、磨合团队。

    地图编辑器与关卡编辑器

        关卡编辑器是一种主要给策划使用的编辑器,它涉及地图中的关卡内容。 一般情况下,关卡编辑器不涉及具体的地图细节,但是它涉及总体的游戏地图和游戏流程。

        地图编辑器的功能就相当于房屋的结构朝向图。我们可以从这张图里,看到每个房间的俯视图。里面包括门的位置、阳台的位置,甚至厕所的位置。而装修公司设计家居,就相当于关卡编辑器的功能。设计师会在你已有房间的结构内,摆放各种桌子、椅子、床、柜子、灯泡等具体的家居用品。

        在实际开发过程中,很多时候,只有一些成体系的大游戏才会把关卡编辑器单独分出来。很多时候,对一些小游戏来说,关卡编辑器和地图编辑器经常是在一起的,你可以在地图编辑器里面直接来编写关卡。

        常见的关卡编辑器的界面一般都是这样的。这个界面最左侧的对话框,是物件的选择界面,具体包括关卡内物件的选择和摆放;界面右侧的对话框是属性选择界面,定义这个物件的属性,比如这个物件是否可以弹跳、爆炸等等;界面右下角是物件 X、Y、Z 轴的编辑,可以自定义物件的拉伸和缩放。
    这里写图片描述
        比如FPS 枪战游戏。可以先在编辑器内画完所有俯视角的地图通路,然后在这个地方放上某种武器,在那个地方放上某种升级包。这就是一个关卡的总体架构。

        随后,需要在编辑器里编写一些简单的脚本程序。这些脚本程序会涉及玩家在进入游戏后总体的游戏进程和逻辑。

        关卡编辑器和地图编辑器的功能,就好比家装设计图和房屋结构朝向图,一个是在地图内设置物件的摆放位置和具体的表现形式;一个是设计地图本身。

    做游戏 Demo的重要性

        游戏 Demo 是完成游戏核心框架,测试地图编辑器等问题,Demo 最终会被舍弃。

        游戏 Demo 可以完成游戏核心框架。 绝大部分情况下,最终完成的游戏成品,都会和游戏 Demo 有较大的差异。这些差异体现在美术画面的优化细节、操作的优化细节、网络优化上等等。游戏 Demo 所肩负的任务,就是完成该游戏总体的核心内容框架。 在这个框架内,可以一窥游戏的总体逻辑、想呈现给玩家的是什么内容。

        游戏 Demo 可以测试 bug。 在游戏开发中,地图编辑器做完之后,会载入经地图编辑器制作的地图,这些地图在游戏中是否有 bug,是否需要调整,游戏体验好不好。这些内容在游戏 Demo 中将被测试出来,并且在正式开发中进行调整。

        游戏 Demo 可以磨合开发团队。有一些引擎自带地图编辑器,所以大多数情况下,地图编辑器不需要自己编写。这个时候,敲下的第一行代码就是游戏 Demo 的代码,所以游戏 Demo 就是团队人员的磨合。和地图编辑器一样,第一次编写游戏 Demo,会有来自策划、美术、程序等各方面的意见和讨论,而制作游戏 Demo 的过程对磨合团队是非常有利的。

        游戏 Demo 最终会被舍弃。 在开发过程中,Demo 版本是不稳定的,是有 bug 的。只要不是特别严重的,一般不会去进行特别的修正。但是一般来说,bug 会在正式版本中被修正。程序代码在游戏中跑起来是不是有瓶颈,bug 出现在哪里,哪些部分可以从 Demo 中提取出来,在正式开发中使用,哪些部分可以在正式版本中优化,这些都是游戏 Demo 所背负的作用。

        由于游戏类型不同,地图编辑器、关卡编辑器和游戏 Demo,并非是必须要做的内容,就像贪吃蛇、俄罗斯方块、象棋、围棋等等这样简单的游戏,这些都不需要任何编辑器。

        在游戏开发的正规流程中,要经历地图编辑器、关卡编辑器、游戏 Demo、正式开发等几个流程。但简单如游戏,可以直接上手编写代码。

    展开全文
  • 给宝宝做一个cocos免费游戏 第一章 背景和开发框架介绍 第二章 Node树和场景制作 第三章 UI、地图和关卡文本制作 第四章 摇杆、按键和角色spine动画制作 第五章 敌人和AI制作 第六章 角色和敌人行为互动脚本制作 第...

    给宝宝做一个cocos免费游戏

    第一章 背景和开发框架介绍
    第二章 Node树和场景制作
    第三章 UI、地图和关卡文本制作
    第四章 摇杆、按键和角色动画制作
    第五章 敌人和AI制作
    第六章 角色和敌人行为互动脚本制作
    第七章 游戏打包、发布和调试


    前言

    最近我们家小猿四个月了,特别喜欢握拳头,似乎有自己的武侠梦。作为程序员老爹,没其他本事,用宝宝作为角色做个游戏圆他的武侠梦,感觉还是挺有意义的。话不多说,有想法了,就算复制黏贴都要实现。看了下小游戏的框架和工具,感觉unity+c#和cocos creator+js比较适合,毕竟小猿爹做ERP java同时也做c#.net和前端开发。最后考虑cocos creator能发布到h5和微信,小游戏支持也好就选了cocos creator
    下面小猿爹会定期把进度和关键代码更新上来,作为cocos业余开发项目交流,有兴趣的朋友可以下载代码进行指导、相互学习都行。


    一、背景和剧情

    考虑小猿爹写了十年代码,文字功底确实一般般,纯粹从给宝宝一个完美童年的出发点出发。就选一个类穿越剧故事作为游戏剧情吧,这样随着小猿他爹不断熟悉cocos,逐渐有能力把曾迷恋的COD辐射废土大表哥甚至一刀9999等游戏融入进来,形成童年的n合一游戏。
    大致剧情:
    2222年,不知道是AI反叛还是人类互丢核弹,地球已经千疮百孔不再适合人类居住。苟延残存的人类为了生存躲进避难所,只能通过培养器的方式繁衍人类。避难所中,往往通过给培养器中的人类植入各个时代的生存场景挑战激发人类脑电波频繁互动,最后达到收集脑电波进行能量利用,以维持避难所的能源需求(抄,不,是致敬某某帝国)。主角便在这个时代出生。。。
    反正就一出生在培养容器,选择不同的生存场景(可以做成类穿越大杂烩毁童年),打怪升级,梦和现实中探究幕后的真相。(剧透了)

    二、开发框架和工具

    1.开发工具cocos creator相关操作

    大家可以直接问度娘,到搜索和下载cocos creator(注意不是cocos2dx或者3d)。然后下载vscode作为js编程和调试工具,也可以下载个谷歌浏览器(方便配合vscode调试)。

    (1)新建游戏项目

    安装后打开,注册(免费的),然后点击"新建项目"
    在这里插入图片描述

    (2)设置编辑器和调试工具

    依次点击菜单“文件”——“设置”——“数据编辑”,然后选择外部脚本编辑器为vscode安装目录下的code.exe
    在这里插入图片描述
    然后点击预览运行,如不用vscode+谷歌浏览器调试的话,可以勾选红圈的调试工具直接使用cocos模拟器调试(类似浏览器F12)
    在这里插入图片描述
    点击菜单“开发者”——“VSCODE工作流”——更新、安装…,建立vscode智能提示和谷歌调试工具:
    在这里插入图片描述
    打开vscode,扩展工具搜索“debugger”,选Debugger for Chrome,安装谷歌debug插件(可以用于cocosdebug),然后到cocos creator的菜单“开发者”——“VSCODE工作流”——添加ChromDebug配置,完成vscode的F5运行和调试配置
    在这里插入图片描述
    至此,项目和开发工具都配置完毕。开发工具大致使用方法如图:
    在这里插入图片描述

    (3)新建几个游戏对象作为范例

    1)在“资源管理器”窗口右击“assets”文件夹,选择新建——“Scene”(场景),命名为“login”,然后双击“login.fire”进入新建的场景
    2)在“层级管理器”-"Canvas"右击——创建节点——创建渲染节点——sprite(精灵),点击新建的sprite然后在“属性检查器”修改名称为“picNode”,调整大小为w:300 h:200
    在这里插入图片描述
    3)在“层级管理器”-"Canvas"右击——创建节点——创建渲染节点——label,新建文本控件,在“属性检查器”把string修改为“press any key to start”
    3)在“层级管理器”-"Canvas"右击——创建节点——创建渲染节点——richText,在“属性检查器”在richText的String中输入上述的剧情介绍。
    到这里,相信你也猜到上面对象用来做什么,后面写js脚本播放下剧情图片(ps出来的不多说),做出press any key一闪一闪的效果后,就算完成了第一课:进入游戏界面的开发了
    cocos creator使用指南请见官网:
    https://docs.cocos.com/creator3d/manual/zh/getting-started/first-game/

    2.游戏框架-cocs 2dx和JS

    总体上,cocos creator源于cocos 2d,使用js的node框架,即使用node+图片的移动变形、canvas画画等来实现游戏效果。接上面场景,新建js和绑定到node:
    (1)在“资源管理器”窗口右击“assets”文件夹,选择新建——文件夹,建立文件夹“script”,然后右击文件夹——新建——javascript,建立js。
    在这里插入图片描述
    (2)这个js就是框架脚本编写的地方,双击js文件名,则打开后结构如下

    //var com = require("comm.js");//全局变量js,引入后变成实例化,可以js的properties、自定义的funciton等
    cc.Class({
        extends: cc.Component,//cocos 2dx框架继承
        properties: {
          mapNode:{type:cc.Node,default:null},
          spf1:{type:cc.SpriteFrame,defualt:null},
          spf2:{type:cc.SpriteFrame,defualt:null},
          spf3:{type:cc.SpriteFrame,defualt:null},
          spf4:{type:cc.SpriteFrame,defualt:null},
          
           //属性值,可以定义node等提前加载的对象和属性
        },
    
        // LIFE-CYCLE CALLBACKS:
        
        onLoad () {
        this.playPic();//执行剧情图片播放
        },//node节点加载时候执行的方法
        start () {//node节点开始渲染时候执行方法
        },
        update (dt) {},//每一帧都执行的方法
        //自定义js方法
        playPic:function(e){
        if(this.picNode){    
        this.picNode.getComponent(cc.Sprite).spriteFrame = this.spf1;
        }
        },
    });
    

    (3)绑定js到层级管理器的"Canvas"中:
    在这里插入图片描述
    这样就能在加载Canvas的时候,直接执行canvasjs.js里面定义的onload等脚本。

    cocs js脚本怎么写,具体大家可以参考官方api:
    http://docs.cocos.com/creator/manual/zh/scripting/use-component.html


    ## 3.制作剧情动画

    现在给开场做一个动画,选定picNode,然后点击动画编辑器窗口,点击添加Animation组件,然后点击新建
    在这里插入图片描述
    在assert/resources/新建animationclipe文件夹,把clip文件保存到哪里:
    在这里插入图片描述
    开始做动画:
    属性列表中添加几个用于动作变化的属性(例如动画目标是变大变小,换图片,我选了position-位置 scale-缩放 cc.Sprite.SpriteFrame-展示图片)
    在这里插入图片描述
    添加关键帧:添加后会自动记录该属性变化形成动画,其他属性同理
    在这里插入图片描述
    通过“属性检查器”修改属性或者默认的工具拖动、缩放等调整场景编辑器的内容
    在这里插入图片描述

    最后点击“播放”按键进行动画预览,退出前记得点击保存
    在这里插入图片描述
    在这里插入图片描述

    最后在canvasjs.js的onLoad中添加播放动画代码

        onLoad () {
        // this.playPic();//执行剧情图片播放
       cc.find('Canvas').getChildByName('picNode').getComponent(cc.Animation).play('login');//保存的clip文件名
        ...
    

    总结

    今天先到这里,总结下学到了:
    1.cocos creator工具界面、配置和大致用法
    2.cocos creator +vscode编辑和调试js代码
    3.cocos creator 动画制作
    后续按章节更新和上传源代码。后面继续推进。
    全部代码如下,项目包留意本人博客下载。所用图片都是网上截取,仅用于技术交流,如有版权问题请联系本人删除

    // Learn cc.Class:
    //  - https://docs.cocos.com/creator/manual/en/scripting/class.html
    // Learn Attribute:
    //  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
    // Learn life-cycle callbacks:
    //  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
    //var com = require("comm.js");//全局变量js,引入后变成实例化,可以js的properties、自定义的funciton等
    cc.Class({
        extends: cc.Component,//cocos 2dx框架继承
        properties: {
          mapNode:{type:cc.Node,default:null},
          spf1:{type:cc.SpriteFrame,default:null},
          spf2:{type:cc.SpriteFrame,default:null},
          spf3:{type:cc.SpriteFrame,default:null},
          spf4:{type:cc.SpriteFrame,default:null},
          
           //属性值,可以定义node等提前加载的对象和属性
        },
    
        // LIFE-CYCLE CALLBACKS:
        
        onLoad () {
        // this.playPic();//执行剧情图片播放
        cc.find('Canvas').getChildByName('picNode').getComponent(cc.Animation).play('login');
        var rtxt = cc.find('Canvas').getChildByName('RichText');
        if(rtxt){
          this.typeText(rtxt,rtxt.getComponent(cc.RichText).string);
        }
        this.showEnterBt();
    
        },//node节点加载时候执行的方法
        start () {//node节点开始渲染时候执行方法
        },
        update (dt) {},//每一帧都执行的方法
        //自定义js方法
        playPic:function(e){
        if(this.picNode){
        
        this.picNode.getComponent(cc.Sprite).spriteFrame = this.spf1;
        }
        },
        typeText:function(rtxt,str){
          var j = 0;
          rtxt.getComponent(cc.RichText).string = "";
          this.schedule(function () {
            rtxt.getComponent(cc.RichText).string += str[j];
              j++;
          }, 0.1, str.length - 1, 0.2);
        },
        showEnterBt:function(e){
          var enbt =cc.find('Canvas').getChildByName('pressanykey');
          if(!enbt){return;}
          this.schedule(function(e){
            if(enbt.active){enbt.active = false;}else{enbt.active = true;}
          },0.3,999,0.2);
        },
    });
    
    ``
    
    
    展开全文
  • CocosCreator学习1:做一个简单的游戏

    万次阅读 2017-02-20 21:41:32
    做一个简单的地图,可以在地图上点击选择城市,发现用Cocos2D-X代码码出来好麻烦,尤其是城市位置问题,需要调试去找对像素区域做一个按钮控制,整个人都不好了。本来还想尝试用Tiled map来做,想法很逗比,应该不...

    把计步器写好了,到了写游戏场景、控件什么的时候,傻眼了。想做一个简单的地图,可以在地图上点击选择城市,发现用Cocos2D-X代码码出来好麻烦,尤其是城市位置问题,需要调试去找对像素区域做一个按钮控制,整个人都不好了。本来还想尝试用Tiled map来做,想法很逗比,应该不能用。今晚被长辈连番教育中,说到了撞墙走弯路才想起来,当初光顾着学引擎看代码了,竟然忘了还有CocosCreator,这么简单实用的工具我竟然没有去用,太傻了。而且现在距离比较提交程序结果时间也比较紧了,直接用CocosCreator做游戏时最明智的。下面将转向CocosCreator的学习。

    CocosCreator有很详细的入门教程,下面我就跟随这个教程来进行学习。
    http://www.cocos.com/docs/creator/getting-started/quick-start.html#–2

    打开项目

    教程中提供了一个简单游戏的初始版本,我就从这个游戏入手进行学习。从CocosCreator选择打开其他项目,打开start_project文件夹,选中即可打开。注意下载的start_project不能放在CocosCreator路径下。

    打开后如图:
    这里写图片描述

    在资源管理器面板中,可以看到项目中的文件。项目资源的根目录叫asserts,对应于解压初始版本得到的文件夹名。其中标注bf图标的文件是位图字体,是一种字体资源,由fnt文件和同名的png图片文件共同组成。

    创建场景

    下面来创建游戏场景。游戏场景一般包括:场景图像(Sprite)、文字(Label)、角色、以组件形式附加在场景节点上的游戏逻辑脚本。在资源管理器中点击asserts目录前面的加号,选择Scene,会创建一个New Scene的场景文件。
    这里写图片描述
    双击New Scene,就会在场景编辑器和层级管理器中打开这个场景。在层级管理器中可以看到当前场景的所有节点和他们的层级关系。

    Canvas画布节点/渲染根节点

    现在New Scene中只有一个Canvas节点,称为画布节点或渲染根节点,点击选中Canvas可以在属性检查器中看到他的属性。
    这里写图片描述
    这里写图片描述
    其中的Design Resolution属性用来指定游戏分辨率,Fit Hight和Fit Width是分辨率自适应匹配方法。只需要把图像放到Canvas下,就可以完成对不同分辨率的自适应,非常简单。

    设置场景图像

    增加背景图像

    在资源管理器中将textures中background图像拖到
    层级管理器的Canvas下即可增加背景图像,会看到Canvas下增加了一个background子节点。
    这里写图片描述
    点击文件->保存场景或使用快捷键ctrl+s保存场景后,在场景编辑器中便会显示增加的背景图像。
    这里写图片描述
    点击窗口左上角工具栏的第四格矩形变换工具,然后选中场景编辑器中的背景图像,可以实现对图像尺寸、位置、锚点的修改。
    这里写图片描述
    当然也可以直接使用属性检查器来直接设置这些参数。
    在实际的应用开发中背景图像一般都是要大于显示范围的,这样可以让背景图覆盖整个屏幕,不出现穿帮的情况。

    增加地面
    使用和增加背景图像相同的方法,将地面图像拖到层级管理器的Canvas上,将ground节点移到background节点下方。
    这里写图片描述
    在层级管理器中,下方的节点的渲染顺序在上方节点之后,也就是说下方节点会遮挡上方节点。
    这里写图片描述
    使用相同的方法可以对地面图像的尺寸、位置、锚点进行修改。

    增加主角
    同样的方法,将主角图像player拖到ground下方。在之后的动画中,需要主角接触地面并跳跃,因此将锚点改为最下方,即y值为0,然后将它拖到地面上。
    这里写图片描述

    编写脚本

    创建并添加脚本
    脚本也就是游戏的逻辑规则,需要代码实现。
    首先在资源管理器中右键点击assets文件夹,新建->文件夹,创建一个名为New Folder的文件夹,然后对其右击选择新建->JavaScript,创建一个JavaScript脚本NewScript,重命名为Player,双击即可打开编写界面。Cocos Creator 中脚本名称就是组件的名称。
    在Player中的properties部分增加以下代码:

    // Player.js
        //...
        properties: {
            // 主角跳跃高度
            jumpHeight: 0,
            // 主角跳跃持续时间
            jumpDuration: 0,
            // 最大移动速度
            maxMoveSpeed: 0,
            // 加速度
            accel: 0,
        },
        //...

    这些属性用于规定主角的移动方式,可以在属性检查器中直接设置属性的数值。

    然后在层级编辑器中选择player,在属性检查器中选择添加组件,选择增加用户脚本组件->Player,即可为主角添加组件。

    现在可以在属性检查器看到Player组件并修改属性数值了。
    这里写图片描述

    跳跃和移动代码
    在properties代码块下面定义setJumpAction方法:

    // Player.js
        properties: {
            //...
        },
    
        setJumpAction: function () {
            // 跳跃上升
            var jumpUp = cc.moveBy(this.jumpDuration, cc.p(0, this.jumpHeight)).easing(cc.easeCubicActionOut());
            // 下落
            var jumpDown = cc.moveBy(this.jumpDuration, cc.p(0, -this.jumpHeight)).easing(cc.easeCubicActionIn());
            // 不断重复
            return cc.repeatForever(cc.sequence(jumpUp, jumpDown));
        },

    修改onLoad: function:

    // Player.js
        onLoad: function () {
            // 初始化跳跃动作
            this.jumpAction = this.setJumpAction();
            this.node.runAction(this.jumpAction);
        },

    onLoad方法会在场景加载完成后立即执行,所以在这里进行初始化操作。
    保存脚本运行一下试试,可以看到player不断的在进行跳跃动作。

    在setJumpAction下面定义setInputControl方法来实现用A和D控制主角的移动操作:

    // Player.js
        setJumpAction: function () {
            //...
        },
    
        setInputControl: function () {
            var self = this;
            // 添加键盘事件监听
            cc.eventManager.addListener({
                event: cc.EventListener.KEYBOARD,
                // 有按键按下时,判断是否是我们指定的方向控制键,并设置向对应方向加速
                onKeyPressed: function(keyCode, event) {
                    switch(keyCode) {
                        case cc.KEY.a:
                            self.accLeft = true;
                            self.accRight = false;
                            break;
                        case cc.KEY.d:
                            self.accLeft = false;
                            self.accRight = true;
                            break;
                    }
                },
                // 松开按键时,停止向该方向的加速
                onKeyReleased: function(keyCode, event) {
                    switch(keyCode) {
                        case cc.KEY.a:
                            self.accLeft = false;
                            break;
                        case cc.KEY.d:
                            self.accRight = false;
                            break;
                    }
                }
            }, self.node);
        },

    修改onLoad方法,在其中加入向左和向右加速的开关,以及主角当前在水平方向的速度,最后再调用我们刚添加的setInputControl方法,在场景加载后就开始监听键盘输入:

    // Player.js
        onLoad: function () {
            // 初始化跳跃动作
            this.jumpAction = this.setJumpAction();
            this.node.runAction(this.jumpAction);
    
            // 加速度方向开关
            this.accLeft = false;
            this.accRight = false;
            // 主角当前水平方向速度
            this.xSpeed = 0;
    
            // 初始化键盘输入监听
            this.setInputControl();
        },

    最后修改update方法,添加加速度、速度和主角当前位置的设置:

    // Player.js
        update: function (dt) {
            // 根据当前加速度方向每帧更新速度
            if (this.accLeft) {
                this.xSpeed -= this.accel * dt;
            } else if (this.accRight) {
                this.xSpeed += this.accel * dt;
            }
            // 限制主角的速度不能超过最大值
            if ( Math.abs(this.xSpeed) > this.maxMoveSpeed ) {
                // if speed reach limit, use max speed with current direction
                this.xSpeed = this.maxMoveSpeed * this.xSpeed / Math.abs(this.xSpeed);
            }
    
            // 根据当前速度更新主角的位置
            this.node.x += this.xSpeed * dt;
        },

    这样就可以实现对主角移动的控制了。

    制作Prefab脚本-星星
    这里增加游戏规则,从随机位置生成星星,用主角接住星星即可得分。
    对于重复生成的节点,可以保存成Prefab(预置)资源,作为动态生成节点时的模板。
    这里直接将assets/textures/star资源到场景中,位置随意,给星星增加一个脚本,当主角碰到星星时,让星星消失。

    // Star.js
        properties: {
            // 星星和主角之间的距离小于这个数值时,就会完成收集
            pickRadius: 0
        },

    给star节点增加脚本,将pickRadius值设置为60。将层级管理器中的star节点拖到资源管理器的assets文件夹下,将场景中的star节点删除。star现在即为Prefab资源。

    添加游戏控制脚本
    在assets/scripts文件夹下添加游戏的主逻辑脚本Game,添加生成星星需要的属性:

    // Game.js
        properties: {
            // 这个属性引用了星星预制资源
            starPrefab: {
                default: null,
                type: cc.Prefab
            },
            // 星星产生后消失时间的随机范围
            maxStarDuration: 0,
            minStarDuration: 0,
            // 地面节点,用于确定星星生成的高度
            ground: {
                default: null,
                type: cc.Node
            },
            // player 节点,用于获取主角弹跳的高度,和控制主角行动开关
            player: {
                default: null,
                type: cc.Node
            }
        },

    然后将Game添加到Canvas节点上,然后将star这个Prefab资源拖到Canvas属性检查器Game组件中的Star Prefab属性上。把层级管理器中的ground和Player节点也拖到组件中相应属性处即可。设置Min Star Duration和Max Star Duration值为3和5,之后生成星星时,会在这两个值之间随机取值作为星星消失前经过的时间。

    在随机位置生成星星
    修改Game脚本,在onLoad方法后面添加星星的逻辑:

    // Game.js
        onLoad: function () {
            // 获取地平面的 y 轴坐标
            this.groundY = this.ground.y + this.ground.height/2;
            // 生成一个新的星星
            this.spawnNewStar();
        },
    
        spawnNewStar: function() {
            // 使用给定的模板在场景中生成一个新节点
            var newStar = cc.instantiate(this.starPrefab);
            // 将新增的节点添加到 Canvas 节点下面
            this.node.addChild(newStar);
            // 为星星设置一个随机位置
            newStar.setPosition(this.getNewStarPosition());
        },
    
        getNewStarPosition: function () {
            var randX = 0;
            // 根据地平面位置和主角跳跃高度,随机得到一个星星的 y 坐标
            var randY = this.groundY + cc.random0To1() * this.player.getComponent('Player').jumpHeight + 50;
            // 根据屏幕宽度,随机得到一个星星 x 坐标
            var maxX = this.node.width/2;
            randX = cc.randomMinus1To1() * maxX;
            // 返回星星坐标
            return cc.p(randX, randY);
        }

    添加主角碰触收集星星的行为
    重点在于星星要随时获取主角节点的位置,才能判断与主角的距离是否小于可收集距离。因此将Game组件的实例传给星星并保存,然后可以随时通过game.player来访问主角节点。
    在Game脚本的spawnNewStar方法最后添加如下代码:

    // Game.js
        spawnNewStar: function() {
            // ...
            // 将 Game 组件的实例传入星星组件
            newStar.getComponent('Star').game = this;
        },

    然后在star脚本里onLoad方法后面添加getPlayerDistance和onPicked方法:

    // Star.js
        getPlayerDistance: function () {
            // 根据 player 节点位置判断距离
            var playerPos = this.game.player.getPosition();
            // 根据两点位置计算两点之间距离
            var dist = cc.pDistance(this.node.position, playerPos);
            return dist;
        },
    
        onPicked: function() {
            // 当星星被收集时,调用 Game 脚本中的接口,生成一个新的星星
            this.game.spawnNewStar();
            // 然后销毁当前星星节点
            this.node.destroy();
        },

    在update方法中添加每帧判断距离,如果距离小于pickRadius属性规定值,就执行收集行为:

    // Star.js
        update: function (dt) {
            // 每帧判断和主角之间的距离是否小于收集距离
            if (this.getPlayerDistance() < this.pickRadius) {
                // 调用收集行为
                this.onPicked();
                return;
            }
        },

    现在可以看效果了。
    这里写图片描述

    添加计分牌
    在层级管理器的Canvas中右键创建新节点->创建渲染节点->Label(文字),命名为score。将position设为(0,180),string设为score:0,Font Size设为50。从资源管理器中将assets/mikado_outline_shadow位图字体资源拖到Font属性中。
    这里写图片描述

    添加得分逻辑
    在Game的properties里添加score需要的属性:

    // Game.js
        properties: {
            // ...
            // score label 的引用
            scoreDisplay: {
                default: null,
                type: cc.Label
            }
        },

    在onLoad方法里添加计分用的变量初始化:

    // Game.js
        onLoad: function () {
            // ...
            // 初始化计分
            this.score = 0;
        },

    在update方法后面添加gainScore的新方法:

    // Game.js
        gainScore: function () {
            this.score += 1;
            // 更新 scoreDisplay Label 的文字
            this.scoreDisplay.string = 'Score: ' + this.score.toString();
        },

    将score节点拖到Canvas属性的Game组件中的Score Display属性中。
    在Star脚本的onPicked方法中添加gainScore的调用:

    // Star.js
        onPicked: function() {
            // 当星星被收集时,调用 Game 脚本中的接口,生成一个新的星星
            this.game.spawnNewStar();
            // 调用 Game 脚本的得分方法
            this.game.gainScore();
            // 然后销毁当前星星节点
            this.node.destroy();
        },

    这样收集到星星,分数就会变化了。
    这里写图片描述

    失败判断和重新开始
    加入给星星加入计时消失的逻辑,在Game脚本的onLoad方法的spawNewStar调用之前加入需要的变量声明:
    // Game.js
    onLoad: function () {
    // …
    // 初始化计时器
    this.timer = 0;
    this.starDuration = 0;
    // 生成一个新的星星
    this.spawnNewStar();
    // 初始化计分
    this.score = 0;
    },
    然后在spawnNewStar方法最后加入重置计时器的逻辑,其中this.minStarDuration和this.maxStarDuration是我们一开始声明的Game组件属性,用来规定星星消失时间的随机范围:

    // Game.js
        spawnNewStar: function() {
            // ...
            // 重置计时器,根据消失时间范围随机取一个值
            this.starDuration = this.minStarDuration + cc.random0To1() * (this.maxStarDuration - this.minStarDuration);
            this.timer = 0;
        },

    在update方法中加入计时器更新和判断超过时限的逻辑:

    // Game.js
        update: function (dt) {
            // 每帧更新计时器,超过限度还没有生成新的星星
            // 就会调用游戏失败逻辑
            if (this.timer > this.starDuration) {
                this.gameOver();
                return;
            }
            this.timer += dt;
        },

    最后加入gameOver方法,游戏失败重新加载场景。

    // Game.js
        gameOver: function () {
            this.player.stopAllActions(); //停止 player 节点的跳跃动作
            cc.director.loadScene('game');
        }

    然后修改Star脚本,加入即将消失星星的提示效果,在update方法中加入以下代码:

    // Star.js
        update: function() {
            // ...
            // 根据 Game 脚本中的计时器更新星星的透明度
            var opacityRatio = 1 - this.game.timer/this.game.starDuration;
            var minOpacity = 50;
            this.node.opacity = minOpacity + Math.floor(opacityRatio * (255 - minOpacity));
        }

    这样游戏画面和逻辑就全部完成了,可以说游戏已经基本完成了。

    加入音效
    首先加入跳跃音效,在Player脚本中引用声音文件资源jumpAudio属性:

    // Player.js
        properties: {
            // ...
            // 跳跃音效资源
            jumpAudio: {
                default: null,
                url: cc.AudioClip
            },
        },

    修改setJumpAction方法,插入播放音效的回调,并通过添加playJumpSound方法来播放声音:

    // Player.js
        setJumpAction: function () {
            // 跳跃上升
            var jumpUp = cc.moveBy(this.jumpDuration, cc.p(0, this.jumpHeight)).easing(cc.easeCubicActionOut());
            // 下落
            var jumpDown = cc.moveBy(this.jumpDuration, cc.p(0, -this.jumpHeight)).easing(cc.easeCubicActionIn());
            // 添加一个回调函数,用于在动作结束时调用我们定义的其他方法
            var callback = cc.callFunc(this.playJumpSound, this);
            // 不断重复,而且每次完成落地动作后调用回调来播放声音
            return cc.repeatForever(cc.sequence(jumpUp, jumpDown, callback));
        },
    
        playJumpSound: function () {
            // 调用声音引擎播放声音
            cc.audioEngine.playEffect(this.jumpAudio, false);
        },

    然后加入得分音效,在Game脚本的properties添加引用声音文件:

    // Game.js
        properties: {
            // ...
            // 得分音效资源
            scoreAudio: {
                default: null,
                url: cc.AudioClip
            }
        },

    在gainScore方法添加播放声音的代码:

    // Game.js
        gainScore: function () {
            this.score += 1;
            // 更新 scoreDisplay Label 的文字
            this.scoreDisplay.string = 'Score: ' + this.score.toString();
            // 播放得分音效
            cc.audioEngine.playEffect(this.scoreAudio, false);
        },

    在层级管理器中,将assets/audio/jump声音资源拖到Player节点的组件Jump Audio属性上。将assets/audio/score资源拖拽到Canvas节点Game组件的Score Audio属性上。
    大功告成,一个完整的游戏就做好了。

    展开全文
  • 开言: ...为了大家做游戏方便,于是我给这个引擎加了这么一个类。 本系列文章文件夹: 怎样制作一款HTML5 RPG游戏引擎——第一篇,地图类的实现 http://blog.csdn.net/yorhomwang/article/details...
  • cocos2dx使用TiledMap创建斜45度地图场景

    千次阅读 热门讨论 2014-01-02 20:29:43
    做游戏场景一个很重要的部分,如果缺少这一步,很难做出好的游戏,对于cocos2dx来说,有很多2D的地图编辑器可以用,效果都还可以,其中Tiled是支持的比较好的,它支持Tiled编辑出来的几种模式,比如正常、45度...
  • 开言: ...为了大家做游戏方便,于是我给这个引擎加了这么一个类。 本系列文章目录: 如何制作一款HTML5 RPG游戏引擎——第一篇,地图类的实现 http://blog.csdn.net/yorhomwang/article/details
  • 本文仅仅是作者最近几天思考网络游戏是什么,该怎么的臆测,我本人最近也仅仅看来...在opengl编程中,一开始绘制图像,比如一个三角形、圆或曲线,这个和游戏中的地图有什么关系? 我们画图的时候,调用的是opengl的
  • Unity小地图制作固定场景

    千次阅读 2015-01-13 09:29:49
    制作小地图的方法很多,...先拿player来举例子,我们可以在player下面建立一个子物体用Sphere这个球体来子物体,这个子物体就是用来代替player在小地图中的显示的。然后把Sphere的属性中的collider这个属性去掉。然
  • 在上课实现场景遮挡效果的基础上如能融合相应的地形系统,那么整个场景才能算有机整体。传统的2D-RPG游戏场景按视角划分可分为横向、纵向与斜向的,本节我将分别向大家介绍如何搭建基于直角坐标系及斜视角的...
  • 记事本保存游戏地图

    2013-05-12 22:45:41
     这个方法是在一个多月前多线程游戏的时候想到的,最初是中南的一位朋友提出来的。最近的博客老是在“炒剩饭”,一些新学的东西也总是来不及作总结,不过觉得这个想法确实不错,所以也才拿出来再与大家探讨一下,...
  • 很多游戏场景,我们都是直接给定一张背景图片作为其游戏背景,图片背景的添加方式和角色的添加方式一样,具体步骤这里就不演示了,大家自己动手试试。 图4-2-1-1 在2D斜视角游戏中,常常将地图区域拆分成...
  •  这种方式需要我们先给出一个角色可以移动的范围,只要游戏角色一超出这个范围地图就开始移动。知道相关的东西后我们就开始编写脚本把,其实我们不用再重新写一遍这个脚本,只要用我在第一篇提供的源码上作修改就...
  • 拖延症晚期的我原本计划趁着周末写个年终总结,但是一直没有什么思路,想来想去也没想到要写啥就胡乱写了这么一个小东西。一直比较痴迷游戏行业,可能我不太适合前端,应该去学C++....首先当然是选择一张背景图,...
  • 一个简单的游戏框架,可快速开始使用python和sfml。 特征 : 自动资源加载器和管理器系统 场景和图层系统 实体,精灵和动画 摄影机 文字和位图字体 平铺的地图加载器(.tmx) 在游戏中调试文字显示 转场 ...
  • cocos2dx也有段时间了,项目也了几个了,总结点东西与大家分享。...一个比较完整的rpg游戏客户端,它肯定由不同的场景(CCScene)比如登录场景,选择角色场景,世界场景;其他场景都可以姑且算是UI,而在世界场景
  • 不过说实话,我没玩过,但看过室友玩过(因为我不喜欢玩游戏,这似乎听起来挺别扭的——一个喜欢研究游戏开发的,却不喜欢玩儿^_^)F话不多说了,在这款(或类似的)端游中,我们经常会看见一个场景:用鼠标控制自己的角
  • Unity 从零开始做游戏

    2021-03-25 20:09:41
    这时场景视图中会出现一个Grid/TileMap GameObject 点击TileMap 看到一堆网格,这就是我们需要作画的位置了 Window ->2D -> Tile palette 调出Tile palette 面板,create new palette 然后将美工给的图拖入到...
  • 一.综述关于地图或者场景漫游导览的生成方式有两种,一种是以代码记录一组摄像头位置然后使用代码牵引摄像头...二.Animation的使用接下来其实就是如何使用Animation做一个导览动画了,我主要讲解地图导览动画的生成技巧

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 150
精华内容 60
关键字:

做一个游戏场景地图