<template>
    <jsv-focus-block autoFocus :onAction="actionDefines">
        <Backdrop :control="control1" :ArrayItem="ArrayItem1" :bgImg="bgImg1" :preload_info="preload_info1"
            :TopRef="GameContext.TopRef1" :MidRef="GameContext.MidRef1" :BottomRef="GameContext.BottomRef1"
            :ObstacleRef="GameContext.ObstacleRef1" :style="{ left: 1280 * 1.5 }" :LeftRef="GameContext.LeftRef1"></Backdrop>
        <Backdrop :control="control2" :ArrayItem="ArrayItem2" :bgImg="bgImg2" :preload_info="preload_info2"
            :TopRef="GameContext.TopRef2" :MidRef="GameContext.MidRef2" :BottomRef="GameContext.BottomRef2"
            :ObstacleRef="GameContext.ObstacleRef2" :LeftRef="GameContext.LeftRef2"></Backdrop>
        <Matchman />
        <!-- 游戏结束的弹窗 -->
        <div v-if="isover" :style="{
            width: 460,
            height: 180,
            top: 280,
            left: 440 - 60,
            backgroundColor: 'rgba(255, 255, 255, 0.8)',
            color: '#000000',
            fontSize: 50,
            textAlign: 'center',
            borderRadius: 30
        }">游戏结束
            <div :style="{
                width: 460,
                height: 180,
                top: 90,
                left: 0,
            }">按[OK]键重新开始</div>
        </div>
        <!-- 变速动画 -->
        <div v-if="isshow"
            :style="{ width: 300, height: 50, color: '#FF1213', top: 40, left: 660, fontSize: 40, animation: 'show 2s ease-in-out' }"
            @animationend="AnimEnd">
            当前速度：{{ speed }}</div>
    </jsv-focus-block>
</template>

<script setup>
import {
    JsvActorMoveControl, SpriteController,
    createImpactTracer,
    createImpactCallback,
    createImpactAutoFroze,
} from "jsview"
import { shallowRef, onMounted, watch, onBeforeUnmount, ref, provide, inject } from "vue";
import Matchman from "./Matchman.vue"
import { _formatInfo, jsonObject } from "../Common/MatchmanInfo"
import { randomBg, randomFloor } from "../Common/Random";
import Backdrop from "./Backdrop.vue";
import Sound from "../Common/Sound.js"
import { Context } from "../Common/Context";
/* 火柴人相关变量控制 */

//音频
const PlaySound = new Sound()

//给定ref
let match = shallowRef(null)
provide("match", match)

//火柴人纵向动作控制器
const verticalControl = new JsvActorMoveControl();
provide("verticalControl", verticalControl)

//雪碧图控制器
const spriteController_run = new SpriteController()
provide("spriteController_run", spriteController_run)

const spriteController_jump = new SpriteController()
provide("spriteController_jump", spriteController_jump)

const spriteController_down = new SpriteController()
provide("spriteController_down", spriteController_down)

const spriteController_roll = new SpriteController()
provide("spriteController_roll", spriteController_roll)

const spriteController_fail = new SpriteController()
provide("spriteController_fail", spriteController_fail)

//主碰撞区域的ref
let body = shallowRef(null)
provide("body", body)
//副碰撞区域（顶层碰撞）的ref
let head = shallowRef(null)
provide("head", head)
//初始化跑步状态json
let sprite_info = ref(_formatInfo(jsonObject.run_json));
provide("sprite_info", sprite_info)
//尺寸
const view_size = {
    w: sprite_info.value.maxW,
    h: sprite_info.value.maxH,
};
provide('view_size', view_size)
//切换主副碰撞体的变量
let ischange = shallowRef(null)
provide("ischange", ischange)
//跳跃计数
let num = shallowRef(0)
//跳跃变量
let isjump = shallowRef(false)
provide("isjump", isjump)
//滚动变量
let isroll = shallowRef(false)
provide("isroll", isroll)
//跑动变量
let isrun = shallowRef(true)
provide('isrun', isrun)
//落下变量
let isdown = shallowRef(false)
provide("isdown", isdown)
//结束变量
let isover = shallowRef(false)
provide("isover", isover)

//火柴人动画结束的回调
const onAnimEnd = () => {
    ischange.value = false
    //在滚动状态时不会正常触发，
    if (isjump.value) {
        isroll.value = false
        isdown.value = false
        isrun.value = false
        num.value = 0
    }
    else if (!isover.value) {
        isroll.value = false
        isdown.value = false
        isjump.value = false
        isrun.value = true
        num.value = 0
    } else {
        isover.value = true
        isroll.value = false
        isdown.value = false
        isjump.value = false
        isrun.value = false
    }

}
provide("onAnimEnd", onAnimEnd)


/* 背景图相关 */
//背景控制
const control1 = new JsvActorMoveControl()
const control2 = new JsvActorMoveControl()
//随机数组
let ArrayItem1 = ref([])
let ArrayItem2 = ref([])
//随机背景图片
let bgImg1 = shallowRef('')
let bgImg2 = shallowRef('')
//预加载的背景图
const preload_info1 = shallowRef([]);
const preload_info2 = shallowRef([])

//背景和地板初始化
randomFloor(ArrayItem1)
randomFloor(ArrayItem2)
randomBg(bgImg1, preload_info1)
randomBg(bgImg2, preload_info2)

/* 整体控制 */

//拿取ref给子组件
let GameContext = new Context()

//碰撞管理
let bump = shallowRef(false)
let sensorList = [];

//碰撞即停变量
let viewsAutoFroze = null;

//变化标志
let flag1 = shallowRef(0)
let flag2 = shallowRef(0)

//接收key
let SenceKey = inject("SenceKey")

//地板碰撞函数
const collisionCallback = () => {
    if (!bump.value) {
        if (!isroll.value) {
            isrun.value = true
            isdown.value = false
            isjump.value = false
            isover.value = false
            num.value = 0
        }
    } else {
        isover.value = true
        isroll.value = false
        isrun.value = false
        isdown.value = false
        isjump.value = false
        num.value = 0
    }
}

//边缘坠落函数
const separate = () => {
    if (!isjump.value) {
        verticalControl.throwAlongY(
            0,
            4000,
            { type: "catch", position: 300, direction: 1 },
            () => {
                gameOver()
            }, // 未碰撞落地时，游戏结束
            () => {
                isdown.value = true
                isroll.value = false
                isrun.value = false
                isdown.value = false
                isjump.value = false
                isover.value = false
            } // 到达拐点时调整成落下状态
        );
    }
}

//键盘事件
const onKeyDown = (ev) => {
    if (ev.keyCode == 8 || ev.keyCode == 27 || ev.keyCode == 10000) {
        //交给主页处理，这里不做处理
    }
    else if (isover.value) {
        if (ev.keyCode == 13) {
            SenceKey.value += 1
        } else {
            return true
        }
    } else if (ev.keyCode == 38 && num.value < 2) {
        ischange.value = false
        isroll.value = false
        isjump.value = true
        isdown.value = false
        isrun.value = false
        isover.value = false
        num.value += 1
        verticalControl.throwAlongY(
            -1000,
            2450,
            { type: "catch", position: 300, direction: 1 },
            () => {
                gameOver()
            }, // 未碰撞落地时，游戏结束
            () => {
                isroll.value = false
                isrun.value = false
                isdown.value = true
                isjump.value = false
                isover.value = false
            } // 到达拐点时调整成落下状态
        );
        //跳跃音频
        PlaySound.playJumpSound()

    } else if (ev.keyCode == 40) {
        isroll.value = true
        isrun.value = false
        isdown.value = false
        isjump.value = false
        isover.value = false
        num.value = 0
        ischange.value = true
        spriteController_roll.start()
    }
}
//游戏结束函数
const gameOver = () => {
    spriteController_fail.start()
    isover.value = true
    isrun.value = false
    isdown.value = false
    isjump.value = false
    isroll.value = false
    num.value = 0
    //播放失败音频，停止运动
    PlaySound.playFailSound()
    control1.pause()
    control2.pause()
}

const actionDefines = {
    onKeyDown
}

//速度显示变量
let speed = shallowRef(274)
//控制速度动画div的变量
let isshow = shallowRef(true)

//速度动画结束回调
const AnimEnd = () => {
    isshow.value = false
}

//监听背景图运动 更新随机地板以及变速
watch(flag1, (n, o) => {
    if (n == 1) {
        isshow.value = true
        speed.value = 640
        control1.altStraightSpeed(640, 3000)
        control2.altStraightSpeed(640, 3000)
        ArrayItem1.value = []
        randomFloor(ArrayItem1)
    } else if (n == 2) {
        ArrayItem1.value = []
    }
    bgImg1.value = ''
    randomBg(bgImg1, preload_info1)
})
watch(flag2, (n, o) => {
    if (n == 1) {
        isshow.value = true
        speed.value = 384
        control1.altStraightSpeed(384, 3000)
        control2.altStraightSpeed(384, 3000)
    }
    ArrayItem2.value = []
    randomFloor(ArrayItem2)
    bgImg2.value = ''
    randomBg(bgImg2, preload_info2)
})

/* 在此生命周期进行碰撞体定义操作以及初始化音频 */
onMounted(() => {
    //初始化音频
    PlaySound.initSound()
    //初始落下
    verticalControl.throwAlongY(
        0,
        9000,
        { type: "catch", position: 300, direction: 1 },
        () => {
            gameOver()
        },
        () => {
            isroll.value = false
            isrun.value = false
            isdown.value = true
            isjump.value = false
            isover.value = false
            num.value = 1
        }
    );
    //给定碰撞即停句柄
    viewsAutoFroze = createImpactAutoFroze(
        [match.value.mainDiv], null
    );

    //移动两个背景图
    control1.scrollMoveAlongX(-1280 * 2 * 1.5, 274, 0, () => {
        flag1.value += 1
        return true
    })
    control2.scrollMoveAlongX(-1280 * 1.5, 274, 1280 * 1.5, () => {
        flag2.value += 1
        return true
    })

    //创建碰撞体,因为每个场景只有两个地板,直接为2
    for (let i = 0; i < 2; i++) {

        //第一屏 上层碰撞体，边缘坠落（火柴人主碰撞体）
        sensorList.push(
            createImpactTracer(
                body.value,
                GameContext.TopRef1.value[i],
                createImpactCallback(() => {
                    collisionCallback()
                }, () => {
                    num.value = 1
                    separate()
                }, null),
            )
        );
        //第二屏 上层碰撞体，边缘坠落（火柴人主碰撞体）
        sensorList.push(
            createImpactTracer(
                body.value,
                GameContext.TopRef2.value[i],
                createImpactCallback(() => {
                    collisionCallback()
                }, () => {
                    num.value = 1
                    separate()
                }, null),
            )
        );

        //第一屏 中层碰撞（火柴人主碰撞体）
        sensorList.push(
            createImpactTracer(
                body.value,
                GameContext.MidRef1.value[i],
                createImpactCallback(() => {
                    //此处计算是针对于pc端 320为初始小人top,50和40为上下两个碰撞体大小。20是为视觉效果更好。
                    verticalControl.jumpTo(0, ArrayItem1.value[i].top - 320 - 50 - 40 - 20)
                    collisionCallback()
                }, null),
                viewsAutoFroze
            )
        );
        //第二屏 中层碰撞（火柴人主碰撞体）
        sensorList.push(
            createImpactTracer(
                body.value,
                GameContext.MidRef2.value[i],
                createImpactCallback(() => {
                    verticalControl.jumpTo(0, ArrayItem2.value[i].top - 320 - 50 - 40 - 20)
                    collisionCallback()
                }, null),
                viewsAutoFroze
            )
        );

        //第一屏 下层碰撞体，碰撞即游戏结束(火柴人主碰撞体)
        sensorList.push(
            createImpactTracer(
                body.value,
                GameContext.BottomRef1.value[i],
                createImpactCallback(() => {
                    if (isjump.value) {
                        bump.value = true
                        gameOver()
                    }
                }, null),
                viewsAutoFroze
            )
        );
        // 第一屏 下层碰撞体，碰撞即游戏结束(火柴人副碰撞体)
        sensorList.push(
            createImpactTracer(
                head.value,
                GameContext.BottomRef1.value[i],
                createImpactCallback(() => {
                    if (isjump.value) {
                        bump.value = true
                        gameOver()
                    }
                }, null),
                viewsAutoFroze
            )
        );

        //第二屏 下层碰撞体，碰撞即游戏结束(火柴人主碰撞体)
        sensorList.push(
            createImpactTracer(
                body.value,
                GameContext.BottomRef2.value[i],
                createImpactCallback(() => {
                    if (isjump.value) {
                        bump.value = true
                        gameOver()
                    }
                }, null),
                viewsAutoFroze
            )
        );
        // 第一屏 下层碰撞体，碰撞即游戏结束(火柴人副碰撞体)
        sensorList.push(
            createImpactTracer(
                head.value,
                GameContext.BottomRef2.value[i],
                createImpactCallback(() => {
                    if (isjump.value) {
                        bump.value = true
                        gameOver()
                    }
                }, null),
                viewsAutoFroze
            )
        );
        //第一屏 跳跃碰到左边临界点(火柴人主碰撞体)
        sensorList.push(
            createImpactTracer(
                body.value,
                GameContext.LeftRef1.value[i],
                createImpactCallback(() => {
                    bump.value = true
                    gameOver()
                }, null),
                viewsAutoFroze
            )
        );
        //第一屏 跳跃碰到左边临界点(火柴人副碰撞体)
        sensorList.push(
            createImpactTracer(
                head.value,
                GameContext.LeftRef1.value[i],
                createImpactCallback(() => {
                    bump.value = true
                    gameOver()
                }, null),
                viewsAutoFroze
            )
        );
        //第二屏 跳跃碰到左边临界点(火柴人主碰撞体)
        sensorList.push(
            createImpactTracer(
                body.value,
                GameContext.LeftRef2.value[i],
                createImpactCallback(() => {
                    bump.value = true
                    gameOver()
                }, null),
                viewsAutoFroze
            )
        );
        //第二屏 跳跃碰到左边临界点(火柴人副碰撞体)
        sensorList.push(
            createImpactTracer(
                head.value,
                GameContext.LeftRef2.value[i],
                createImpactCallback(() => {
                    bump.value = true
                    gameOver()
                }, null),
                viewsAutoFroze
            )
        );
    }
    //第一屏 与障碍物相撞（火柴人主碰撞体）
    sensorList.push(
        createImpactTracer(
            body.value,
            GameContext.ObstacleRef1.value[0],
            createImpactCallback(() => {
                bump.value = true
                gameOver()
            }, null),
            viewsAutoFroze
        )
    );
    //第一屏 与障碍物相撞（火柴人副碰撞体）
    sensorList.push(
        createImpactTracer(
            head.value,
            GameContext.ObstacleRef1.value[0],
            createImpactCallback(() => {
                bump.value = true
                gameOver()
            }, null),
            viewsAutoFroze
        )
    );
    //第二屏 与障碍物相撞（火柴人主碰撞体）
    sensorList.push(
        createImpactTracer(
            body.value,
            GameContext.ObstacleRef2.value[0],
            createImpactCallback(() => {
                bump.value = true
                gameOver()
            }, null),
            viewsAutoFroze
        )
    );
    //第二屏 与障碍物相撞（火柴人副碰撞体）
    sensorList.push(
        createImpactTracer(
            head.value,
            GameContext.ObstacleRef2.value[0],
            createImpactCallback(() => {
                bump.value = true
                gameOver()
            }, null),
            viewsAutoFroze
        )
    );

})

/* 重要! 退出后应该释放所有碰撞监听者 */
onBeforeUnmount(() => {
    for (const sensor of sensorList) {
        sensor.Recycle();
    }
    viewsAutoFroze?.Recycle();
    //摧毁音频
    PlaySound.destroy();
})
</script>

<style lang="scss" scoped>
@keyframes show {
    from {
        transform: scale3d(1, 1, 1);
        opacity: 1;
    }

    to {
        transform: scale3d(1.2, 1.2, 1.2);
        opacity: 0;
    }
}
</style>