Cocos2d-js3.3 虚拟摇杆的实现
2015-04-03 09:51
246 查看
虚拟摇杆是在手机格斗游戏中经常看到的一个东西,今天就来了解一下如何在cocos2d-js实现一个虚拟摇杆...
首先,先来看一下这个虚拟摇杆的效果
默认类型(Default):
跟随类型(Follow):
下面,来看一下我实现的这个虚拟摇杆的创建方法:
可以看到,构造函数中传进了6个参数,分别是:
遥控杆的背景(底盘)图、遥控杆图、底盘半径、触摸类型、方向类型和要控制的目标
其中,触摸类型分为:默认(DEFAULT) 和跟随(FOLLOW)
方向类型分为:四方位(上下左右)、八方位(上下左右、左上左下、右上右下)、全方位
然后,我们可以设置摇杆的位置、速度1、速度2、透明度、是否可用、绑定回调函数。
这里解释一下,速度1和速度2,当控杆中心在底盘边缘,目标移动速度为速度2,否则移动速度为速度1
而绑定回调函数,是为了在控杆的角度变化时,能反馈过来,是否需要改变目标的朝向等。
最后,来看一下这个虚拟控杆类
源码下载:点击打开链接
首先,先来看一下这个虚拟摇杆的效果
默认类型(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-js3.3虚拟摇杆的实现
- Cocos2d-x3.2实现虚拟摇杆多点触摸-----沈大海
- Cocos2d-js3.3 模态对话框的实现
- cocos2D 虚拟摇杆Joystick功能实现
- Cocos2d-x3.2实现虚拟摇杆多点触摸
- 「cocos2d-x」虚拟摇杆实现(2)
- 基于Cocos2d-x3.2的虚拟摇杆实现及操控角色移动
- Cocos2d-x3.2实现虚拟摇杆多点触摸
- 「cocos2d-x」虚拟摇杆实现(1)
- ios joystick 虚拟摇杆实现 ( 非 Cocos2d )
- Cocos2d-JS 3.3 模态对话框的实现
- cocos2d-x 之虚拟摇杆实现
- Cocos2d-x虚拟摇杆控制精灵上下左右运动----之游戏开发《赵云要格斗》(1) cocos2dx 3.3移植版
- Cocos2d-x3.2实现虚拟摇杆多点触摸
- 做一个cocos2d-html5的虚拟摇杆
- Cocos2d-x Js Binding 的手动绑定实现
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植3:游戏主菜单界面的实现
- cocos2d-js屏幕任何位置点击开始的实现
- cocos2d-x 街机摇杆 实现
- cocos2d-x jsbinding 资源下载实现