年糕生存游戏
This commit is contained in:
@@ -70,10 +70,30 @@ function saveTouchMode(mode) {
|
||||
localStorage.setItem('starve_touch_mode', mode)
|
||||
window.dispatchEvent(new CustomEvent('starve-touch-mode', { detail: mode }))
|
||||
}
|
||||
const isMobile = computed(() => typeof window !== 'undefined' && ('ontouchstart' in window || navigator.maxTouchPoints > 0))
|
||||
const isPortrait = ref(false)
|
||||
let portraitMq = null
|
||||
function updateOrientation() {
|
||||
isPortrait.value = isMobile.value && !!portraitMq?.matches
|
||||
}
|
||||
async function enterLandscape() {
|
||||
try {
|
||||
if (document.fullscreenElement) await document.exitFullscreen()
|
||||
await document.documentElement.requestFullscreen?.()
|
||||
} catch (e) {}
|
||||
try {
|
||||
await screen.orientation?.lock?.('landscape')
|
||||
} catch (e) {}
|
||||
updateOrientation()
|
||||
}
|
||||
function openManual() {
|
||||
showManual.value = true
|
||||
if (phase.value === 'playing') gameRef.value?.setPaused?.(true)
|
||||
}
|
||||
function toggleHeadNav() {
|
||||
headShow.value = !headShow.value
|
||||
window.dispatchEvent(new CustomEvent('nlg:starve-nav-toggle'))
|
||||
}
|
||||
function closeManual() {
|
||||
showManual.value = false
|
||||
if (phase.value === 'playing') gameRef.value?.setPaused?.(false)
|
||||
@@ -581,11 +601,17 @@ onMounted(() => {
|
||||
// 宽屏游戏(如饥荒):给 body 打标解除全局 1200px 限宽
|
||||
if (meta?.wide) document.body.classList.add('wide-page')
|
||||
load()
|
||||
portraitMq = window.matchMedia('(orientation: portrait)')
|
||||
window.addEventListener('nlg:open-settings', openSettings)
|
||||
portraitMq.addEventListener('change', updateOrientation)
|
||||
updateOrientation()
|
||||
window.addEventListener('nlg:open-manual', openManual)
|
||||
if (coopable) {
|
||||
window.addEventListener('nlg:pending-join', tryPendingJoin)
|
||||
tryPendingJoin()
|
||||
}
|
||||
portraitMq?.removeEventListener('change', updateOrientation)
|
||||
window.removeEventListener('nlg:open-settings', openSettings)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
document.body.classList.remove('wide-page')
|
||||
@@ -600,8 +626,8 @@ onBeforeUnmount(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="detail" class="play-wrap" :class="{ 'play-fill': meta?.wide }">
|
||||
<button v-if="floatHead" class="head-toggle" @click="headShow = !headShow">
|
||||
<div v-if="detail" class="play-wrap" :class="{ 'play-fill': meta?.wide, 'starve-ui': code === 'starve' }">
|
||||
<button v-if="floatHead" class="head-toggle" @click="toggleHeadNav">
|
||||
{{ headShow ? '▲ 收起' : '☰ 年糕求生' }}
|
||||
</button>
|
||||
<!-- 顶部信息条 -->
|
||||
@@ -985,6 +1011,16 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="floatHead && isPortrait" class="landscape-tip">
|
||||
<div class="landscape-card">
|
||||
<div class="landscape-icon">📱↻</div>
|
||||
<h3>请横屏游玩</h3>
|
||||
<p class="text-dim">年糕求生建议横屏操作,点击按钮自动进入横屏。</p>
|
||||
<button class="btn" @click="enterLandscape">进入横屏</button>
|
||||
<button class="btn btn-ghost" @click="isPortrait = false">暂不</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 未拥有提示 -->
|
||||
@@ -1800,4 +1836,172 @@ onBeforeUnmount(() => {
|
||||
color: var(--primary-2);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* ---- 移动端横屏提示 ---- */
|
||||
.landscape-tip {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 400;
|
||||
background: rgba(8, 5, 4, 0.82);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
}
|
||||
.landscape-card {
|
||||
background: linear-gradient(180deg, #2b2115, #17120b);
|
||||
border: 2px solid #b89a5c;
|
||||
border-radius: 18px;
|
||||
padding: 26px 30px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.landscape-icon {
|
||||
font-size: 54px;
|
||||
}
|
||||
/* ---- 年糕求生 UI:游戏内弹窗/面板统一手绘木纸风格 ---- */
|
||||
.play-wrap.starve-ui .modal-mask {
|
||||
background: rgba(10, 7, 4, 0.62);
|
||||
}
|
||||
.play-wrap.starve-ui .mod-modal,
|
||||
.play-wrap.starve-ui .modal-mask .mod-modal {
|
||||
background: linear-gradient(180deg, #2b2115, #17120b);
|
||||
border: 2px solid #b89a5c;
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
|
||||
color: #f4ead2;
|
||||
}
|
||||
.play-wrap.starve-ui .btn-ghost {
|
||||
background: rgba(42, 32, 18, 0.9);
|
||||
border-color: #6f5b38;
|
||||
color: #f4ead2;
|
||||
}
|
||||
.play-wrap.starve-ui .play-head {
|
||||
background: linear-gradient(180deg, #2b2115, #17120b);
|
||||
border: 2px solid #b89a5c;
|
||||
}
|
||||
.play-wrap.starve-ui .stat-chip {
|
||||
background: rgba(42, 32, 18, 0.9);
|
||||
border-color: #6f5b38;
|
||||
}
|
||||
.play-wrap.starve-ui .head-toggle {
|
||||
background: #2b2115;
|
||||
border-color: #b89a5c;
|
||||
color: #f4ead2;
|
||||
}
|
||||
|
||||
.play-wrap.starve-ui .mod-card {
|
||||
background: rgba(42, 32, 18, 0.9);
|
||||
border-color: #6f5b38;
|
||||
}
|
||||
.play-wrap.starve-ui .mod-card:hover {
|
||||
border-color: #e8bc5a;
|
||||
}
|
||||
.play-wrap.starve-ui .btn {
|
||||
border-radius: 10px;
|
||||
border-color: #b89a5c;
|
||||
background: linear-gradient(180deg, #5a4327, #3a2b17);
|
||||
color: #f4ead2;
|
||||
}
|
||||
.play-wrap.starve-ui .mode-card {
|
||||
background: rgba(42, 32, 18, 0.92);
|
||||
border-color: #6f5b38;
|
||||
border-radius: 14px;
|
||||
}
|
||||
.play-wrap.starve-ui .mode-card:hover {
|
||||
border-color: #e8bc5a;
|
||||
}
|
||||
.play-wrap.starve-ui .join-row,
|
||||
.play-wrap.starve-ui .overlay.room-entry .ov-btns {
|
||||
background: rgba(42, 32, 18, 0.9);
|
||||
border-color: #6f5b38;
|
||||
}
|
||||
.play-wrap.starve-ui .join-input {
|
||||
background: #17120b;
|
||||
border-color: #b89a5c;
|
||||
color: #f4ead2;
|
||||
}
|
||||
.play-wrap.starve-ui .mod-modal h3 {
|
||||
color: #f4ead2;
|
||||
}
|
||||
|
||||
|
||||
/* 更强的饥荒主题:羊皮纸/木箱/铜扣 */
|
||||
.play-wrap.starve-ui .mod-modal,
|
||||
.play-wrap.starve-ui .manual-modal,
|
||||
.play-wrap.starve-ui .settings-modal {
|
||||
background:
|
||||
radial-gradient(circle at 12% 10%, rgba(232, 188, 90, 0.16), transparent 32%),
|
||||
repeating-linear-gradient(90deg, rgba(0,0,0,0.06) 0 2px, transparent 2px 14px),
|
||||
linear-gradient(180deg, #33261a, #17120b);
|
||||
border: 2px solid #b89a5c;
|
||||
box-shadow:
|
||||
inset 0 0 0 4px #241a10,
|
||||
0 12px 40px rgba(0, 0, 0, 0.6);
|
||||
color: #f4ead2;
|
||||
}
|
||||
.play-wrap.starve-ui .mod-modal h3,
|
||||
.play-wrap.starve-ui .manual-modal h3,
|
||||
.play-wrap.starve-ui .settings-modal h3 {
|
||||
font-family: "Ma Shan Zheng", "KaiTi", serif;
|
||||
letter-spacing: 2px;
|
||||
color: #f4d68a;
|
||||
text-shadow: 2px 2px 0 #17120b;
|
||||
}
|
||||
.play-wrap.starve-ui .btn,
|
||||
.play-wrap.starve-ui .btn-ghost {
|
||||
position: relative;
|
||||
font-family: "Ma Shan Zheng", "KaiTi", serif;
|
||||
letter-spacing: 1px;
|
||||
border: 1.6px solid #b89a5c;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.08), transparent 45%),
|
||||
linear-gradient(180deg, #5a4327, #2b1d10);
|
||||
box-shadow: inset 0 0 0 2px #1d1409, 0 3px 0 #0d0906;
|
||||
text-shadow: 1px 1px 0 #0d0906;
|
||||
}
|
||||
.play-wrap.starve-ui .btn:hover,
|
||||
.play-wrap.starve-ui .btn-ghost:hover {
|
||||
border-color: #f0c04a;
|
||||
color: #fff2c0;
|
||||
}
|
||||
.play-wrap.starve-ui .mode-card {
|
||||
background:
|
||||
radial-gradient(circle at 50% 0%, rgba(232, 188, 90, 0.18), transparent 45%),
|
||||
linear-gradient(180deg, #302213, #17120b);
|
||||
box-shadow: inset 0 0 0 3px #1d1409, 0 6px 16px rgba(0,0,0,0.35);
|
||||
font-family: "Ma Shan Zheng", "KaiTi", serif;
|
||||
}
|
||||
.play-wrap.starve-ui .overlay.room-entry .ov-btns,
|
||||
.play-wrap.starve-ui .join-row {
|
||||
background:
|
||||
linear-gradient(180deg, rgba(232,188,90,0.08), transparent),
|
||||
linear-gradient(180deg, #302213, #17120b);
|
||||
box-shadow: inset 0 0 0 2px #1d1409;
|
||||
}
|
||||
.play-wrap.starve-ui .mod-modal,
|
||||
.play-wrap.starve-ui .manual-modal,
|
||||
.play-wrap.starve-ui .settings-modal,
|
||||
.play-wrap.starve-ui .mode-card,
|
||||
.play-wrap.starve-ui .mod-card,
|
||||
.play-wrap.starve-ui .join-row,
|
||||
.play-wrap.starve-ui .join-input {
|
||||
border-radius: 0;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
.play-wrap.starve-ui .bm-close {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
padding: 0;
|
||||
border: 2px solid #b89a5c;
|
||||
background: #2b2115;
|
||||
color: #f4ead2;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
.play-wrap.starve-ui .mod-card-check {
|
||||
border-radius: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user