const { ccclass, property } = cc._decorator;

@ccclass
export default class Test extends cc.Component {

    private sw: number = 1422 * 2;
    private screenW: number = cc.winSize.width;
    private sh: number = cc.winSize.height;
    private 场景缩放范围: Array<number> = [1, 1.4];
    private 不滚屏范围: Array<number> = [-300, 0];
    private r: number = 32;
    private left: number = this.r;
    private right: number = this.sw - this.r;
    private bottom: number = -this.sh + this.r;
    private top: number = -this.r;
    private v0: number = 10;
    private dirX: -1 | 0 | 1;
    private dirY: -1 | 0 | 1;
    private sqrt2 = Math.sqrt(2);

    private outterContainer: cc.Node;
    private 天空: cc.Node;
    private 中景: cc.Node;
    private container: cc.Node;
    private ball: cc.Node;

    private targetBottomX: number;
    private bottomX: number;

    protected start(): void {
        this.outterContainer = this.node.getChildByName("container");//再套一层用于镜头缩放
        const _container = this.outterContainer.getChildByName("container");//多套一层只是为了内部元素坐标从0开始好计算
        this.天空 = _container.getChildByName("天空");
        this.中景 = _container.getChildByName("中景");
        this.container = _container.getChildByName("container");//主角，敌人，特效都可以直接加到 this.container 里
        this.ball = this.container.getChildByName("ball");
        this.dirX = 0;
        this.dirY = 0;

        _container.x = -this.screenW / 2;
        this.targetBottomX = this.bottomX = 0;

        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, (evt: { keyCode: number }) => {
            switch (evt.keyCode) {
                case cc.macro.KEY.a:
                case cc.macro.KEY.left:
                    this.dirX = -1;
                    break;
                case cc.macro.KEY.w:
                case cc.macro.KEY.up:
                    this.dirY = 1;
                    break;
                case cc.macro.KEY.d:
                case cc.macro.KEY.right:
                    this.dirX = 1;
                    break;
                case cc.macro.KEY.s:
                case cc.macro.KEY.down:
                    this.dirY = -1;
                    break;
            }
        });
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, (evt: { keyCode: number }) => {
            switch (evt.keyCode) {
                case cc.macro.KEY.a:
                case cc.macro.KEY.left:
                    if (this.dirX == -1) this.dirX = 0;
                    break;
                case cc.macro.KEY.w:
                case cc.macro.KEY.up:
                    if (this.dirY == 1) this.dirY = 0;
                    break;
                case cc.macro.KEY.d:
                case cc.macro.KEY.right:
                    if (this.dirX == 1) this.dirX = 0;
                    break;
                case cc.macro.KEY.s:
                case cc.macro.KEY.down:
                    if (this.dirY == -1) this.dirY = 0;
                    break;
            }
        });
    }

    protected update(): void {
        if (this.dirX == 0 || this.dirY == 0) {
            this.ball.x += this.dirX * this.v0;
            this.ball.y += this.dirY * this.v0;
        } else {
            this.ball.x += this.dirX * this.v0 / this.sqrt2;
            this.ball.y += this.dirY * this.v0 / this.sqrt2;
        }
        if (this.dirX < 0) {
            if (this.ball.x <= this.left) {
                this.ball.x = this.left;
            }
        } else {
            if (this.ball.x >= this.right) {
                this.ball.x = this.right;
            }
        }
        if (this.dirY < 0) {
            if (this.ball.y <= this.bottom) {
                this.ball.y = this.bottom;
            }
        } else {
            if (this.ball.y >= this.top) {
                this.ball.y = this.top;
            }
        }

        const x = this.ball.x - this.screenW / 2;
        const heroDx = this.targetBottomX + x;
        if (heroDx < this.不滚屏范围[0]) {
            this.targetBottomX = -x + this.不滚屏范围[0];
        } else if (heroDx > this.不滚屏范围[1]) {
            this.targetBottomX = -x + this.不滚屏范围[1];
        }
        if (this.targetBottomX > 0) {
            this.targetBottomX = 0;
        } else if (this.targetBottomX < this.screenW - this.sw) {
            this.targetBottomX = this.screenW - this.sw;
        }

        const dx = this.targetBottomX - this.bottomX;
        if (dx * dx > 1) {
            this.bottomX += dx * 0.2;
            this.container.x = this.bottomX;
            this.天空.x = this.bottomX * (this.screenW - this.天空.width) / (this.screenW - this.sw);
            this.中景.x = this.bottomX * (this.screenW - this.中景.width) / (this.screenW - this.sw);
        }

        const left = this.bottomX + this.ball.x - this.r - 100 - this.screenW / 2;
        const right = this.bottomX + this.ball.x + this.r + 100 - this.screenW / 2;
        let scale: number = (this.screenW / 2) / Math.max(Math.abs(left), Math.abs(right));
        if (scale < this.场景缩放范围[0]) {
            scale = this.场景缩放范围[0];
        } else if (scale > this.场景缩放范围[1]) {
            scale = this.场景缩放范围[1];
        }
        const dScale = scale - this.outterContainer.scale;
        if (dScale * dScale > 0.0001) {
            this.outterContainer.scale += dScale * 0.2;
        }

    }

}
