手游摇杆(二)八方向摇杆和移动范围限制

发表于2017-12-13
评论0 4.5k浏览

前面的实现了一版最简单的四方向摇杆,基于此下面来个稍微复杂点的,实现一个八方向摇杆和移动范围的限制。

一、八方向

前面做的四方向摇杆,确认方向是基于不等式区域做的,八方向的会有四条直线方程,处理起来稍微麻烦一点,所以这里换成角度来做。

如图:已知点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点的位置,才能改变移动方向,操作起来就挺累了,基于现有的摇杆,后面再优化一版,实现一个跟随式摇杆来解决这个问题。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引