2015-04-03 09:51
虚拟摇杆是在手机格斗游戏中经常看到的一个东西,今天就来了解一下如何在cocos2d-js实现一个虚拟摇杆...
首先,先来看一下这个虚拟摇杆的效果
默认类型(Default):
跟随类型(Follow):
下面,来看一下我实现的这个虚拟摇杆的创建方法:
- varjoystick=newJoystick(res.JoystickBG_png,
- res.Joystick_png,
- 50,
- TouchType.DEFAULT,108); list-style:decimal-leading-zero outside; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important"> DirectionType.ALL,248)"> 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,101);
可以看到,构造函数中传进了6个参数,分别是:
遥控杆的背景(底盘)图、遥控杆图、底盘半径、触摸类型、方向类型和要控制的目标
其中,触摸类型分为:默认(DEFAULT)和跟随(FOLLOW)
方向类型分为:四方位(上下左右)、八方位(上下左右、左上左下、右上右下)、全方位
然后,我们可以设置摇杆的位置、速度1、速度2、透明度、是否可用、绑定回调函数。
这里解释一下,速度1和速度2,当控杆中心在底盘边缘,目标移动速度为速度2,否则移动速度为速度1
而绑定回调函数,是为了在控杆的角度变化时,能反馈过来,是否需要改变目标的朝向等。
最后,来看一下这个虚拟控杆类
copy
- varTouchType={
- DEFAULT:"DEFAULT",
- FOLLOW:"FOLLOW"
- };
- varDirectionType={
- FOUR:"FOUR",248)"> EIGHT:"EIGHT",108); list-style:decimal-leading-zero outside; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important"> ALL:"ALL"
- varJoystick=cc.Node.extend({
- _stick:null,//控杆
- _stickBG://控杆背景
- _listener://监听器
- _radius:0,//半径
- _angle://角度
- _radian://弧度
- _target://操控的目标
- _speed:0,0); background-color:inherit">//实际速度
- _speed1:1,0); background-color:inherit">//一段速度
- _speed2:2,0); background-color:inherit">//二段速度
- _touchType://触摸类型
- _directionType://方向类型
- _opacity:0,0); background-color:inherit">//透明度
- callback://回调函数
- ctor:function(stickBG,stick,radius,touchType,directionType,target)
- {
- this._super();
- this._target=target;
- this._touchType=touchType;
- this._directionType=directionType;
- //创建摇杆精灵
- this._createStickSprite(stickBG,radius);
- //初始化触摸事件
- this._initTouchEvent();
- },108); list-style:decimal-leading-zero outside; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important"> _createStickSprite:this._radius=radius;
- if(this._touchType==TouchType.FOLLOW)
- this.setVisible(false);
- //摇杆背景精灵
- this._stickBG=newcc.Sprite(stickBG);
- this._stickBG.setPosition(cc.p(radius,radius));
- this.addChild(this._stickBG);
- //摇杆精灵
- this._stick=newcc.Sprite(stick);
- this._stick.setPosition(cc.p(radius,radius));
- this._stick);
- //根据半径设置缩放比例
- varscale=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));
- },248)"> _initTouchEvent:function()
- {
- this._listener=cc.EventListener.create({
- event:cc.EventListener.TOUCH_ONE_BY_ONE,248)"> swallowTouches:false,108); list-style:decimal-leading-zero outside; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important"> onTouchBegan:this.onTouchBegan,248)"> onTouchMoved:this.onTouchMoved,108); list-style:decimal-leading-zero outside; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important"> onTouchEnded:this.onTouchEnded
- });
- //如果存在相同的对象,将被移除
- this.setUserObject(this._listener);
- //添加触摸监听
- cc.eventManager.addListener(this._listener,this._stickBG);
- //计算角度并返回
- _getAngle:function(point)
- varpos=this._stickBG.getPosition();
- this._angle=Math.atan2(point.y-pos.y,point.x-pos.x)*(180/cc.PI);
- returnthis._angle;
- //计算弧度并返回
- _getRadian:this._radian=cc.PI/180*this._getAngle(point);
- this._radian;
- //计算两点间的距离并返回
- _getDistance:function(pos1,pos2)
- returnMath.sqrt(Math.pow(pos1.x-pos2.x,2)+
- Math.pow(pos1.y-pos2.y,2));
- function(touch,event)
- //触摸监听目标
- vartarget=event.getCurrentTarget();
- //如果触摸类型为FOLLOW,则摇控杆的位置为触摸位置,触摸开始时候现形
- if(target.getParent()._touchType==TouchType.FOLLOW)
- target.getParent().setPosition(touch.getLocation());
- target.getParent().setVisible(true);
- target.getParent().scheduleUpdate();
- true;
- }
- else
- //把触摸点坐标转换为相对与目标的模型坐标
- vartouchPos=target.convertToNodeSpace(touch.getLocation());
- //点与圆心的距离
- vardistance=target.getParent()._getDistance(touchPos,target);
- //圆的半径
- varradius=target.getBoundingBox().width/2;
- //如果点与圆心距离小于圆的半径,返回true
- if(radius>distance)
- target.getParent()._stick.setPosition(touchPos);
- }
- false;
- //触摸监听目标
- vartarget=event.getCurrentTarget();
- //把触摸点坐标转换为相对与目标的模型坐标
- vartouchPos=target.convertToNodeSpace(touch.getLocation());
- //点与圆心的距离
- //圆的半径
- varradius=target.getBoundingBox().width/2;
- if(radius>distance)
- target.getParent()._stick.setPosition(touchPos);
- else
- varx=target.getPositionX()+Math.cos(target.getParent()._getRadian(touchPos))*target.getParent()._radius;
- vary=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://如果触摸类型为FOLLOW,离开触摸后隐藏
- if(target.getParent()._touchType==TouchType.FOLLOW)
- target.getParent().setVisible(false);
- //摇杆恢复位置
- target.getParent()._stick.setPosition(target.getPosition());
- target.getParent().unscheduleUpdate();
- _setSpeed://触摸点和遥控杆中心的距离
- vardistance=this._getDistance(point,153); font-weight:bold; background-color:inherit">this._stickBG.getPosition());
- //如果半径
- if(distance<this._radius)
- this._speed=this._speed1;
- this._speed2;
- _updateCallback:function()
- this.callback&&typeof(this.callback)==="function")
- this.callback();
- //更新移动目标
- update:function(dt)
- switch(this._directionType)
- caseDirectionType.FOUR:
- this._fourDirectionsMove();
- break;
- caseDirectionType.EIGHT:
- this._eightDirectionsMove();
- break;
- caseDirectionType.ALL:
- this._allDirectionsMove();
- default:
- //四个方向移动(上下左右)
- _fourDirectionsMove:this._angle>45&&this._angle<135)
- this._target.y+=this._speed;
- elsethis._angle>-135&&this._angle<-45)
- this._target.y-=this._angle<-135&&this._angle>-180||this._angle>135&&this._angle<180)
- this._target.x-=this._angle<0&&this._angle>-45||this._angle>0&&this._angle<45)
- this._target.x+=//八个方向移动(上下左右、左上、右上、左下、右下)
- _eightDirectionsMove:this._angle>67.5&&this._angle<112.5)
- this._speed;
- this._angle>-112.5&&this._angle<-67.5)
- this._angle<-157.5&&this._angle>157.5&&this._angle<180)
- this._angle>-22.5||this._angle<22.5)
- this._angle>112.5&&this._angle<157.5)
- this._speed/1.414;
- this._speed/1.414;
- this._angle>22.5&&this._angle<67.5)
- this._angle>-157.5&&this._angle<-112.5)
- this._angle>-67.5&&this._angle<-22.5)
- //全方向移动
- _allDirectionsMove:this._target.x+=Math.cos(this._angle*(Math.PI/180))*this._target.y+=Math.sin(//设置透明度
- setOpacity:function(opacity)
- this._opacity=opacity;
- this._stick.setOpacity(opacity);
- this._stickBG.setOpacity(opacity);
- //设置一段速度
- setSpeedwithLevel1:function(speed)
- this._speed1=speed;
- //设置二段速度
- setSpeedwithLevel2:this._speed1<speed)
- this._speed2=speed;
- this._speed2=//设置遥控杆开关
- setEnable:function(enable)
- this._listener!=null)
- if(enable)
- cc.eventManager.addListener( cc.eventManager.removeListener(//获取角度
- getAngle:this._angle;
- onExit:this._super();
- //移除触摸监听
- null)
- cc.eventManager.removeListener(this._listener);
- });