CocosCreator知识库<一>_JavaScript的虚拟摇杆的通用模板_全方向_八个方向_四个方向

关于CocosCreator知识库<二>_JavaScript的虚拟摇杆的通用模板_全方向_八个方向_四个方向<25/12/2017>

首先,上实际图效果:

全方向

四方向

八方向

先介绍demo层级管理器的分配:


上全所有脚本,如下:

Joystick脚本:

var Common = require('JoystickBar');
var JoystickBG = require('JoystickBG');

cc.Class({
    extends: cc.Component,

    properties: {
        dot: {
            default: null,
            type: cc.Node,
            displayName: '摇杆节点',
        },
        ring: {
            default: null,
            type: JoystickBG,
            displayName: '摇杆背景节点',
        },
        stickX: {
            default: 0,
            displayName: '摇杆X位置',
        },

        stickY: {
            default: 0,
            displayName: '摇杆Y位置',
        },
        touchType: {
            default: Common.TouchType.DEFAULT,
            type: Common.TouchType,
            displayName: '触摸类型',
        },
        directionType: {
            default: Common.DirectionType.ALL,
            type: Common.DirectionType,
            displayName: '方向类型',

        },
        sprite: {
            default: null,
            type: cc.Node,
            displayName: '操控的目标',

        },

        _stickPos: {
            default: null,
            type: cc.Node,
            displayName: '摇杆当前位置',
        },

        _touchLocation: {
            default: null,
            type: cc.Node,
            displayName: '摇杆当前位置',

        }
    },

    onLoad: function () {
        this._createStickSprite();
        //当触摸类型为FOLLOW会在此对圆圈的触摸监听
        if (this.touchType == Common.TouchType.FOLLOW) {
            this._initTouchEvent();
        }
    },

    _createStickSprite: function () {
        //调整摇杆的位置
        this.ring.node.setPosition(this.stickX, this.stickY);
        this.dot.setPosition(this.stickX, this.stickY);
    },

    _initTouchEvent: function () {
        var self = this;

        self.node.on(cc.Node.EventType.TOUCH_START, self._touchStartEvent, self);

        self.node.on(cc.Node.EventType.TOUCH_MOVE, self._touchMoveEvent, self);

        // 触摸在圆圈内离开或在圆圈外离开后,摇杆归位,player速度为0
        self.node.on(cc.Node.EventType.TOUCH_END, self._touchEndEvent, self);
        self.node.on(cc.Node.EventType.TOUCH_CANCEL, self._touchEndEvent, self);


    },

    _touchStartEvent: function (event) {
        // 记录触摸的世界坐标,给touch move使用
        this._touchLocation = event.getLocation();
        var touchPos = this.node.convertToNodeSpaceAR(event.getLocation());
        // 更改摇杆的位置
        this.ring.node.setPosition(touchPos);
        this.dot.setPosition(touchPos);
        // 记录摇杆位置,给touch move使用
        this._stickPos = touchPos;
    },

    _touchMoveEvent: function (event) {

        // 如果touch start位置和touch move相同,禁止移动
        if (this._touchLocation.x == event.getLocation().x && this._touchLocation.y == event.getLocation().y) {
            return false;
        }
        // 以圆圈为锚点获取触摸坐标
        var touchPos = this.ring.node.convertToNodeSpaceAR(event.getLocation());
        var distance = this.ring._getDistance(touchPos, cc.p(0, 0));
        var radius = this.ring.node.width / 2;

        // 由于摇杆的postion是以父节点为锚点,所以定位要加上touch start时的位置
        var posX = this._stickPos.x + touchPos.x;
        var posY = this._stickPos.y + touchPos.y;
        if (radius > distance) {
            this.dot.setPosition(cc.p(posX, posY));
        } else {
            //控杆永远保持在圈内,并在圈内跟随触摸更新角度
            var x = this._stickPos.x + Math.cos(this.ring._getRadian(cc.p(posX, posY))) * radius;
            var y = this._stickPos.y + Math.sin(this.ring._getRadian(cc.p(posX, posY))) * radius;
            this.dot.setPosition(cc.p(x, y));
        }
        //更新角度
        this.ring._getAngle(cc.p(posX, posY));
        //设置实际速度
        this.ring._setSpeed(cc.p(posX, posY));
    },

    _touchEndEvent: function () {
        this.dot.setPosition(this.ring.node.getPosition());
        this.ring._speed = 0;
    },

});
JoystickBar脚本:

module.exports = {

    TouchType : cc.Enum({
        DEFAULT: 0,
        FOLLOW: 1,
    }),

    DirectionType : cc.Enum({
        FOUR: 4,
        EIGHT: 8,
        ALL: 0,
    }),

};
JoystickBG脚本:

var Common = require('JoystickBar');

cc.Class({
    extends: cc.Component,

    properties: {
        dot: {
            default: null,
            type: cc.Node,
            displayName: '摇杆节点',
        },

        _joyCom: {
            default: null,
            displayName: 'joy Node',

        },
        _playerNode: {
            default: null,
            displayName: '被操作的目标Node',
        },

        _angle: {
            default: null,
            displayName: '当前触摸的角度',

        },

        _radian: {
            default: null,
            displayName: '弧度',
        },


        _speed: 0, //实际速度
        _speed1: 1, //一段速度
        _speed2: 2, //二段速度
        _opacity: 0, //透明度
    },


    onLoad: function () {
        // joy下的Joystick组件
        this._joyCom = this.node.parent.getComponent('Joystick');
        // Joystick组件下的player节点
        this._playerNode = this._joyCom.sprite;

        if (this._joyCom.touchType == Common.TouchType.DEFAULT) {
            //对圆圈的触摸监听
            this._initTouchEvent();
        }
    },


    //对圆圈的触摸监听
    _initTouchEvent: function () {
        var self = this;

        self.node.on(cc.Node.EventType.TOUCH_START, this._touchStartEvent, self);

        self.node.on(cc.Node.EventType.TOUCH_MOVE, this._touchMoveEvent, self);

        // 触摸在圆圈内离开或在圆圈外离开后,摇杆归位,player速度为0
        self.node.on(cc.Node.EventType.TOUCH_END, this._touchEndEvent, self);
        self.node.on(cc.Node.EventType.TOUCH_CANCEL, this._touchEndEvent, self);
    },

    //更新移动目标
    update: function (dt) {
        switch (this._joyCom.directionType) {
            case Common.DirectionType.FOUR:
                this._fourDirectionsMove();
                break;
            case Common.DirectionType.EIGHT:
                this._eightDirectionsMove();
                break;
            case Common.DirectionType.ALL:
                this._allDirectionsMove();
                break;
            default:
                break;
        }
    },

    //四个方向移动(上下左右)  
    _fourDirectionsMove: function () {
        if (this._angle > 45 && this._angle < 135) {
            this._playerNode.y += this._speed;
        } else if (this._angle > -135 && this._angle < -45) {
            this._playerNode.y -= this._speed;
        } else if (this._angle < -135 && this._angle > -180 || this._angle > 135 && this._angle < 180) {
            this._playerNode.x -= this._speed;
        } else if (this._angle < 0 && this._angle > -45 || this._angle > 0 && this._angle < 45) {
            this._playerNode.x += this._speed;
        }
    },

    //八个方向移动(上下左右、左上、右上、左下、右下)  
    _eightDirectionsMove: function () {
        if (this._angle > 67.5 && this._angle < 112.5) {
            this._playerNode.y += this._speed;
        } else if (this._angle > -112.5 && this._angle < -67.5) {
            this._playerNode.y -= this._speed;
        } else if (this._angle < -157.5 && this._angle > -180 || this._angle > 157.5 && this._angle < 180) {
            this._playerNode.x -= this._speed;
        } else if (this._angle < 0 && this._angle > -22.5 || this._angle > 0 && this._angle < 22.5) {
            this._playerNode.x += this._speed;
        } else if (this._angle > 112.5 && this._angle < 157.5) {
            this._playerNode.x -= this._speed / 1.414;
            this._playerNode.y += this._speed / 1.414;
        } else if (this._angle > 22.5 && this._angle < 67.5) {
            this._playerNode.x += this._speed / 1.414;
            this._playerNode.y += this._speed / 1.414;
        } else if (this._angle > -157.5 && this._angle < -112.5) {
            this._playerNode.x -= this._speed / 1.414;
            this._playerNode.y -= this._speed / 1.414;
        } else if (this._angle > -67.5 && this._angle < -22.5) {
            this._playerNode.x += this._speed / 1.414;
            this._playerNode.y -= this._speed / 1.414;
        }
    },

    //全方向移动
    _allDirectionsMove: function () {
        this._playerNode.x += Math.cos(this._angle * (Math.PI / 180)) * this._speed;
        this._playerNode.y += Math.sin(this._angle * (Math.PI / 180)) * this._speed;
    },

    //计算两点间的距离并返回
    _getDistance: function (pos1, pos2) {
        return Math.sqrt(Math.pow(pos1.x - pos2.x, 2) +
            Math.pow(pos1.y - pos2.y, 2));
    },

    /*角度/弧度转换
    角度 = 弧度 * 180 / Math.PI
    弧度 = 角度 * Math.PI / 180*/
    //计算弧度并返回
    _getRadian: function (point) {
        this._radian = Math.PI / 180 * this._getAngle(point);
        return this._radian;
    },

    //计算角度并返回
    _getAngle: function (point) {

        var pos = this.node.getPosition();
        this._angle = Math.atan2(point.y - pos.y, point.x - pos.x) * (180 / Math.PI);
        return this._angle;
    },

    //设置实际速度
    _setSpeed: function (point) {
        //触摸点和遥控杆中心的距离
        var distance = this._getDistance(point, this.node.getPosition());

        //如果半径
        if (distance < this._radius) {
            this._speed = this._speed1;
        } else {
            this._speed = this._speed2;
        }
    },

    _touchStartEvent: function (event) {
        // 获取触摸位置的世界坐标转换成圆圈的相对坐标(以圆圈的锚点为基准)
        var touchPos = this.node.convertToNodeSpaceAR(event.getLocation());
        //触摸点与圆圈中心的距离
        var distance = this._getDistance(touchPos, cc.p(0, 0));
        //圆圈半径
        var radius = this.node.width / 2;
        // 记录摇杆位置,给touch move使用
        this._stickPos = touchPos;
        var posX = this.node.getPosition().x + touchPos.x;
        var posY = this.node.getPosition().y + touchPos.y;
        //手指在圆圈内触摸,控杆跟随触摸点
        if (radius > distance) {
            this.dot.setPosition(cc.p(posX, posY));
            return true;
        }
        return false;
    },

    _touchMoveEvent: function (event) {
        var touchPos = this.node.convertToNodeSpaceAR(event.getLocation());
        var distance = this._getDistance(touchPos, cc.p(0, 0));
        var radius = this.node.width / 2;
        // 由于摇杆的postion是以父节点为锚点,所以定位要加上ring和dot当前的位置(stickX,stickY)
        var posX = this.node.getPosition().x + touchPos.x;
        var posY = this.node.getPosition().y + touchPos.y;
        if (radius > distance) {
            this.dot.setPosition(cc.p(posX, posY));
        } else {
            //控杆永远保持在圈内,并在圈内跟随触摸更新角度
            var x = this.node.getPosition().x + Math.cos(this._getRadian(cc.p(posX, posY))) * radius;
            var y = this.node.getPosition().y + Math.sin(this._getRadian(cc.p(posX, posY))) * radius;
            this.dot.setPosition(cc.p(x, y));
        }
        //更新角度
        this._getAngle(cc.p(posX, posY));
        //设置实际速度
        this._setSpeed(cc.p(posX, posY));

    },

    _touchEndEvent: function () {
        this.dot.setPosition(this.node.getPosition());
        this._speed = 0;
    },
});


以上!


猜你喜欢

转载自blog.csdn.net/MaximilianLiu/article/details/78896125