CocosCreator中,滑屏控制镜头移动

需求

滑动屏幕调整镜头位置。
可以限制只能竖向或横向滑动。

效果

滑动镜头.gif

思路

提供一个SingleTouchCtr,用于发出单指滑屏的相关事件,传出参数为手指触点位置。
CamMoveCtr控制镜头移动:在手指移动时根据手指位置换算出镜头应移动至的目标位置,在update中根据配置的速度使镜头缓动至目标位置。

配置

image.png

代码

SingleTouchCtr.ts

import { _decorator, Component, Node, input, Input, EventTouch, EventTarget } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('SingleTouchCtr')
export class SingleTouchCtr extends Component 
{
    private _touchId: number;
    private static readonly defaultTouchId = -1;

    private _eventTarget: EventTarget;
    public get eventTarget(): EventTarget { return this._eventTarget };

    public static readonly SingleTouchDownEvent: string = 'SingleTouchDownEvent';
    public static readonly SingleTouchMoveEvent: string = 'SingleTouchMoveEvent';
    public static readonly SingleTouchUpEvent: string = 'SingleTouchUpEvent';

    start()
    {
        this.init();
    }

    onDestroy()
    { 
        this.myDestroy();
    }
    
    private init(): void
    {
        input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
        this.resetTouchId();
        this._eventTarget = new EventTarget();
    }
    
    private myDestroy(): void
    { 
        input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
        this._eventTarget = null;
    }

    private resetTouchId(): void
    { 
        this._touchId = SingleTouchCtr.defaultTouchId;
    }
    private hasTouchId(): boolean
    { 
        return this._touchId != SingleTouchCtr.defaultTouchId;
    }

    private onTouchStart(event: EventTouch):void
    { 
        if (!this.hasTouchId())
        {
            this._touchId = event.touch.getID();
            this.eventTarget.emit(SingleTouchCtr.SingleTouchDownEvent, event.touch.getLocation());
        }
    }
    private onTouchMove(event: EventTouch):void
    { 
        if (this._touchId == event.touch.getID())
        {
            this.eventTarget.emit(SingleTouchCtr.SingleTouchMoveEvent, event.touch.getLocation());
        }
    }
    private onTouchEnd(event: EventTouch):void
    { 
        if (this._touchId == event.touch.getID())
        {
            this.eventTarget.emit(SingleTouchCtr.SingleTouchUpEvent, event.touch.getLocation());
            this.resetTouchId();
        }
    }
}

CamMoveCtr.ts

import { _decorator, Component, Node, Vec2, CCFloat, Vec3, Enum, } from 'cc';
import { SingleTouchCtr } from './SingleTouchCtr';
const { ccclass, property } = _decorator;

enum MoveDir
{
    Horizontal,
    Vertical,
    Both,
}

@ccclass('CamMoveCtr')
export class CamMoveCtr extends Component 
{
    @property({ type: Node, visible: true, displayName: '相机Node' })
    private _camNode: Node;
    @property({ type: SingleTouchCtr, visible: true, displayName: '单指触屏控制' })
    private _singleTouchCtr: SingleTouchCtr;

    private _lastTouchPos: Vec2;
    private _targetPos: Vec3;
    @property({ type: CCFloat, visible: true, displayName: '移动速度' })
    private _moveSpeed: number = 10; 
    @property({ type: CCFloat, visible: true, displayName: '距离系数' })
    private _lengthFactor: number = 0.01;
    @property({ type: Enum(MoveDir), visible: true, displayName: '可移动的朝向' })
    private _moveDir: MoveDir = MoveDir.Both;

    start()
    {
        this.init();
    }

    onDestroy()
    { 
        this.myDestroy();
    }

    update(deltaTime: number)
    {
        if (!this._camNode.position.equals(this._targetPos))
        { 
            this._camNode.position = this._camNode.position.lerp(this._targetPos, this._moveSpeed * deltaTime);
        }
    }
    
    private init(): void
    {
        this._singleTouchCtr.eventTarget.on(SingleTouchCtr.SingleTouchDownEvent, this.onTouchDown, this);
        this._singleTouchCtr.eventTarget.on(SingleTouchCtr.SingleTouchMoveEvent, this.onTouchMove, this);
        this._singleTouchCtr.eventTarget.on(SingleTouchCtr.SingleTouchUpEvent, this.onTouchUp, this);

        this.stopMove();
    }
    
    private myDestroy(): void
    { 
        this._singleTouchCtr.eventTarget.off(SingleTouchCtr.SingleTouchDownEvent, this.onTouchDown, this);
        this._singleTouchCtr.eventTarget.off(SingleTouchCtr.SingleTouchMoveEvent, this.onTouchMove, this);
        this._singleTouchCtr.eventTarget.off(SingleTouchCtr.SingleTouchUpEvent, this.onTouchUp, this);
    }

    private onTouchDown(pos: Vec2): void
    { 
        this._lastTouchPos = pos;
        this.stopMove();
    }
    private onTouchMove(pos: Vec2): void
    { 
        let dir: Vec2 = pos.subtract(this._lastTouchPos);
        const length: number = dir.length();
        dir = dir.normalize();
        const posOffset = dir.multiplyScalar(length * this._lengthFactor);
        let tempPos: Vec3 = new Vec3(0, 0, 0);
        Vec3.add(tempPos, this._camNode.position, new Vec3(posOffset.x, posOffset.y, 0));

        if (this._moveDir == MoveDir.Horizontal)
        {
            tempPos.y = this._camNode.position.y;
        }
        else if (this._moveDir == MoveDir.Vertical)
        { 
            tempPos.x = this._camNode.position.x;
        }
        
        this._targetPos = tempPos;

    }
    private onTouchUp(pos: Vec2): void
    { 
        // this.stopMove();
    }

    private stopMove(): void
    { 
        this._targetPos = this._camNode.position;
    }
}

你可能感兴趣的:(CocosCreator中,滑屏控制镜头移动)