博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos UI、地图和关卡文本制作(一)
阅读量:4091 次
发布时间:2019-05-25

本文共 9406 字,大约阅读时间需要 31 分钟。

给宝宝做一个cocos免费游戏

第一章 背景和开发框架介绍

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

第三章 cocs UI、地图和关卡文本制作


请下载上一章代码:https://download.csdn.net/download/sinat_29014637/17854872?spm=1001.2014.3001.5503。本章节上上一章代码基础上开发

一、UI-设置、equipment和item栏

1.设置tab

原理:通过cc.sys.localstorage来设定参数作为设定值(HTML平台清空缓存会被清理),jsb操作json在h5平台不受支持,所以我们项目暂时使用前者。

1.1在Canva节点右击创建节点-创建UI节点-layout,然后在layout上添加一个botton三个editBox

在这里插入图片描述

1.2 添加加载、写入和显示layout的代码

既然是全局的代码,我们放到canvasjs.js上

//1.显示和隐藏setting  showOrHideSetting:function(e){
var setl = cc.find('Canvas').getChildByName('settingLayout'); if(setl){
setl.active = setl.active? false:true; } },//2.显示配置内容 loadSetting:function(e){
var setl = cc.find('Canvas').getChildByName('settingLayout'); var pname = cc.sys.localStorage.getItem('pname'); if(setl && pname){
setl.getChildByName('EditBox1').getComponent(cc.EditBox).string = pname; setl.getChildByName('EditBox1').getChildByName('LABEL').string = 'pname'; //voice //graphic //action } var uinode = cc.find('Canvas').getChildByName('UI'); var userinfo = uinode.getChildByName('playerinfo'); if(userinfo){
userinfo.getChildByName('pname').getComponent(cc.Label).string = pname? pname:'notnamed';},//3.修改配置内容 setSetting:function(e){
var setl = cc.find('Canvas').getChildByName('settingLayout'); var value = setl.getChildByName('EditBox1').getComponent(cc.EditBox).string ; var keys = setl.getChildByName('EditBox1').getChildByName('LABEL').string; cc.sys.localStorage.setItem(keys,value); },

1.3 在场景加载时候加载这个配置内容

onLoad(){
this.loadSetting();//加载setting,显示在右上角头像和三围 }

2.item栏和equipment tab

现在开始做物品和装备栏,上一章我们建立了equipment节点:头身体和四肢+3个技能栏组成和scrollview,因为我们日常都是拖动物品到装备栏,故建议把equipment节点放到scrollview子节点下,方便在同一个js上写触摸拖动、碰撞、碰撞后填入栏位的功能。

2.1加载ITEMS

LOAD和set读写items的代码公用性较强,可以写到canvasjs.js

(1)考虑scrollview导致node层级较多,这里把itemSrollView修改一下,把view节点改为grid,添加layout组件:
在这里插入图片描述
(2)添加后在grid节点添加子节点发现都会自动按照网格排列。所以清空grid的子对象,使用代码读取json和localstorage来添加相应的物品。
这里遇到一个问题,cc.sys.loalstorage是异步读取的,所以读取json时候重复读spriteframe图片,会发现读完spriteframe后,前面已经读取完,故只有最后一个json记录才有spritefram,这里先记录下来后面找找原因,知道解决方法的朋友也请留言告诉我一声
虽然json遇到问题,项目还是要进行,那就替代方案走起:

1)js直接定义一个array变量记录初始的item

const TOOLS = [    {
id:'W1',//唯一值:type+序号 sname:'mainMap',//场景 type:'W',//类型 W-weapon I-ITEMS E-EQUIPMENT S-SKILL技能 name: '工具套装', // 名称 desc: '这是一个工具盒,撬门破解无所不能', // 点击显示介绍 owner:'player',//所在位置(拥有者) eff:'at',//效果 at=attact hp=+-hp mp=+-mp lp=+-lp值 value:'10',//配合eff,eff的值,支持+-号 rotation:'0',//方向 icon: 'icons/png-0007' // 动态加载路径 }, {
id:'I1',//唯一值:type+序号 sname:'mainMap',//场景 type:'I',//类型 W-weapon I-ITEMS E-EQUIPMENT name: '放大镜', desc: '就是个放大镜,啥东西放上去都能变大', owner:'player',//所在位置(拥有者) eff:'at',//效果 at=attact hp=+-hp mp=+-mp lp=+-lp值 value:'10',//配合eff,eff的值,支持+-号 rotation:'0',//方向 icon: 'icons/png-0017' }, {
id:'W2',//唯一值:type+序号 sname:'mainMap',//场景 type:'W',//类型 W-weapon I-ITEMS E-EQUIPMENT name: '剪刀', desc: '这是剪刀,当做武器不知道行不行', owner:'player',//所在位置(拥有者) eff:'at',//效果 at=attact hp=+-hp mp=+-mp lp=+-lp值 value:'20',//配合eff,eff的值,支持+-号 rotation:'0',//方向 icon: 'icons/png-0031' }, {
id:'W3',//唯一值:type+序号 sname:'mainMap',//场景 type:'W',//类型 W-weapon I-ITEMS E-EQUIPMENT name: '卷轴', desc: '这是卷轴', owner:'player',//所在位置(拥有者) eff:'at',//效果 at=attact hp=+-hp mp=+-mp lp=+-lp值 value:'20',//配合eff,eff的值,支持+-号 rotation:'0',//方向 icon: 'icons/卷轴' },];export {
TOOLS}; // import {TOOLS} from './array'; //通过这个函数调用js

2)新建一个itemstab.js来编写加载spriteframe动态icon的代码

// update (dt) {},    setSpriteFrame:function(iconurl){
var self = this; cc.loader.loadRes(iconurl,cc.SpriteFrame,function(err,res){
self.node.getComponent(cc.Sprite).spriteFrame = res; }); },

3)定义一个物品的prefab方便实例化复制然后切换不同的icon来代码不同物品

a.在grid节点——新建节点——sprite,然后添加一个label
在这里插入图片描述
b.给item添加js组件
在这里插入图片描述
c.拖动item节点到资源管理器新建的prefab文件夹(任意都行,方便管理新建了prefab文件夹)
在这里插入图片描述
这样就完成了预制体的制作,后面通过cc.instance()来不断实例化和复制,重复利用

4)在canvasjs.js中编写代码,要加载icon图片时候,直接调用itemstab.js就可以同步加载,解决异步问题

//items和equipte相关代码  loadItems: function (e, customerData) {
var itemsview = cc.find('Canvas').getChildByName('UI').getChildByName('itemScrollView'); if (!itemsview) {
cc.log('找不到itemScrollView'); return; } //customerData:i类-formal items E类-equipment W类-weapon //是否有缓存,有则取缓存的档案,没有取json的初始档案 var items = cc.sys.localStorage.getItem('items'); if (!items) {
//from json var url = 'json/main';//resources/json/.. // cc.loader.loadRes(url, cc.RawAsset, function (err, res) {//异步跟下面异步获取spriteframe有冲突 // if (!err) {
// var rs = res.json.items;//json的obj:mapobj items acts for (var i = 0; i < TOOLS.length; i++) {
if (TOOLS[i].owner == 'player') {
var obj; obj = cc.instantiate(this.item); //(new cc.Node());//this.floor无效 if (obj) {
obj.name = TOOLS[i].id;//TOOLS[i].name; obj.angle = - TOOLS[i].rotation;//方向 // obj.addComponent(cc.Sprite); // obj.parent = itemsview.getChildByName('grid'); //父本 sv-view-content-item // obj.setPosition(cc.v2(rs[i].posx, rs[i].posy)); // cc.loader.loadRes(rs[i].icon,cc.SpriteFrame,function(err,res){
// obj.getComponent(cc.Sprite).spriteFrame = res; // }); var itemjs = obj.getComponent('itemstab'); var icons = TOOLS[i].icon; itemjs.setSpriteFrame(icons);//直接调用item的方法 itemsview.getChildByName('grid').addChild(obj); } } } // } else { cc.log(err); } //异步 往往会执行后面之后再回调函数 // }); } else {
//from localstorage } }, setItems: function (e) {
},

最终效果:比较“斋”,目的达到就好,后面再找时间美化下

在这里插入图片描述

2.2拖动和排序实现

item拖动可以通过touch_move的方法实现,移动时候鼠标变为图片,停止时候执行排序,排列顺序呢目前是按照grad layout标准方法排列:新的放到最后,旧的不变

onLoad() {
var self = this; this.initpos; this.endpos; this.node.on(cc.Node.EventType.TOUCH_START, function (e) {
this.initpos = e.getLocation; }.bind(this), this); this.node.on(cc.Node.EventType.TOUCH_MOVE, function (e) {
var dis = e.getDelta(); // cc.log(dis.x +':'+ dis.y); if(self.node.parent.parent.name == 'equipment'){
return;} var dy = self.node.position.y + dis.y; var dx = self.node.position.x + dis.x; var isv = cc.find('Canvas').getChildByName('UI').getChildByName('itemScrollView'); // cc.log(self.node.parent);//需要添加不等于装备 self.node.parent = isv;//grid 里面是不能随便拖动的,转到别的父本 self.node.setPosition(cc.v2(dx, dy)); }.bind(this), this); this.node.on(cc.Node.EventType.TOUCH_END, function (e) {
}.bind(this), this); this.node.on(cc.Node.EventType.TOUCH_CANCEL, function (e) {
// self.node.removeFromParent();//移走 //没有移到其他栏目则回来原来grid if (self.node.parent == cc.find('Canvas').getChildByName('UI').getChildByName('itemScrollView')) {
self.node.parent = cc.find('Canvas').getChildByName('UI').getChildByName('itemScrollView').getChildByName('grid'); } }.bind(this), this); },

2.3 equipment-碰撞实现加入栏位

而考虑交互事件较多、冒泡事件传递较复杂,我们需要在itemstab.js脚本文件来编写items的拖拉筛选等代码

原理剖析:首先我们是拖动item,故应该在每个item启用touch方法;拖动后放到装备栏或者使用按钮,有两种方法实现:a.判断坐标是否落入 b.直接使用碰撞,碰撞后从物品栏去掉,加载到具体装备栏。我选择b资源不用重复加载,换一个副本即可。另外我们需要把装备类item节点命名为E+名称,这样就可以简单判断。

2.3.1为equipment栏添加碰撞组件

在这里插入图片描述

2.3.2在itemstab.js添加碰撞检测代码

(1)开启碰撞

onLoad() {
//开启碰撞检测 var collider = cc.director.getCollisionManager(); collider.enabled = true; // collider.enabledDebugDraw = true; //debug // collider.enabledDrawBoundingBox = true; ...

检查碰撞组:UI之间还是要碰撞(也可以单独给item分配新的组)

在这里插入图片描述

(2)检测碰撞时候改变副本为具体的equipment栏

//碰撞检测    onCollisionEnter:function(other,self){
// cc.log('ot:'+other.node.name); // cc.log('se:'+self.node.name.substr(0,1)); if(self.node.name.substr(0,1) != 'W' && self.node.name.substr(0,1) != 'S' && self.node.name.substr(0,1) != 'E'){
return;} var i = 0; switch(other.node.name){
//对应equipment节点所有的装备栏 case 'head':i =1;break; case 'body':i =2;break; case 'lhand':i =3;break; case 'rhand':i =4;break; case 'lfoot':i =5;break; case 'rfoot':i =6;break; case 'skill1':i =7;break; case 'skill2':i =8;break; case 'skill3':i =9;break; // case '':break; // case '':break; // case '':break; } if(i!= 0 && other.node.children.length<1){
self.node.parent = other.node ; // cc.log(other.node.name); self.node.setPosition(cc.v2(0,0)); } },

总结

有点复杂,花了较长时间只做了item栏和装备栏的互动,后面还要做数据运算等,地图和关卡文本放到(二)文章处理吧。

这里提供物品栏制作的文章供参考,非常感谢博主对我们这些菜鸟的指引:
https://blog.csdn.net/La_vie_est_belle/article/details/105147837

你可能感兴趣的文章
(python版)《剑指Offer》JZ32:把数组排成最小的数
查看>>
(python版)《剑指Offer》JZ02:替换空格
查看>>
JSP/Servlet——MVC设计模式
查看>>
使用JSTL
查看>>
Java 8新特性:Stream API
查看>>
管理用户状态——Cookie与Session
查看>>
最受欢迎的前端框架Bootstrap 入门
查看>>
JavaScript编程简介:DOM、AJAX与Chrome调试器
查看>>
通过Maven管理项目依赖
查看>>
通过Spring Boot三分钟创建Spring Web项目
查看>>
Spring的IoC(依赖注入)原理
查看>>
Guava快速入门
查看>>
Java编程基础:static的用法
查看>>
Java编程基础:抽象类和接口
查看>>
Java编程基础:异常处理
查看>>
Java编程基础:了解面向对象
查看>>
新一代Java模板引擎Thymeleaf
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
Spring Boot构建简单的微博应用
查看>>
Spring处理表单提交
查看>>