Virtual joystick achieve
In this tutorial we realize a virtual joystick steering control your character and movement.
Operating results are as follows:
Cocos Creator Version: 2.2.0
No reply back public " virtual joystick " to get the full tutorial download address:
Rocker layout implementations
The initial content item file screenshot below:
Create a new scenario called a joystick, textures folder there are two pictures into the background as a rocker and rocker buttons, rocker function code stored in JoyStick.js.
First, we put joystick_panel image onto the hierarchy manager as a child node in the Canvas:
Then joystick_btn image onto the hierarchy manager in it as a child node of joystick_panel (this button will automatically located in the center background):
Then the property inspector provided joystick_btn width and height 60:
Now Scene Editor is shown below:
Rocker is usually located in the bottom left of the screen, so we add a node to joystick_panel Widget component to fix its position:
We set the value of the node distance from the screen to the left and bottom 5% are:
Games run shot as follows:
We see the lower left corner of the FPS information obscured some, we can get rid of it in JoyStick.js with this line of code:
onLoad () {
// hide FPS info
cc.debug.setDisplayStats(false);
},
Run the game again after the JoyStick.js linked to the joystick_panel node:
No information has been found that the FPS.
Rocker function realization
Here sure to use touch event, we first write complete this part of the relevant code:
onLoad () {
// hide FPS info
cc.debug.setDisplayStats(false);
// get joyStickBtn
this.joyStickBtn = this.node.children[0];
// touch event
this.node.on('touchstart', this.onTouchStart, this);
this.node.on('touchmove', this.onTouchMove, this);
this.node.on('touchend', this.onTouchEnd, this);
this.node.on('touchcancel', this.onTouchCancel, this);
},
onDestroy() {
// touch event
this.node.off('touchstart', this.onTouchStart, this);
this.node.off('touchmove', this.onTouchMove, this);
this.node.off('touchend', this.onTouchEnd, this);
this.node.off('touchcancel', this.onTouchCancel, this);
},
In the onLoad method, we also acquired joystick_btn this node and stored in joyStickBtn variable.
下面分别是onTouchStart,onTouchMove,onTouchEnd和onTouchCancel方法实现:
onTouchStart(event) {
// when touch starts, set joyStickBtn's position
let pos = this.node.convertToNodeSpaceAR(event.getLocation());
this.joyStickBtn.setPosition(pos);
},
onTouchMove(event) {
// constantly change joyStickBtn's position
let posDelta = event.getDelta();
this.joyStickBtn.setPosition(this.joyStickBtn.position.add(posDelta));
},
onTouchEnd(event) {
// reset
this.joyStickBtn.setPosition(cc.v2(0, 0));
},
onTouchCancel(event) {
// reset
this.joyStickBtn.setPosition(cc.v2(0, 0));
},
- 在onTouchStart中我们通过event.getLocation()获取触摸坐标,由于这里获取到的是世界坐标,我们需要通过convertToNodeSpaceAR方法将其转换成joystick_panel节点上的坐标。转换好后,将其设置成摇杆按钮的坐标。
- 在onTouchMove中,我们通过event.getDelta()获取手指位移距离(向量),然后加上当前摇杆按钮的坐标就得到了按钮在移动之后的坐标。
- 在onTouchEnd和onTouchCancel中,我们还原按钮位置。
此时运行游戏,我们发现一个待完善的地方,就是按钮它可以移动到摇杆背景外:
为解决这个问题我们在update方法中添加如下代码:
update (dt) {
// get ratio
let len = this.joyStickBtn.position.mag();
let maxLen = this.node.width / 2;
let ratio = len / maxLen;
// restrict joyStickBtn inside the joyStickPanel
if (ratio > 1) {
this.joyStickBtn.setPosition(this.joyStickBtn.position.div(ratio));
}
},
为方便理解以上代码,请看下面这张图:
首先获取摇杆按钮当前所在位置坐标(x1, y1),因为这是一个向量,所以我们可以调用mag()求出该向量的长度len。也就是按钮中心到原点(摇杆背景中心)的直线长度。如果该直线长度大于摇杆背景的半径maxLen(按钮在背景外),那我们就获取超出的比例值ratio,然后让按钮当前的坐标除以它,即x1/ratio和y1/ratio,这样我们其实就得到了按钮在摇杆背景边界上时的x和y坐标。
现在运行游戏你会发现摇杆按钮被限制在了背景中:
用摇杆控制主角
这里的主角我们直接用粒子来代替。在层级管理器中创建一个粒子节点并重命名为player:
接着我们在properties中添加两个属性,一个是用于挂载节点,另一个用于设置主角最大移动速度:
properties: {
player: {
default: null,
type: cc.Node
},
maxSpeed: 0,
},
将player节点拖入,并设置maxSpeed属性值为10:
现在来解决主角的移动问题。首先是移动方向,我们在onLoad方法中新建一个dir变量用于存储主角移动方向:
onLoad () {
...
// Player's move direction
this.dir = cc.v2(0, 0);
...
},
读者如果玩过带摇杆功能的游戏的话,应该都知道摇杆按钮的移动方向就是主角的移动方向。而我们在onTouchMove方法中是知道主角移动后的坐标(向量)的,所以获取方向非常简单:
onTouchMove(event) {
// constantly change joyStickBtn's position
let posDelta = event.getDelta();
this.joyStickBtn.setPosition(this.joyStickBtn.position.add(posDelta));
// get direction
this.dir = this.joyStickBtn.position.normalize();
},
我们这里调用了normalize()让向量归一化(方向不变但长度为1)。
接着在update方法中设置玩家位置:
update (dt) {
...
// move Player
let dis = this.dir.mul(this.maxSpeed * ratio);
this.player.setPosition(this.player.position.add(dis));
},
this.maxSpeed *ratio表示主角移动的速度会根据摇杆按钮所移动的距离来变换。如果摇杆按钮只移动一点,那么主角移动速度就慢;如果摇杆按钮处于摇杆背景的边界处,那么移动速度就达到最大值。
然后我们再将得到的值与this.dir这个方向向量相乘,这样就可以得到朝特定方向的位移大小,最后加上主角当前位置即可。
当然我们还得限制主角移动范围,不能移动到屏幕外边:
update (dt) {
...
// move Player
let dis = this.dir.mul(this.maxSpeed * ratio);
this.player.setPosition(this.player.position.add(dis));
// restrict Player inside the Canvas
if (this.player.x > this.player.parent.width / 2)
this.player.x = this.player.parent.width / 2;
else if (this.player.x < -this.player.parent.width / 2)
this.player.x = -this.player.parent.width /2;
if (this.player.y > this.player.parent.height / 2)
this.player.y = this.player.parent.height / 2;
else if (this.player.y < -this.player.parent.height / 2)
this.player.y = -this.player.parent.height / 2;
},
这里的this.player.parent就是Canvas节点。
运行截图如下:
好,那到这里虚拟摇杆的功能就全部都实现了,希望大家有所收获!
欢迎关注我的微信公众号,发现更多有趣内容: