123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- import { _decorator, Component, Node, Enum, EventTouch, UITransformComponent, Vec3, view, UITransform, Vec2 } from "cc";
- import { config } from "../config";
- import { DirType } from "../data";
- import { car } from "./car";
- const { ccclass, property } = _decorator;
- //触摸类型
- const TOUCH_TYPE = Enum({
- DEFAULT: 0,//按钮和背景距离不变,背景位置与触碰点一致,不可改变按钮背景位置,按钮背景随着按钮移动而移动,松手后无法恢复到初始位置
- FOLLOW: 1,//按钮和背景距离不变,背景位置与触碰点一致,不可改变按钮背景位置,按钮背景随着按钮移动而移动,松手后恢复到初始位置
- FOLLOW_ALWAYS: 2, //按钮和背景距离不变,背景位置与触碰点一致,可改变按钮背景位置,按钮背景随着按钮移动而移动,松手后恢复到初始位置
- FOLLOW_DOT: 3 //按钮和背景距离可改变,按钮位置与触碰点可不一致,不可改变按钮背景位置,按钮背景不随着按钮移动而移动,松手后恢复到初始位置
- });
- //方向
- const DIRECTION_TYPE = Enum({
- FOUR: 4,
- EIGHT: 8,
- ALL: 0,
- });
- const screenHeight = view.getVisibleSize().height;//屏幕可视范围高度
- @ccclass("Joystick")
- export class Joystick extends Component {
- @property({type: Node, displayName: '摇杆背景节点'})
- public ndRing: Node = null!;
- @property({type: Node, displayName: '摇杆节点'})
- public ndDot: Node = null!;
- @property({type: TOUCH_TYPE, displayName: '触摸类型'})
- public touchType = TOUCH_TYPE.DEFAULT;
- @property({type: DIRECTION_TYPE, displayName: '方向类型'})
- public directionType = DIRECTION_TYPE.ALL;
- @property({displayName: '启动半透明'})
- public isEnableTransparent: boolean = false;
- @property({displayName: '点击跟随'})
- public isFollowStart: boolean = false;
- @property({displayName: '内圈大小'})
- public innerSize: number = 10;
- @property(Node) spr_dun:Node = null;
- public onClickCb: Function = null!;
- public onEndCb: Function = null!;
- public clearFECb: Function = null!;
- public onBeginFECb: Function = null!;
- public onSuccessFECb: Function = null!;
- public isMoving: boolean = false;//是否正在移动
- private mCar:car = null
- private mDir:DirType = DirType.NONE
- public get distanceRate () {
- return this._distanceRate;
- }
- public get angle () {
- return this._angle;
- }
- public set angle (v: number) {
- this._angle = v;
- }
- private _angle: number = 0;//当前的角度
- private _oriRingPos: Vec3 = null!;//圆圈初始位置
- private _targetRingPos: Vec3 = new Vec3();//圆圈背景位置
- private _touchStartLocation: Vec3 = new Vec3();//开始触碰位置
- private _touchMoveLocation: Vec3 = new Vec3();//移动触碰位置
- private _touchEndLocation: Vec3 = new Vec3();//结束触碰位置
- private _isOutInnerSize: Boolean = false;//终点拖动的点是否超出按钮圆圈背景
- private _distanceRate: number = 0; //遥感移动距离比
- private _checkInterval: number = 0.04;//每40ms刷新一次
- private _oldAngle: number = 0;//之前的角度
- private _oldDotPos: number = 0;
- private _currentTime: number = 0;//当前累积时间
- private _oriDotPos: Vec3 = new Vec3();//中间按钮初始坐标
- private _movePos: Vec3 = new Vec3();//移动坐标
- private _curRingPos_1: Vec3 = new Vec3();//当前圆圈坐标
- private _curRingPos_2: Vec3 = new Vec3();//
- private _origin_pos:Vec3 = Vec3.ZERO
- private mCallBack = null;
- start () {
- // Your initialization goes here.
- }
- public init(call_back,car:car)
- {
- this.mCar = car
- this.mCallBack = call_back
- this.node.on(Node.EventType.TOUCH_START, this._touchStartEvent, this);
- this.node.on(Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);
- // 触摸在圆圈内离开或在圆圈外离开后,摇杆归位,player速度为0
- this.node.on(Node.EventType.TOUCH_END, this._touchEndEvent, this);
- this.node.on(Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);
- }
- public unInit(){
- this.node.off(Node.EventType.TOUCH_START, this._touchStartEvent, this);
- this.node.off(Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);
- // 触摸在圆圈内离开或在圆圈外离开后,摇杆归位,player速度为0
- this.node.off(Node.EventType.TOUCH_END, this._touchEndEvent, this);
- this.node.off(Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);
- //重置
- this.isMoving = false;
- this.ndDot.setPosition(this._oriDotPos);
- this._origin_pos = this._oriDotPos
- if (this._oriRingPos) {
- this.ndRing.setPosition(this._oriRingPos);
- }
- }
- private _touchStartEvent (event: EventTouch) {
- // 记录触摸的世界坐标,给touch move使用
- // this.dot.opacity = 255;
- this._targetRingPos = null!;
- let touch = event.getUILocation();
- this._touchStartLocation.set(touch.x, touch.y, 0);
- let touchPos = this.node.getComponent(UITransformComponent)?.convertToNodeSpaceAR(this._touchStartLocation) as Vec3;
- if (!this._oriRingPos) {
- this._oriRingPos = this.ndRing.getPosition().clone();
- }
- // 记录摇杆位置,给touch move使用
- // this._stickPos.set(touchPos);
- this._isOutInnerSize = false;
- if (!this.isFollowStart) {
- touchPos = this.ndRing.getComponent(UITransformComponent)?.convertToNodeSpaceAR(this._touchStartLocation) as Vec3;
- //触摸点与圆圈中心的距离
- let distance = touchPos.length();
- let width = this.ndRing.getComponent(UITransformComponent)?.contentSize.width as number;
- //圆圈半径
- let radius = width / 2;
-
- //手指在圆圈内触摸,控杆跟随触摸点
- if (radius > distance) {
- this.ndDot.setPosition(touchPos);
- this._updateAngle(touchPos);
- return true;
- }
- return false;
- } else {
- //设置遥感可移动范围
- if (this.touchType === TOUCH_TYPE.FOLLOW) {
- touchPos.y = touchPos.y >= -screenHeight/6 ? -screenHeight/6 : touchPos.y;
- }
- this.ndRing.setPosition(touchPos);
- }
- }
- private _touchMoveEvent (event: EventTouch) {
- let touch = event.getUILocation();
- this._touchMoveLocation.set(touch.x, touch.y, 0);
- let touchPos = this.ndRing.getComponent(UITransformComponent)?.convertToNodeSpaceAR(this._touchMoveLocation) as Vec3;
- // if (this.touchType === TOUCH_TYPE.FOLLOW) {
- // let offsetPos = cc.v3(touchPos.x - this._stickPos.x, touchPos.y - this._stickPos.y, 0);
- // touchPos = offsetPos;
- // }
- let dir_type = DirType.NONE
- if(touchPos.x>this.ndDot.position.x){
- dir_type = DirType.RIGHT
- }else if(touchPos.x<this.ndDot.position.x){
- dir_type = DirType.LEFT
- }
- this.mDir = dir_type
- if(this.mDir!=dir_type){
- this._origin_pos = this.ndDot.position
- }
- let distance = touchPos.length();
- if (distance > this.innerSize) {
- this.isMoving = true;
- this._isOutInnerSize = true;
- } else {
- this._isOutInnerSize = false;
- }
- let width = this.ndRing.getComponent(UITransformComponent)?.contentSize.width as number;
- //圆圈半径
- let radius = width / 2;
- let rate = 0;
- // 由于摇杆的postion是以父节点为锚点,所以定位要加上ring和dot当前的位置(stickX,stickY)
- if (radius > distance) {
- rate = Number((distance / radius).toFixed(3));
- this.ndDot.setPosition(touchPos);
- }
- else if (this.touchType !== TOUCH_TYPE.FOLLOW_DOT) {
- rate = 1;
- //控杆永远保持在圈内,并在圈内跟随触摸更新角度
- let radian = Math.atan2(touchPos.y, touchPos.x);
-
- let x = Math.cos(radian) * radius;
- let y = Math.sin(radian) * radius;
- this._movePos.set(x, y, 0);
- if (this.touchType === TOUCH_TYPE.FOLLOW_ALWAYS) {
- this._curRingPos_2.set(touch.x - x, touch.y - y, 0);
- let ringPos = this.node.getComponent(UITransformComponent)?.convertToNodeSpaceAR(this._curRingPos_2) as Vec3;
- this._targetRingPos = ringPos;
- }
- this.ndDot.setPosition(this._movePos);
- } else {
- // 点跟随移动
- this.ndDot.setPosition(touchPos);
- }
- //更新角度
- this._updateAngle(touchPos);
- //更新遥感移动距离百分比
- this._distanceRate = rate;
- }
- private _touchEndEvent (event: EventTouch) {
- if (!this.isMoving) {
- //可以判断为点击
- this.onClickCb && this.onClickCb();
- } else {
- let touch = event.getUILocation();
- this._touchEndLocation.set(touch.x, touch.y, 0);
- let touchPos = this.ndRing.getComponent(UITransformComponent)?.convertToNodeSpaceAR(this._touchEndLocation) as Vec3;
- let isDragToInner = false;
- if (touchPos.length() < this.innerSize) {
- //取消掉
- isDragToInner = true;
-
- this.onEndCb && this.onEndCb(isDragToInner);
-
- } else {
- this.onEndCb && this.onEndCb(isDragToInner);
- }
- }
- this.isMoving = false;
- this.mDir = DirType.NONE
- this.ndDot.setPosition(this._oriDotPos);
- this._origin_pos = this._oriDotPos
- if (this.touchType === TOUCH_TYPE.FOLLOW || this.touchType === TOUCH_TYPE.FOLLOW_ALWAYS || this.touchType === TOUCH_TYPE.FOLLOW_DOT) {
- this._targetRingPos = null!;
- this.ndRing.setPosition(this._oriRingPos);
- }
- }
- private _updateAngle (pos: Vec3) {
- this._angle = Math.round(Math.atan2(pos.y, pos.x) * 180 / Math.PI);
- return this._angle;
- }
- public reset () {
- this.isMoving = false;
- this._origin_pos = this._oriDotPos
- this.ndDot.setPosition(this._oriDotPos);
- }
- public getJoyInfo(){
- this.mCar.setDir(this.mDir)
- console.log("this.mDir",this.mDir)
- this.mCar.setMoveSpeedX(Math.abs(this.ndDot.position.x-this._origin_pos.x)/130*50)
- }
- update (deltaTime: number) {
- // Your update function goes here.
- //设置终终点按钮位置
- // if (this._targetRingPos) {
- // this._curRingPos_1.set(0, 0, 0);
- // Vec3.lerp(this._curRingPos_1, this.ndRing.position, this._targetRingPos, 20 * deltaTime);
- // this.ndRing.setPosition(this._curRingPos_1);
- // }
- this._currentTime += deltaTime;
- if (this._currentTime >= this._checkInterval) {
- this._currentTime = 0;
- if (this.isMoving) {
- if (this.angle !== this._oldAngle) {
- this._oldAngle = this.angle;
- }
- } else {
- this.isMoving = false;
- }
- if(this.mCallBack !=null ){
- this.mCallBack()
- }
- this._oldDotPos = this.ndDot.position.x
- this.getJoyInfo()
- }
- }
- }
|