mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-04-11 15:47:06 +08:00
完善标题界面
This commit is contained in:
parent
0d59b0a5a9
commit
b57fccb723
@ -21,6 +21,7 @@
|
|||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"lz-string": "^1.4.4",
|
"lz-string": "^1.4.4",
|
||||||
"mutate-animate": "^1.0.2",
|
"mutate-animate": "^1.0.2",
|
||||||
|
"three": "^0.149.0",
|
||||||
"vue": "^3.2.45"
|
"vue": "^3.2.45"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -22,6 +22,7 @@ specifiers:
|
|||||||
lz-string: ^1.4.4
|
lz-string: ^1.4.4
|
||||||
mutate-animate: ^1.0.2
|
mutate-animate: ^1.0.2
|
||||||
terser: ^5.16.1
|
terser: ^5.16.1
|
||||||
|
three: ^0.149.0
|
||||||
ts-node: ^10.9.1
|
ts-node: ^10.9.1
|
||||||
typescript: ^4.9.4
|
typescript: ^4.9.4
|
||||||
unplugin-vue-components: ^0.22.12
|
unplugin-vue-components: ^0.22.12
|
||||||
@ -37,6 +38,7 @@ dependencies:
|
|||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
lz-string: 1.4.4
|
lz-string: 1.4.4
|
||||||
mutate-animate: 1.0.2
|
mutate-animate: 1.0.2
|
||||||
|
three: 0.149.0
|
||||||
vue: 3.2.45
|
vue: 3.2.45
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
@ -3164,6 +3166,10 @@ packages:
|
|||||||
source-map-support: 0.5.21
|
source-map-support: 0.5.21
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/three/0.149.0:
|
||||||
|
resolution: {integrity: sha512-tohpUxPDht0qExRLDTM8sjRLc5d9STURNrdnK3w9A+V4pxaTBfKWWT/IqtiLfg23Vfc3Z+ImNfvRw1/0CtxrkQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/through/2.3.8:
|
/through/2.3.8:
|
||||||
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
187
src/ui/start.vue
187
src/ui/start.vue
@ -4,6 +4,18 @@
|
|||||||
<img id="background" src="/project/images/bg.jpg" />
|
<img id="background" src="/project/images/bg.jpg" />
|
||||||
<div id="start-main">
|
<div id="start-main">
|
||||||
<div id="title">人类:开天辟地</div>
|
<div id="title">人类:开天辟地</div>
|
||||||
|
<div id="settings">
|
||||||
|
<div
|
||||||
|
id="sound"
|
||||||
|
class="setting-buttons"
|
||||||
|
:checked="soundChecked"
|
||||||
|
@click="bgm"
|
||||||
|
>
|
||||||
|
<sound-outlined />
|
||||||
|
<span v-if="!soundChecked" id="sound-del"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="background-gradient"></div>
|
||||||
<div id="buttons">
|
<div id="buttons">
|
||||||
<right-outlined id="cursor" />
|
<right-outlined id="cursor" />
|
||||||
<TransitionGroup name="start">
|
<TransitionGroup name="start">
|
||||||
@ -15,28 +27,40 @@
|
|||||||
:selected="selected === v"
|
:selected="selected === v"
|
||||||
:showed="showed"
|
:showed="showed"
|
||||||
@click="clickStartButton(v)"
|
@click="clickStartButton(v)"
|
||||||
|
@mouseenter="
|
||||||
|
movein(
|
||||||
|
$event.target as HTMLElement,
|
||||||
|
toshow.length - i - 1
|
||||||
|
)
|
||||||
|
"
|
||||||
>{{ text[i] }}</span
|
>{{ text[i] }}</span
|
||||||
>
|
>
|
||||||
</TransitionGroup>
|
</TransitionGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="listen" @mousemove="onmove"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, onMounted, onUnmounted, reactive, ref } from 'vue';
|
import { nextTick, onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||||
import { RightOutlined } from '@ant-design/icons-vue';
|
import { RightOutlined, SoundOutlined } from '@ant-design/icons-vue';
|
||||||
import { sleep } from 'mutate-animate';
|
import { sleep } from 'mutate-animate';
|
||||||
|
import { Matrix4 } from '../plugin/webgl/matrix';
|
||||||
|
import { keycode } from '../plugin/utils';
|
||||||
|
import { KeyCode } from '../plugin/keyCodes';
|
||||||
|
|
||||||
let startdiv: HTMLDivElement;
|
let startdiv: HTMLDivElement;
|
||||||
let start: HTMLDivElement;
|
let start: HTMLDivElement;
|
||||||
let main: HTMLDivElement;
|
let main: HTMLDivElement;
|
||||||
let cursor: HTMLElement;
|
let cursor: HTMLElement;
|
||||||
|
let background: HTMLImageElement;
|
||||||
|
|
||||||
let buttons: HTMLSpanElement[] = [];
|
let buttons: HTMLSpanElement[] = [];
|
||||||
|
|
||||||
let played: boolean;
|
let played: boolean;
|
||||||
|
const soundChecked = ref(false);
|
||||||
|
|
||||||
const showed = ref(false);
|
const showed = ref(false);
|
||||||
|
|
||||||
@ -78,11 +102,13 @@ function setCursor(ele: HTMLSpanElement, i: number) {
|
|||||||
cursor.style.left = `${parseFloat(style.left) - 30}px`;
|
cursor.style.left = `${parseFloat(style.left) - 30}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickStartButton(id: string) {
|
async function clickStartButton(id: string) {
|
||||||
core.checkBgm();
|
core.checkBgm();
|
||||||
if (id === 'start-game') showHard();
|
if (id === 'start-game') showHard();
|
||||||
if (id === 'back') setButtonAnimate();
|
if (id === 'back') setButtonAnimate();
|
||||||
if (id === 'easy' || id === 'hard-hard') {
|
if (id === 'easy' || id === 'hard-hard') {
|
||||||
|
start.style.opacity = '0';
|
||||||
|
await sleep(600);
|
||||||
core.startGame(id);
|
core.startGame(id);
|
||||||
}
|
}
|
||||||
if (id === 'load-game') {
|
if (id === 'load-game') {
|
||||||
@ -93,6 +119,61 @@ function clickStartButton(id: string) {
|
|||||||
if (id === 'replay') core.chooseReplayFile();
|
if (id === 'replay') core.chooseReplayFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onmove(e: MouseEvent) {
|
||||||
|
const { offsetX, offsetY } = e;
|
||||||
|
const ele = e.target as HTMLDivElement;
|
||||||
|
const style = getComputedStyle(ele);
|
||||||
|
const width = parseFloat(style.width);
|
||||||
|
const height = parseFloat(style.height);
|
||||||
|
const cx = width / 2;
|
||||||
|
const cy = height / 2;
|
||||||
|
const dx = (offsetX - cx) / cx;
|
||||||
|
const dy = (offsetY - cy) / cy;
|
||||||
|
|
||||||
|
const matrix = new Matrix4();
|
||||||
|
|
||||||
|
matrix.scale(1.2, 1.2, 1);
|
||||||
|
matrix.rotate((dy * 10 * Math.PI) / 180, -(dx * 10 * Math.PI) / 180);
|
||||||
|
const end = Array.from(matrix.transpose()).flat().join(',');
|
||||||
|
background.style.transform = `perspective(${
|
||||||
|
1000 * core.domStyle.scale
|
||||||
|
}px)matrix3d(${end})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function movein(button: HTMLElement, i: number) {
|
||||||
|
setCursor(button, i);
|
||||||
|
selected.value = button.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function keydown(e: KeyboardEvent) {
|
||||||
|
const c = keycode(e.keyCode);
|
||||||
|
const i = toshow.indexOf(selected.value);
|
||||||
|
if (c === KeyCode.DownArrow) {
|
||||||
|
const next = toshow[i - 1];
|
||||||
|
if (!next) return;
|
||||||
|
selected.value = next;
|
||||||
|
setCursor(buttons[toshow.length - i], toshow.length - i);
|
||||||
|
}
|
||||||
|
if (c === KeyCode.UpArrow) {
|
||||||
|
const next = toshow[i + 1];
|
||||||
|
if (!next) return;
|
||||||
|
selected.value = next;
|
||||||
|
setCursor(buttons[toshow.length - i - 2], toshow.length - i - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyup(e: KeyboardEvent) {
|
||||||
|
const c = keycode(e.keyCode);
|
||||||
|
if (c === KeyCode.Enter || c === KeyCode.Space || c === KeyCode.KeyC) {
|
||||||
|
clickStartButton(selected.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bgm() {
|
||||||
|
core.triggerBgm();
|
||||||
|
soundChecked.value = !soundChecked.value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始 -> 难度
|
* 初始 -> 难度
|
||||||
*/
|
*/
|
||||||
@ -122,15 +203,9 @@ async function showHard() {
|
|||||||
.reverse();
|
.reverse();
|
||||||
cursor.style.opacity = '1';
|
cursor.style.opacity = '1';
|
||||||
setCursor(buttons[0], 0);
|
setCursor(buttons[0], 0);
|
||||||
buttons.forEach((v, i) => {
|
|
||||||
v.addEventListener('mouseenter', e => {
|
|
||||||
setCursor(v, i);
|
|
||||||
selected.value = v.id;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
await sleep(600);
|
await sleep(600);
|
||||||
buttons.forEach(v => (v.style.transition = 'color 0.3s ease-out'));
|
buttons.forEach(v => (v.style.transition = 'all 0.3s ease-out'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,17 +242,12 @@ async function setButtonAnimate() {
|
|||||||
.reverse();
|
.reverse();
|
||||||
cursor.style.opacity = '1';
|
cursor.style.opacity = '1';
|
||||||
setCursor(buttons[0], 0);
|
setCursor(buttons[0], 0);
|
||||||
buttons.forEach((v, i) => {
|
buttons.forEach((v, i) => {});
|
||||||
v.addEventListener('mouseenter', e => {
|
|
||||||
setCursor(v, i);
|
|
||||||
selected.value = v.id;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
if (!showed.value) await sleep(1200);
|
if (!showed.value) await sleep(1200);
|
||||||
else await sleep(600);
|
else await sleep(600);
|
||||||
|
|
||||||
buttons.forEach(v => (v.style.transition = 'color 0.3s ease-out'));
|
buttons.forEach(v => (v.style.transition = 'all 0.3s ease-out'));
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@ -186,8 +256,15 @@ onMounted(async () => {
|
|||||||
startdiv = document.getElementById('start-div') as HTMLDivElement;
|
startdiv = document.getElementById('start-div') as HTMLDivElement;
|
||||||
main = document.getElementById('start-main') as HTMLDivElement;
|
main = document.getElementById('start-main') as HTMLDivElement;
|
||||||
start = document.getElementById('start') as HTMLDivElement;
|
start = document.getElementById('start') as HTMLDivElement;
|
||||||
|
background = document.getElementById('background') as HTMLImageElement;
|
||||||
|
|
||||||
core.registerResize('start', resize);
|
core.registerResize('start', resize);
|
||||||
|
document.addEventListener('keydown', keydown);
|
||||||
|
document.addEventListener('keyup', keyup);
|
||||||
resize();
|
resize();
|
||||||
|
|
||||||
|
soundChecked.value = core.musicStatus.bgmStatus;
|
||||||
|
|
||||||
await sleep(50);
|
await sleep(50);
|
||||||
start.style.opacity = '1';
|
start.style.opacity = '1';
|
||||||
if (played) {
|
if (played) {
|
||||||
@ -202,6 +279,8 @@ onMounted(async () => {
|
|||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
core.unregisterResize('start');
|
core.unregisterResize('start');
|
||||||
|
document.removeEventListener('keydown', keydown);
|
||||||
|
document.removeEventListener('keyup', keyup);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -214,12 +293,13 @@ onUnmounted(() => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 1.2s ease-out;
|
transition: opacity 0.6s ease-out;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
#start-div {
|
#start-div {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#background {
|
#background {
|
||||||
@ -228,6 +308,30 @@ onUnmounted(() => {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
filter: sepia(30%) contrast(115%);
|
filter: sepia(30%) contrast(115%);
|
||||||
|
transform: scale(120%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#background-gradient {
|
||||||
|
z-index: 2;
|
||||||
|
position: absolute;
|
||||||
|
width: 200%;
|
||||||
|
height: 100%;
|
||||||
|
left: -100%;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
45deg,
|
||||||
|
transparent 0%,
|
||||||
|
transparent 30%,
|
||||||
|
#000 60%,
|
||||||
|
#000 100%
|
||||||
|
);
|
||||||
|
animation: gradient 4s ease-out 0.5s 1 normal forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
#listen {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#start-main {
|
#start-main {
|
||||||
@ -270,6 +374,7 @@ onUnmounted(() => {
|
|||||||
left: 18%;
|
left: 18%;
|
||||||
bottom: 10%;
|
bottom: 10%;
|
||||||
filter: brightness(120%) contrast(110%);
|
filter: brightness(120%) contrast(110%);
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
#cursor {
|
#cursor {
|
||||||
text-shadow: 2px 2px 3px black;
|
text-shadow: 2px 2px 3px black;
|
||||||
@ -357,6 +462,44 @@ onUnmounted(() => {
|
|||||||
margin-bottom: 16%;
|
margin-bottom: 16%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#settings {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
right: 5%;
|
||||||
|
bottom: 10%;
|
||||||
|
font-size: 1.3em;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
.setting-buttons {
|
||||||
|
margin-left: 40%;
|
||||||
|
color: white;
|
||||||
|
transition: color 0.2s linear;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sound[checked='false'] {
|
||||||
|
color: rgb(255, 43, 43);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sound:hover {
|
||||||
|
color: aqua;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sound[checked='false']:hover {
|
||||||
|
color: rgb(253, 139, 139);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sound-del {
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-bottom: 2px solid #aaa;
|
||||||
|
transform: translate(-85%, -50%) rotate(-45deg) scale(1.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.start-button {
|
.start-button {
|
||||||
@ -365,6 +508,7 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
.start-button[selected='true'] {
|
.start-button[selected='true'] {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
|
transform: scale(115%) translate(7.5%);
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes cursor {
|
@keyframes cursor {
|
||||||
@ -376,6 +520,15 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes gradient {
|
||||||
|
from {
|
||||||
|
left: -100%;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.start-enter-active {
|
.start-enter-active {
|
||||||
transition: all 1.2s ease-out;
|
transition: all 1.2s ease-out;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ export default defineConfig({
|
|||||||
output: {
|
output: {
|
||||||
manualChunks: {
|
manualChunks: {
|
||||||
antdv: ['ant-design-vue', '@ant-design/icons-vue'],
|
antdv: ['ant-design-vue', '@ant-design/icons-vue'],
|
||||||
common: ['lodash', 'axios', 'lz-string', 'chart.js', 'mutate-animate']
|
common: ['lodash', 'axios', 'lz-string', 'chart.js', 'mutate-animate', 'three.js']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user