<template>
  <div>
    <!-- 测试卡帧 -->
    <div
      class="test"
      :style="{
        animation: 'impact-stop-anim-rotate 1s infinite linear',
      }"
    >
      {{ "测试卡帧" }}
    </div>
    <jsv-focus-block autoFocus :onAction="onActionObj">
      <div :style="{ width: 1280, height: 720, backgroundColor: '#000000' }">
        <!-- 滑块 -->
        <jsv-free-move-actor
          ref="actorRef"
          :top="520 - 30"
          :left="40"
          :width="30"
          :height="30"
        >
          <div
            :style="{
              width: 30,
              height: 30,
              backgroundColor: actorColor,
            }"
          ></div>
        </jsv-free-move-actor>

        <!-- 左边跳板 -->
        <jsv-env-blocker
          :top="520"
          :left="40"
          :width="400"
          :height="5"
          :topGID="1"
          :bottomGID="2"
          :leftGID="3"
          :rightGID="4"
        >
          <div
            :style="{
              width: 400,
              height: 5,
              backgroundColor: 'rgba(255,255,0,1)',
            }"
          ></div>
        </jsv-env-blocker>

        <!-- 中间跳板 -->
        <jsv-env-blocker
          :top="320"
          :left="540"
          :width="200"
          :height="5"
          :topGID="1"
          :bottomGID="2"
          :leftGID="3"
          :rightGID="4"
        >
          <div
            :style="{
              width: 200,
              height: 5,
              backgroundColor: 'rgba(255,255,0,1)',
            }"
          ></div>
        </jsv-env-blocker>

        <!-- 右边跳板 -->
        <jsv-env-blocker
          :top="520"
          :left="840"
          :width="400"
          :height="5"
          :topGID="1"
          :bottomGID="2"
          :leftGID="3"
          :rightGID="4"
        >
          <div
            :style="{
              width: 400,
              height: 5,
              backgroundColor: 'rgba(255,255,0,1)',
            }"
          ></div>
        </jsv-env-blocker>

        <!-- 底板 -->
        <jsv-env-blocker
          :top="620"
          :left="40"
          :width="1200"
          :height="5"
          :topGID="1"
          :bottomGID="2"
          :leftGID="3"
          :rightGID="4"
        >
          <div
            :style="{
              width: 1200,
              height: 5,
              backgroundColor: '#F0FFF0',
            }"
          ></div>
        </jsv-env-blocker>

        <!-- 标题区域 -->
        <div
          :style="{
            textAlign: 'center',
            fontSize: 30,
            lineHeight: 50,
            color: '#ffffff',
            left: 100,
            top: 20,
            width: 1280 - 200,
            height: 50,
            backgroundColor: 'rgba(27,38,151,0.8)',
          }"
        >
          JsView环境下不会穿透模型
        </div>

        <!-- 大多数设备的文字宽度时405, 但某些android 9.0设备上文字宽度是407 -->
        <div
          key="PrecisionGuideText"
          class="text"
          :style="{ top: 528, left: 40, width: 407, height: 40 }"
        >
          JSV下,立刻起跳会精确到边缘
        </div>

        <!-- 提示文字 -->
        <div
          key="GuideText1"
          class="text"
          :style="{ top: 625, left: 370, width: 540, height: 40 }"
        >
          左右键调整跳跃起点，按OK键进行跳跃
        </div>

        <!-- 方向提示 -->
        <div
          key="DirectText"
          class="text"
          :style="{ top: 150, left: 425, width: 430, height: 40 }"
        >
          {{ `当前方向:${direction > 0 ? "->" : "<-"}` }}
        </div>
      </div>
    </jsv-focus-block>
  </div>
</template>

<script setup>
import {
  JsvFreeMoveActor,
  FreeMoveDef,
  JsvEnvBlocker,
  FreeMoveFunc,
} from "jsview";
import { shallowRef, computed, onMounted } from "vue";
let actorControl = null;
let actorRef = shallowRef(null);
const direction = shallowRef(1);
const bodyState = shallowRef(0);
let board = "left";
let jumping = false;
const actEvents = FreeMoveDef.ActEventDefine;

const actorColor = computed(() => {
  switch (bodyState.value) {
    case 0: // 静止
      return "#FF00FF";
    case 1: // 跳起
      return "#FFFF00";
    case 2: // 落下
      return "#00FFFF";
    default:
      return "#FFFFFF";
  }
});
//键盘事件
const procKeyDown = (ev) => {
  if (jumping) {
    // 跳跃中，键盘锁定
    return true;
  }
  switch (ev.keyCode) {
    case 13:
      jumping = true;

      let interactNexus = FreeMoveFunc.newNexus();

      actorControl.run((cmds) => [
        cmds.state().clearAllConditions(),
        cmds
          .condition()
          .onNextTick(1)
          .then([
            () => {
              bodyState.value = 1;
            },
            cmds
              .condition()
              .onHitBlock(1)
              .then([
                () => {
                  console.log("LudlDebug on hit 1");
                  bodyState.value = 0;
                },
                cmds.state().revertWithHitBlock(),
                cmds.action().stopMoving(),
                (a) => {
                  jumping = false;

                  console.log("LudlDebug on hit 1~", a);

                  if (a.yPos <= -200) {
                    board = "middle";
                  } else if (a.yPos <= 0) {
                    if (a.xPos < 440) {
                      board = "left";
                      direction.value = 1;
                    } else {
                      board = "right";
                      direction.value = 0;
                    }
                  } else {
                    reset();
                  }
                },
              ]),
          ]),
      ]);

      if (direction.value) {
        actorControl.run((cmds) => [
          cmds
            .action(0, 0, interactNexus)
            .setSpdAndAccel(7.9, -24, undefined, 1, null, () => {}),
          cmds
            .condition()
            .onNexusEvent(interactNexus, actEvents.SpeedRevertY)
            .then([
              () => {
                bodyState.value = 2;
              },
            ]),
        ]);
      } else {
        actorControl.run((cmds) => [
          cmds
            .action(0, 0, interactNexus)
            .setSpdAndAccel(-7.9, -24, undefined, 1, null, () => {}),
          cmds
            .condition()
            .onNexusEvent(interactNexus, actEvents.SpeedRevertY)
            .then([
              () => {
                bodyState.value = 2;
              },
            ]),
        ]);
      }

      break;
    case 37:
      if (board == "left") {
        actorControl.run((cmds) => [cmds.action().setSpeed(-5, 0)]);
        actorControl.run((cmds) => [
          cmds.state().clearAllConditions(),
          cmds
            .condition()
            .reachPosition(0, undefined)
            .then([cmds.action().stopMoving()]),
        ]);
      } else if (board == "right") {
        actorControl.run((cmds) => [cmds.action().setSpeed(-5, 0)]);
        actorControl.run((cmds) => [
          cmds.state().clearAllConditions(),
          cmds
            .condition()
            .reachPosition(840 - 40, undefined)
            .then([cmds.action().stopMoving()]),
        ]);
      } else if (board == "middle") {
        actorControl.run((cmds) => [cmds.action().setSpeed(-5, 0)]);
        actorControl.run((cmds) => [
          cmds.state().clearAllConditions(),
          cmds
            .condition()
            .reachPosition(540 - 40, undefined)
            .then([cmds.action().stopMoving()]),
        ]);
      }
      break;
    case 39:
      if (board == "left") {
        actorControl.run((cmds) => [cmds.action().setSpeed(5, 0)]);
        actorControl.run((cmds) => [
          cmds.state().clearAllConditions(),
          cmds
            .condition()
            .reachPosition(410 - 40, undefined)
            .then([cmds.action().stopMoving()]),
        ]);
      } else if (board == "right") {
        actorControl.run((cmds) => [cmds.action().setSpeed(5, 0)]);
        actorControl.run((cmds) => [
          cmds.state().clearAllConditions(),
          cmds
            .condition()
            .reachPosition(1240 - 30 - 40, undefined)
            .then([cmds.action().stopMoving()]),
        ]);
      } else if (board == "middle") {
        actorControl.run((cmds) => [cmds.action().setSpeed(5, 0)]);
        actorControl.run((cmds) => [
          cmds.state().clearAllConditions(),
          cmds
            .condition()
            .reachPosition(740 - 40 - 30, undefined)
            .then([cmds.action().stopMoving()]),
        ]);
      }
      break;
  }
};
const procKeyUp = (ev) => {
  if (jumping) {
    // 跳跃中，键盘锁定
    return true;
  }
  switch (ev.keyCode) {
    case 37:
      actorControl.run((cmds) => [cmds.action().stopMoving()]);
      break;
    case 39:
      actorControl.run((cmds) => [cmds.action().stopMoving()]);
      break;

    default:
      break;
  }
};
const onActionObj = {
  onKeyDown: procKeyDown,
  onKeyUp: procKeyUp,
};

//掉到最下面一层的地板则重新定位
const reset = () => {
  board = "left";
  direction.value = 1;
  actorControl.run((cmds) => [cmds.action().teleportTo(0, 0)]);
};
onMounted(() => {
  actorControl = actorRef.value.control;
});
</script>

<style scoped>
.test {
  top: 100;
  left: 50;
  height: 150;
  width: 150;
  background-color: #334455;
  text-align: center;
  line-height: 150;
  font-size: 30;
  color: #ffffff;
  z-index: 999;
}
@keyframes impact-stop-anim-rotate {
  from {
    transform: rotate3d(0, 0, 1, 360deg);
  }
  to {
    transform: rotate3d(0, 0, 1, 0deg);
  }
}
.text {
  font-size: 30;
  color: #73665c;
  line-height: 40;
  white-space: nowrap;
  text-overflow: ellipsis;
  text-align: center;
}
</style>
