欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

手游摇杆(一)最简单的四方向摇杆

程序员文章站 2024-03-20 19:25:28
...

摇杆是所有手游中不可或缺的一部分,是最基本的操作方式,下面是用cococ creator实现的一个简单的摇杆,后面将基于此慢慢优化。

一 场景

新建一个场景,拖入三中图片,如图:

手游摇杆(一)最简单的四方向摇杆

分别表示:

  • spPlayer 代表游戏中的角色,通过摇杆控制其移动;
  • spRoker 摇杆的事件影响区域;
  • spRokerCenter 摇杆的中心点。

二 事件监听

为了能控制摇杆,需要监听摇杆的事件,新建一个脚本CompRoker,挂到Canvas上,然后编辑器其内容如下:

cc.Class({
    extends: cc.Component,

    properties: {
        spPlayer: cc.Sprite,
        spRoker: cc.Sprite,
        spRokerCenter: cc.Sprite
    },

    onLoad: function () {
        this.spRoker.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.spRoker.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.spRoker.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.spRoker.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    },

    onTouchStart: function(event) {
        console.log("start ...");
    },

    onTouchMove: function(event) {
        console.log("move ...");
    },

    onTouchEnd: function(event) {
        console.log("end ...");
    },

    onTouchCancel: function(event) {
        console.log("cancel ...");
    },
});

定义了三个变量,分别表示前面说到的三个控件,从cocos中,将其关联到相应的变量,然后运行,可以看到输出,说明事件监听正确。

三 方向控制

首先,我们做一个最简单的额四方向摇杆,控制角色上下左右移动。

如图,当我们触摸点在spRoker的不同区域,分别表示角色向不同的方向移动。

手游摇杆(一)最简单的四方向摇杆

那么,如何来判断触摸点落在那个区域呢,以spRoker的原点为坐标原点的直角坐标系中,对角线的方程即为:
x = y和x = -y,每个区域分别为:

  • 上:x < y 且 x > -y
  • 下:x > y 且 x < -y
  • 左:x < y 且 x < -y
  • 右:x > y 且 x > -y

基于这个原理,添加一个函数getDirection根据传入点来获取方向,如下:

    onTouchStart: function(event) {
        var touchPoint = event.getLocation();
        var pos = this.spRoker.node.convertToNodeSpaceAR(touchPoint);
        var dir = this.getDirection(pos);
        console.log("start ...", dir);
    },

    onTouchMove: function(event) {
        var touchPoint = event.getLocation();
        var pos = this.spRoker.node.convertToNodeSpaceAR(touchPoint);
        var dir = this.getDirection(pos);
        console.log("move ...", dir);
    },

    getDirection: function(pos) {
        var x = pos.x;
        var y = pos.y;
        if (x <= y && x > -y) {
            return cc.v2(0, 1);// 上
        } else if (x >= y && x < -y) {
            return cc.v2(0, -1);// 下
        } else if (x <= y && x < -y) {
            return cc.v2(-1, 0);// 左
        } else {
            return cc.v2(1, 0);// 右
        }
    },

运行,点击摇杆的不同位置,验证获得的方向是否准确。

此外,我们需要需要不断的更新摇杆中心点的位置。

    onTouchStart: function(event) {
        var touchPos = event.getLocation();
        var pos = this.spRoker.node.convertToNodeSpaceAR(touchPos);
        var dir = this.getDirection(pos);
        console.log("start ...", dir);
        this.updateRokerCenterPos(pos);
    },

    onTouchMove: function(event) {
        var touchPos = event.getLocation();
        var pos = this.spRoker.node.convertToNodeSpaceAR(touchPos);
        var dir = this.getDirection(pos);
        console.log("move ...", dir);
        this.updateRokerCenterPos(pos);
    },

    onTouchEnd: function(event) {
        console.log("end ...");
        this.updateRokerCenterPos(cc.v2(0, 0));
    },

    onTouchCancel: function(event) {
         console.log("cancel ...");
        this.updateRokerCenterPos(cc.v2(0, 0));
    },

    updateRokerCenterPos: function(pos) {
        this.spRokerCenter.node.setPosition(pos);
    }

四 控制角色移动

通过上面的几几个步骤,已经得到移动的方向,据此,可以来更新角色的位置,另外为了控制角色移动快慢,在设置一个速度。
最终代码如下:

cc.Class({
    extends: cc.Component,

    properties: {
        spPlayer: cc.Sprite,
        spRoker: cc.Sprite,
        spRokerCenter: cc.Sprite,
        moveSpeed: {
            type: cc.Float,
            default: 1
        }
    },

    onLoad: function () {
        this.spRoker.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.spRoker.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.spRoker.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.spRoker.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    },

    onTouchStart: function(event) {
        var touchPos = event.getLocation();
        var pos = this.spRoker.node.convertToNodeSpaceAR(touchPos);
        var dir = this.getDirection(pos);
        this.moveDir = this.getDirection(pos);
        this.updateRokerCenterPos(pos);
    },

    onTouchMove: function(event) {
        var touchPos = event.getLocation();
        var pos = this.spRoker.node.convertToNodeSpaceAR(touchPos);
        this.moveDir = this.getDirection(pos);
        this.updateRokerCenterPos(pos);
    },

    onTouchEnd: function(event) {
        this.updateRokerCenterPos(cc.v2(0, 0));
        this.moveDir = null;
    },

    onTouchCancel: function(event) {
        this.updateRokerCenterPos(cc.v2(0, 0));
        this.moveDir = null;
    },

    getDirection: function(pos) {
        var x = pos.x;
        var y = pos.y;
        if (x <= y && x > -y) {
            return cc.v2(0, 1);// 上
        } else if (x >= y && x < -y) {
            return cc.v2(0, -1);// 下
        } else if (x <= y && x < -y) {
            return cc.v2(-1, 0);// 左
        } else {
            return cc.v2(1, 0);// 右
        }
    },

    updateRokerCenterPos: function(pos) {
        this.spRokerCenter.node.setPosition(pos);
    },

    updatePlayerPos: function(dir) {
        this.spPlayer.node.x += dir.x * this.moveSpeed;
        this.spPlayer.node.y += dir.y * this.moveSpeed;
    },

    update: function(dt) {
        if (this.moveDir) {
            this.updatePlayerPos(this.moveDir);
        }
    },
});

到这里,就可以看到角色在摇杆的控制下动起来了,当然还有很多细节需要优化的地方,后面再加上。