一起来学习用nodejs和CocosCreator开发网络游戏吧(四)--- 可操纵的游戏角色(上)
游戏不可或缺的一个内容就是操作,尤其是对于RPG类型的游戏来讲。所以,对于websocket来说,能够实时体现数据交互的一个重要方法就是可操纵游戏角色在场景中的状态变化,能够让所有连接到服务器的客户端都能够看得到。
这次就先做一个能操作角色的场景吧。
首先,给聊天窗口加一个按钮,可以用来隐藏聊天界面(调整了一下大小,所以加个按钮控制界面以免影响操作)。
加一个UILayout,用来承载所有UI界面上的内容,然后把ChatLayout放到UILayout上,接下来把ChatLayout移出到界面外面,默认一开始为隐藏状态。然后在左下角添加一个button。


然后在代码脚本处,创建一个UIComponent,用来存放所有的UI相关的组件,并创建一个UIController,用来处理对UI层的操作。

在UIController中挂载聊天窗和按钮:
properties: {
isShowChatLayout: false,
chatLayout: {
type: cc.Node,
default: null
},
chatLayoutControlBtnLabel: {
type: cc.Label,
default: null
}
},
添加按钮的事件函数:
chatLayoutControlBtn() {
if(this.isShowChatLayout) {
let move = cc.moveBy(0.5, cc.v2(-this.chatLayout.width, 0));
this.chatLayout.runAction(move);
this.chatLayoutControlBtnLabel.string = "显";
}else {
let move = cc.moveBy(0.5, cc.v2(this.chatLayout.width, 0));
this.chatLayout.runAction(move);
this.chatLayoutControlBtnLabel.string = "隐";
}
this.isShowChatLayout = !this.isShowChatLayout;
}
在这里,用一个moveBy函数来驱动聊天窗口的隐藏和显示动画。
好了,UI层就处理完了。接下来,创建一个游戏场景。
这里我所使用的素材来源于《东方绯想天》的来自东方系列的格斗同人作品(没错我也算是半个东方厨)。
具体的拼场景就是一个体力活了,大家喜欢什么就按照自己手头的素材来整,毕竟为爱做游戏嘛。
在Canvas中新建一个Background的节点,用来布局背景。

运行一下看一眼


看起来还不错的样子,嗯!
然后创建一个游戏角色层RolePlayer,放一个角色进去。(这里使用的人物动作文件,是用龙骨编辑器制作的,有兴趣的话可以自己去研究一下,这里就不多做介绍了)
龙骨动画一共有三个文件,一个是骨骼动画数据 name_ske.json,一个是切图数据 name_tex.json,一个是贴图 name_tex.png。
将name_ske当做节点拖入到场景中,然后把贴图数据拖入到组件栏里,还需要选中默认骨骼和默认动作。


运行一下, 就有了女仆长站在场景中的画面了。

接下来制作一个虚拟摇杆,用来以后控制女仆长在场景中行走。
首先创建一个游戏控制层,ControllerLayer,尺寸填满Canvas。然后在其内部创建一个JoyStick。我的设计时摇杆在手机左边屏幕指定区域内,当手指触碰到屏幕,就在触碰点显示摇杆并操作。所以这个JoyStick给他一个尺寸960 * 800,并左下角对齐到Controller。


然后把准备好的摇杆素材,拖入到JoyStick中


然后,添加一个新的摇杆脚本JoyStick.js

因为摇杆由两部分组成,一个是摇杆背景,一个是摇杆,所以在这里需要两个挂载两个节点
properties: {
joyStickBG: {
type: cc.Node,
default: null
},
joyStickBar: {
type: cc.Node,
default: null
}
},

我们先创建一个公共的工具类Common/Tools.js,因为摇杆操作需要用到一些几何计算,所以抽出公共方法便于通用。

class Tools {
//计算弧度
getRadian(point) {
let radian = Math.atan2(point.y, point.x) ;
return radian ;
}
//计算两点间距离
getDistance(pos1, pos2) {
let x = pos1.x - pos2.x ;
let y = pos1.y - pos2.y ;
return Math.sqrt(x * x + y * y) ;
}
}
export default new Tools() ;
然后去编写对摇杆操作的代码。回到JoyStick.js中,引入工具类。
import Tools from "../Common/Tools";
onLoad () {
//初始化时候,隐藏摇杆
this.joyStickBG.active = false ;
this.joyStickBar.active = false ;
//初始化摇杆触摸状态,以及摇杆初始坐标,和摇杆与摇杆中心距离。
this._joyStart = false ;
this._joyStartPos = null ;
this._radian = -100 ;
//给这个节点添加触摸事件,此为触摸屏幕开始
this.node.on(
'touchstart',
(event) => {
//激活摇杆操作,并显示摇杆和背景
this._joyStart = true ;
this.joyStickBG.active = true ;
this.joyStickBar.active = true ;
//根据触屏位置,设置摇杆位置
this._joyStartPos = this.node.convertToNodeSpaceAR(event.getLocation()) ;
this.joyStickBG.setPosition(this._joyStartPos) ;
this.joyStickBar.setPosition(this._joyStartPos) ;
}
) ;
//给这个节点添加触摸事件,此为鼠标点击屏幕开始
this.node.on(
'mousedown', (event) => {
this._joyStart = true ;
this.joyStickBG.active = true ;
this.joyStickBar.active = true ;
this._joyStartPos = this.node.convertToNodeSpaceAR(event.getLocation()) ;
this.joyStickBG.setPosition(this._joyStartPos) ;
this.joyStickBar.setPosition(this._joyStartPos) ;
}
) ;
//手指在屏幕移动的监听
this.node.on('touchmove', (event) => {
if(this._joyStart) {
//将手指触摸到界面的坐标,转换到摇杆背景上,用来计算摇杆的移动位置
let pos = this.joyStickBG.convertToNodeSpaceAR(event.getLocation()) ;
let radian = this._radian = Tools.getRadian(pos) ;
//将摇杆和背景中心点,最远距离设为50像素,这样手指移动的较远的话,摇杆也不会超出摇杆背景
if(Tools.getDistance(cc.v2(0, 0), pos) <= 50) {
pos.x += this._joyStartPos.x ;
pos.y += this._joyStartPos.y ;
}else {
//手指超出摇杆背景了,就需要用三角函数来计算对应的没有超出背景的坐标,来设置摇杆的位置
pos.x = this._joyStartPos.x + Math.cos(radian) * 50 ;
pos.y = this._joyStartPos.y + Math.sin(radian) * 50 ;
}
this.joyStickBar.setPosition(pos) ;
}
}) ;
//监听鼠标用的
this.node.on('mousemove', (event) => {
if(this._joyStart) {
let pos = this.joyStickBG.convertToNodeSpaceAR(event.getLocation()) ;
let radian = this._radian = Tools.getRadian(pos) ;
//console.log('mouse radian : ' + radian) ;
if(Tools.getDistance(cc.v2(0, 0), pos) <= 50) {
pos.x += this._joyStartPos.x ;
pos.y += this._joyStartPos.y ;
}else {
pos.x = this._joyStartPos.x + Math.cos(radian) * 50 ;
pos.y = this._joyStartPos.y + Math.sin(radian) * 50 ;
}
this.joyStickBar.setPosition(pos) ;
}
}) ;
//离开屏幕,隐藏摇杆并设置初始值。
this.node.on('touchend', (event) => {
if(this._joyStart) {
this._joyStart = false ;
this.joyStickBG.active = false ;
this.joyStickBar.active = false ;
this._radian = -100 ;
}
}) ;
this.node.on('mouseup', (event) => {
if(this._joyStart) {
this._joyStart = false ;
this.joyStickBG.active = false ;
this.joyStickBar.active = false ;
this._radian = -100 ;
}
}) ;
//手指滑动超出了摇杆的控制区域,视同手指离开屏幕
this.node.on('touchcancel', (event) => {
if(this._joyStart) {
this._joyStart = false ;
this.joyStickBG.active = false ;
this.joyStickBar.active = false ;
this._radian = -100 ;
}
}) ;
this.node.on('mouseleave', (event) => {
if(this._joyStart) {
this._joyStart = false ;
this.joyStickBG.active = false ;
this.joyStickBar.active = false ;
this._radian = -100 ;
}
}) ;
},
具体的功能代码中注释也有了说明,这里就不再说了。

然后我们操作摇杆,就可以看到摇杆已经能够按照我们的操作正确表现了。
本次文章先到这里,在下一次中,我们将摇杆操作和控制人物结合在一起。
文章中的代码:
客户端: https://github.com/MythosMa/CocosCreator_ClientTest.git
服务端: https://github.com/MythosMa/NodeJS_GameServerTest.git
浙公网安备 33010602011771号