您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-js3.3 虚拟摇杆的实现

2015-04-03 09:51 246 查看
虚拟摇杆是在手机格斗游戏中经常看到的一个东西,今天就来了解一下如何在cocos2d-js实现一个虚拟摇杆...

首先,先来看一下这个虚拟摇杆的效果

默认类型(Default):






跟随类型(Follow):







下面,来看一下我实现的这个虚拟摇杆的创建方法:

var joystick = new Joystick(res.JoystickBG_png,
res.Joystick_png,
50,
TouchType.DEFAULT,
DirectionType.ALL,
sprite);
joystick.setPosition(cc.p(100, 100));
joystick.setSpeedwithLevel1(1);
joystick.setSpeedwithLevel2(2);
//joystick.setOpacity(128);
//joystick.setEnable(true);
joystick.callback = this.onCallback.bind(this);
this.addChild(joystick, 0, 101);


可以看到,构造函数中传进了6个参数,分别是:

遥控杆的背景(底盘)图、遥控杆图、底盘半径、触摸类型、方向类型和要控制的目标

其中,触摸类型分为:默认(DEFAULT) 和跟随(FOLLOW)

方向类型分为:四方位(上下左右)、八方位(上下左右、左上左下、右上右下)、全方位

然后,我们可以设置摇杆的位置、速度1、速度2、透明度、是否可用、绑定回调函数。

这里解释一下,速度1和速度2,当控杆中心在底盘边缘,目标移动速度为速度2,否则移动速度为速度1

而绑定回调函数,是为了在控杆的角度变化时,能反馈过来,是否需要改变目标的朝向等。

最后,来看一下这个虚拟控杆类

var TouchType = {
DEFAULT: "DEFAULT",
FOLLOW: "FOLLOW"
};

var DirectionType = {
FOUR: "FOUR",
EIGHT: "EIGHT",
ALL: "ALL"
};

var Joystick = cc.Node.extend({
_stick: null,       //控杆
_stickBG: null,     //控杆背景
_listener: null,    //监听器
_radius: 0,         //半径
_angle: null,       //角度
_radian: null,      //弧度
_target: null,      //操控的目标
_speed: 0,          //实际速度
_speed1: 1,         //一段速度
_speed2: 2,         //二段速度
_touchType: null,   //触摸类型
_directionType: null,   //方向类型
_opacity: 0,        //透明度
callback: null,     //回调函数
ctor: function(stickBG, stick, radius, touchType, directionType, target)
{
this._super();
this._target = target;
this._touchType = touchType;
this._directionType = directionType;

//创建摇杆精灵
this._createStickSprite(stickBG, stick, radius);

//初始化触摸事件
this._initTouchEvent();
},

_createStickSprite: function(stickBG, stick, radius)
{
this._radius = radius;

if(this._touchType == TouchType.FOLLOW)
this.setVisible(false);

//摇杆背景精灵
this._stickBG = new cc.Sprite(stickBG);
this._stickBG.setPosition(cc.p(radius, radius));
this.addChild(this._stickBG);

//摇杆精灵
this._stick = new cc.Sprite(stick);
this._stick.setPosition(cc.p(radius, radius));
this.addChild(this._stick);

//根据半径设置缩放比例
var scale = radius / (this._stickBG.getContentSize().width / 2);
this._stickBG.setScale(scale);
this._stick.setScale(scale);

//设置大小
this.setContentSize(this._stickBG.getBoundingBox());

//设置锚点
this.setAnchorPoint(cc.p(0.5, 0.5));
},

_initTouchEvent: function()
{
this._listener = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: false,
onTouchBegan: this.onTouchBegan,
onTouchMoved: this.onTouchMoved,
onTouchEnded: this.onTouchEnded
});

//如果存在相同的对象,将被移除
this.setUserObject(this._listener);

//添加触摸监听
cc.eventManager.addListener(this._listener, this._stickBG);
},

//计算角度并返回
_getAngle: function(point)
{
var pos = this._stickBG.getPosition();
this._angle = Math.atan2(point.y-pos.y, point.x-pos.x) * (180/cc.PI);
return this._angle;
},

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

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

onTouchBegan: function(touch, event)
{
//触摸监听目标
var target = event.getCurrentTarget();

//如果触摸类型为FOLLOW,则摇控杆的位置为触摸位置,触摸开始时候现形
if(target.getParent()._touchType == TouchType.FOLLOW)
{
target.getParent().setPosition(touch.getLocation());
target.getParent().setVisible(true);
target.getParent().scheduleUpdate();
return true;
}
else
{
//把触摸点坐标转换为相对与目标的模型坐标
var touchPos = target.convertToNodeSpace(touch.getLocation());

//点与圆心的距离
var distance = target.getParent()._getDistance(touchPos, target);

//圆的半径
var radius = target.getBoundingBox().width / 2;

//如果点与圆心距离小于圆的半径,返回true
if(radius > distance)
{
target.getParent()._stick.setPosition(touchPos);
target.getParent().scheduleUpdate();
return true;
}
}
return false;
},

onTouchMoved: function(touch, event)
{
//触摸监听目标
var target = event.getCurrentTarget();

//把触摸点坐标转换为相对与目标的模型坐标
var touchPos = target.convertToNodeSpace(touch.getLocation());

//点与圆心的距离
var distance = target.getParent()._getDistance(touchPos, target);

//圆的半径
var radius = target.getBoundingBox().width / 2;

//如果点与圆心距离小于圆的半径,控杆跟随触摸点
if(radius > distance)
{
target.getParent()._stick.setPosition(touchPos);
}
else
{
var x = target.getPositionX() + Math.cos(target.getParent()._getRadian(touchPos)) * target.getParent()._radius;
var y = target.getPositionY() + Math.sin(target.getParent()._getRadian(touchPos)) * target.getParent()._radius;
target.getParent()._stick.setPosition(cc.p(x, y));
}

//更新角度
target.getParent()._getAngle(touchPos);

//设置实际速度
target.getParent()._setSpeed(touchPos);

//更新回调
target.getParent()._updateCallback();
},

onTouchEnded: function(touch, event)
{
//触摸监听目标
var target = event.getCurrentTarget();

//如果触摸类型为FOLLOW,离开触摸后隐藏
if(target.getParent()._touchType == TouchType.FOLLOW)
target.getParent().setVisible(false);

//摇杆恢复位置
target.getParent()._stick.setPosition(target.getPosition());

target.getParent().unscheduleUpdate();
},

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

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

//更新回调
_updateCallback: function()
{
if(this.callback && typeof(this.callback) === "function")
{
this.callback();
}
},

//更新移动目标
update: function(dt)
{
switch (this._directionType)

9e00
{
case DirectionType.FOUR:
this._fourDirectionsMove();
break;
case DirectionType.EIGHT:
this._eightDirectionsMove();
break;
case DirectionType.ALL:
this._allDirectionsMove();
break;
default :
break;
}
},

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

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

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

//设置透明度
setOpacity: function(opacity)
{
this._opacity = opacity;
this._stick.setOpacity(opacity);
this._stickBG.setOpacity(opacity);
},

//设置一段速度
setSpeedwithLevel1: function(speed)
{
this._speed1 = speed;
},

//设置二段速度
setSpeedwithLevel2: function(speed)
{
if(this._speed1 < speed)
{
this._speed2 = speed;
}
else
{
this._speed2 = this._speed2;
}
},

//设置遥控杆开关
setEnable: function(enable)
{
if(this._listener != null)
{
if(enable)
{
cc.eventManager.addListener(this._listener, this._stickBG);
}
else
{
cc.eventManager.removeListener(this._listener);
}
}
},

//获取角度
getAngle: function()
{
return this._angle;
},

onExit: function()
{
this._super();
//移除触摸监听
if(this._listener != null)
{
cc.eventManager.removeListener(this._listener);
}
}
});


源码下载:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  虚拟摇杆 cocos2d-js