手游摇杆(二)八方向摇杆和移动范围限制
发表于2017-12-13
前面的实现了一版最简单的四方向摇杆,基于此下面来个稍微复杂点的,实现一个八方向摇杆和移动范围的限制。
一、八方向
前面做的四方向摇杆,确认方向是基于不等式区域做的,八方向的会有四条直线方程,处理起来稍微麻烦一点,所以这里换成角度来做。
如图:已知点P的坐标为(x, y),求op与x轴正方向的夹角a。
由 tan(a) = y/x 可得 a = atan(y/x),所以由触摸点坐标p,可以得出op与x轴正向夹角。
如图,表示了每个方向的角度范围。
修改getDirection方法如下:
getDirection: function(pos) { var rad = Math.atan2(pos.y, pos.x);// [-PI, PI] if ((rad >= -Math.PI / 8 && rad < 0) || (rad >= 0 && rad < Math.PI / 8)) { return cc.v2(1, 0);// 右 } else if (rad >= Math.PI / 8 && rad < 3 * Math.PI / 8) { return cc.v2(1, 1);// 右上 } else if (rad >= 3 * Math.PI / 8 && rad < 5 * Math.PI / 8) { return cc.v2(0, 1);// 上 } else if (rad >= 5 * Math.PI / 8 && rad < 7 * Math.PI / 8) { return cc.v2(-1, 1);// 左上 } else if ((rad >= 7 * Math.PI / 8 && rad < Math.PI) || (rad >= -Math.PI && rad < -7 * Math.PI / 8)) { return cc.v2(-1, 0);// 左 } else if (rad >= -7 * Math.PI / 8 && rad < -5 * Math.PI / 8) { return cc.v2(-1, -1);// 左下 } else if (rad >= -5 * Math.PI / 8 && rad < -3 * Math.PI / 8) { return cc.v2(0, -1);// 下 } else { return cc.v2(1, -1);// 右下 } },
二、移动范围显示
移动方位包括两个,摇杆中心点和角色。
首先,需要把摇杆中心限制在摇杆的范围内,添加一个变量,表示摇杆可以移动的半径,并让其可以在cocos creator中设置。由触摸点可以求出与x轴正向的夹角,由夹角和最大移动半径就可以得出在这个角度可以移动最大距离。
由以上思路,修改updateRokerCenterPos方法如下:
updateRokerCenterPos: function(pos) { var rad = Math.atan2(pos.y, pos.x); var maxX = Math.cos(rad) * this.maxRadius; var x = maxX > 0 ? Math.min(maxX, pos.x) : Math.max(maxX, pos.x); var maxY = Math.sin(rad) * this.maxRadius; var y = maxY > 0 ? Math.min(maxY, pos.y) : Math.max(maxY, pos.y); this.spRokerCenter.node.setPosition(x, y); },
然后角色的移动范围,必须是在屏幕方位内,所以角色的最大坐标和最小坐标值就是屏幕宽高的一般,因为角色时有宽度的,中心点在锚点,因此还需要减去角色自身宽高的一般,修改updatePlayerPos方法如下:
updatePlayerPos: function(dir) { var size = cc.director.getWinSize(); var x = this.spPlayer.node.x + dir.x * this.moveSpeed; var maxX = size.width * 0.5 - this.spPlayer.node.width * 0.5; var x = x > 0 ? Math.min(x, maxX) : Math.max(x, -maxX); var y = this.spPlayer.node.y + dir.y * this.moveSpeed; var maxY = size.height * 0.5 - this.spPlayer.node.height * 0.5; var y = y > 0 ? Math.min(y, maxY) : Math.max(y, -maxY); this.spPlayer.node.setPosition(x, y); },
现在这就是一个完全可以用的八方向手游摇杆了,但还不是最优的,比如,如图:
现在手指按在A点向左移动,希望改为向右移动,手指就必须至少要移动B点的位置,才能改变移动方向,操作起来就挺累了,基于现有的摇杆,后面再优化一版,实现一个跟随式摇杆来解决这个问题。