Files
DFJ/mobile_main_menu_1.html
2025-09-10 18:13:28 +08:00

1203 lines
45 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>飞机大战 - 移动端高可用版</title>
<meta name="theme-color" content="#0f1419">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<style>
:root {
/* 深空科技主题色彩系统 */
--primary-color: #6366f1;
--primary-light: #8b5cf6;
--primary-dark: #4f46e5;
--secondary-color: #10b981;
--secondary-light: #34d399;
--accent-color: #f59e0b;
--accent-light: #fbbf24;
--danger-color: #ef4444;
/* 移动端优化背景色系 */
--bg-primary: #0f1419;
--bg-secondary: #1a1d29;
--bg-tertiary: #252837;
--bg-elevated: #2d3142;
/* 高对比度边框色系 */
--border-primary: #3d4159;
--border-secondary: #4a5073;
--border-highlight: #6366f1;
/* 文字色系 */
--text-primary: #ffffff;
--text-secondary: #b4b7c9;
--text-tertiary: #9ca3af;
--text-disabled: #6b7280;
/* 移动端触摸区域尺寸 */
--touch-target-min: 44px;
--safe-area-padding: 20px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
overflow-x: hidden;
-webkit-text-size-adjust: 100%;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Microsoft YaHei UI", sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
touch-action: manipulation;
}
/* PWA 支持的安全区域适配 */
.safe-area {
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
}
/* 动态背景星空效果 */
.background-constellation {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: -1;
}
.star {
position: absolute;
width: 2px;
height: 2px;
background: var(--primary-color);
border-radius: 50%;
opacity: 0.6;
animation: twinkle 3s infinite ease-in-out;
}
.star:nth-child(2n) {
background: var(--accent-color);
animation-delay: 1s;
}
.star:nth-child(3n) {
background: var(--secondary-color);
animation-delay: 2s;
}
@keyframes twinkle {
0%, 100% { opacity: 0.3; transform: scale(0.8); }
50% { opacity: 1; transform: scale(1.2); }
}
/* 主容器 - 全屏布局 */
.app-container {
display: flex;
flex-direction: column;
min-height: 100vh;
position: relative;
z-index: 1;
}
/* 状态栏 */
.status-bar {
background: rgba(26, 29, 41, 0.95);
backdrop-filter: blur(20px);
padding: 8px var(--safe-area-padding);
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
color: var(--text-tertiary);
position: sticky;
top: 0;
z-index: 100;
}
.network-status {
display: flex;
align-items: center;
gap: 6px;
}
.connection-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--secondary-color);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.4; transform: scale(1.3); }
}
/* 主内容区域 */
.main-content {
flex: 1;
display: flex;
flex-direction: column;
padding: var(--safe-area-padding);
justify-content: center;
align-items: center;
text-align: center;
position: relative;
}
/* 游戏Logo区域 */
.game-header {
margin-bottom: 40px;
}
.game-logo {
font-size: clamp(28px, 8vw, 36px);
font-weight: 800;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-light) 50%, var(--accent-color) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 12px;
letter-spacing: 2px;
animation: logoGlow 4s ease-in-out infinite alternate;
}
@keyframes logoGlow {
0% { filter: drop-shadow(0 0 5px rgba(99, 102, 241, 0.3)); }
100% { filter: drop-shadow(0 0 25px rgba(139, 92, 246, 0.6)); }
}
.game-subtitle {
font-size: 14px;
color: var(--text-secondary);
font-weight: 500;
letter-spacing: 1px;
}
/* 游戏特色展示 */
.game-preview {
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 16px;
padding: 24px;
margin: 30px 0;
max-width: 340px;
width: 100%;
position: relative;
overflow: hidden;
}
.game-preview::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
animation: shimmer 3s infinite;
}
@keyframes shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
.preview-title {
font-size: 16px;
font-weight: bold;
color: var(--text-primary);
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.plane-icon {
font-size: 18px;
color: var(--accent-color);
}
/* 十字形飞机演示 */
.cross-plane-display {
font-family: 'Courier New', monospace;
font-size: 12px;
line-height: 1.1;
background: var(--bg-primary);
border: 1px solid var(--border-secondary);
border-radius: 12px;
padding: 16px;
margin: 16px 0;
position: relative;
}
.plane-structure {
color: var(--text-primary);
text-align: center;
position: relative;
z-index: 2;
}
.plane-head { color: var(--accent-color); }
.plane-wing { color: var(--primary-light); }
.plane-body { color: var(--primary-color); }
.plane-tail { color: var(--text-tertiary); }
.structure-legend {
font-size: 10px;
color: var(--text-tertiary);
margin-top: 12px;
line-height: 1.4;
}
/* 游戏规则简介 */
.game-rules-brief {
font-size: 13px;
color: var(--text-secondary);
line-height: 1.5;
margin-top: 16px;
}
.highlight-text {
color: var(--accent-light);
font-weight: 600;
}
/* 主操作按钮组 */
.action-buttons {
width: 100%;
max-width: 300px;
display: flex;
flex-direction: column;
gap: 16px;
margin: 30px 0 20px 0;
}
.btn {
min-height: var(--touch-target-min);
border: none;
border-radius: 12px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
position: relative;
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
text-decoration: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
padding: 0 24px;
}
/* 按钮触摸反馈效果 */
.btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
transform: translate(-50%, -50%);
transition: width 0.3s, height 0.3s;
}
.btn:active::before {
width: 100%;
height: 100%;
}
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--primary-light));
color: #ffffff;
box-shadow: 0 4px 16px rgba(99, 102, 241, 0.3);
}
.btn-primary:hover, .btn-primary:focus {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(99, 102, 241, 0.4);
}
.btn-primary:active {
transform: translateY(0);
}
.btn-success {
background: linear-gradient(135deg, var(--secondary-color), var(--secondary-light));
color: #ffffff;
box-shadow: 0 4px 16px rgba(16, 185, 129, 0.3);
}
.btn-success:hover, .btn-success:focus {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(16, 185, 129, 0.4);
}
.btn-secondary {
background: rgba(99, 102, 241, 0.15);
color: var(--primary-color);
border: 1px solid var(--primary-color);
backdrop-filter: blur(10px);
}
.btn-secondary:hover, .btn-secondary:focus {
background: rgba(99, 102, 241, 0.25);
transform: translateY(-1px);
}
/* 快速操作区域 */
.quick-actions {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px;
width: 100%;
max-width: 300px;
margin-top: 20px;
}
.quick-btn {
min-height: 40px;
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
border-radius: 10px;
color: var(--text-secondary);
font-size: 14px;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
transition: all 0.3s ease;
cursor: pointer;
text-decoration: none;
}
.quick-btn:hover, .quick-btn:focus {
background: var(--bg-elevated);
border-color: var(--border-highlight);
color: var(--text-primary);
transform: translateY(-1px);
}
/* 底部信息栏 */
.bottom-info {
background: rgba(26, 29, 41, 0.8);
backdrop-filter: blur(20px);
padding: 16px var(--safe-area-padding);
border-top: 1px solid var(--border-primary);
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
color: var(--text-tertiary);
}
.offline-indicator {
display: none;
color: var(--danger-color);
font-weight: 500;
}
.offline .offline-indicator {
display: block;
}
.offline .connection-dot {
background: var(--danger-color);
animation: none;
}
/* 加载状态 */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(15, 20, 25, 0.95);
backdrop-filter: blur(10px);
display: none;
align-items: center;
justify-content: center;
z-index: 1000;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 3px solid rgba(99, 102, 241, 0.3);
border-top: 3px solid var(--primary-color);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
margin-top: 16px;
color: var(--text-secondary);
font-size: 14px;
}
/* 响应式设计增强 */
@media (max-width: 375px) {
.game-preview {
padding: 20px;
margin: 20px 0;
}
.action-buttons {
max-width: 280px;
gap: 14px;
}
.btn {
font-size: 15px;
min-height: 42px;
}
}
@media (max-height: 640px) {
.main-content {
justify-content: flex-start;
padding-top: 20px;
}
.game-header {
margin-bottom: 20px;
}
.game-preview {
margin: 20px 0;
padding: 20px;
}
}
/* 高对比度支持 */
@media (prefers-contrast: high) {
:root {
--text-primary: #ffffff;
--text-secondary: #e5e5e5;
--border-primary: #ffffff;
--bg-secondary: #000000;
}
}
/* 减少动画偏好 */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* 暗色模式强制支持 */
@media (prefers-color-scheme: dark) {
body {
background: var(--bg-primary);
color: var(--text-primary);
}
}
</style>
</head>
<body class="safe-area">
<!-- 动态星空背景 -->
<div class="background-constellation" id="starField"></div>
<!-- 加载遮罩 -->
<div class="loading-overlay" id="loadingOverlay">
<div>
<div class="loading-spinner"></div>
<div class="loading-text">正在启动游戏...</div>
</div>
</div>
<div class="app-container">
<!-- 状态栏 -->
<header class="status-bar">
<div class="network-status">
<div class="connection-dot"></div>
<span id="networkStatus">在线</span>
<span class="offline-indicator">离线模式</span>
</div>
<div class="app-version">v2.0.0</div>
</header>
<!-- 主内容 -->
<main class="main-content">
<header class="game-header">
<h1 class="game-logo">飞机大战</h1>
<p class="game-subtitle">十字飞机 • 战略博弈</p>
</header>
<section class="game-preview">
<h2 class="preview-title">
<span class="plane-icon"></span>
游戏特色
</h2>
<div class="cross-plane-display">
<div class="plane-structure">
十字形飞机结构 (11格):<br><br>
<span class="plane-head">  ●  </span><br>
<span class="plane-wing"> ◆</span><span class="plane-body"></span><span class="plane-wing">◆ </span><br>
<span class="plane-body">  ■  </span><br>
<span class="plane-wing"> ◆</span><span class="plane-body"></span><span class="plane-wing">◆ </span><br>
<span class="plane-tail">  ▲  </span><br>
<span class="plane-tail">  ▲  </span>
</div>
<div class="structure-legend">
● 机头 (击中摧毁) | ■ 机身 | ◆ 机翼 | ▲ 机尾
</div>
</div>
<div class="game-rules-brief">
<span class="highlight-text">10×10 网格</span> 中布置 <span class="highlight-text">3架飞机</span><br>
轮流攻击寻找敌机,<span class="highlight-text">击中机头</span> 即可摧毁整架飞机
</div>
</section>
<div class="action-buttons">
<button class="btn btn-primary" id="startGameBtn">
<span>🎮</span>
开始游戏
</button>
<button class="btn btn-success" id="quickMatchBtn">
<span></span>
快速匹配
</button>
<button class="btn btn-secondary" id="tutorialBtn">
<span>📖</span>
游戏教程
</button>
</div>
<div class="quick-actions">
<a href="#" class="quick-btn" id="rankingBtn">
<span>🏆</span>
排行榜
</a>
<a href="#" class="quick-btn" id="settingsBtn">
<span>⚙️</span>
设置
</a>
</div>
</main>
<!-- 底部信息栏 -->
<footer class="bottom-info">
<div class="game-info">移动端优化版 | 支持离线游戏</div>
<div class="build-info">Build 2025.03</div>
</footer>
</div>
<script>
// 应用状态管理
class MobileGameApp {
constructor() {
this.isOnline = navigator.onLine;
this.isLoading = false;
this.touchStartTime = 0;
this.initializeApp();
this.bindEvents();
this.createStarField();
this.checkNetworkStatus();
}
initializeApp() {
// 防止双击缩放
document.addEventListener('touchstart', this.handleTouchStart.bind(this), {passive: false});
document.addEventListener('touchend', this.handleTouchEnd.bind(this), {passive: false});
// PWA 支持检测
if ('serviceWorker' in navigator) {
this.registerServiceWorker();
}
// 页面可见性变化处理
document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this));
console.log('🎮 移动端飞机大战应用已启动');
}
bindEvents() {
// 主要按钮事件
document.getElementById('startGameBtn').addEventListener('click', this.startGame.bind(this));
document.getElementById('quickMatchBtn').addEventListener('click', this.quickMatch.bind(this));
document.getElementById('tutorialBtn').addEventListener('click', this.showTutorial.bind(this));
document.getElementById('rankingBtn').addEventListener('click', this.showRanking.bind(this));
document.getElementById('settingsBtn').addEventListener('click', this.showSettings.bind(this));
// 网络状态监听
window.addEventListener('online', this.handleOnline.bind(this));
window.addEventListener('offline', this.handleOffline.bind(this));
// 内存警告处理
if ('memory' in performance) {
this.monitorMemoryUsage();
}
}
// 触摸事件处理 - 防止意外操作
handleTouchStart(e) {
this.touchStartTime = Date.now();
// 防止多点触控导致的缩放
if (e.touches.length > 1) {
e.preventDefault();
}
}
handleTouchEnd(e) {
const touchDuration = Date.now() - this.touchStartTime;
// 处理长按事件
if (touchDuration > 500) {
this.handleLongPress(e);
}
}
handleLongPress(e) {
// 长按反馈
if (e.target.classList.contains('btn')) {
this.showContextMenu(e.target);
}
}
// 游戏功能实现
async startGame() {
this.showLoading('正在准备游戏...');
try {
// 模拟游戏加载过程
await this.delay(1200);
// 检查设备性能
const deviceInfo = this.getDeviceInfo();
console.log('设备信息:', deviceInfo);
// 跳转到飞机放置界面
this.navigateToPlacement();
} catch (error) {
this.handleError('游戏启动失败', error);
} finally {
this.hideLoading();
}
}
async quickMatch() {
if (!this.isOnline) {
this.showToast('需要网络连接才能进行快速匹配', 'warning');
return;
}
this.showLoading('正在匹配对手...');
try {
// 模拟匹配过程
await this.delay(2000);
// 模拟匹配成功
this.showToast('匹配成功!即将开始对战', 'success');
await this.delay(800);
this.navigateToPlacement();
} catch (error) {
this.handleError('匹配失败', error);
} finally {
this.hideLoading();
}
}
showTutorial() {
// 创建教程弹窗
const tutorialHTML = `
<div class="modal-overlay" id="tutorialModal">
<div class="modal-content">
<div class="modal-header">
<h3>🎯 游戏教程</h3>
<button class="modal-close">&times;</button>
</div>
<div class="modal-body">
<div class="tutorial-step">
<h4>📋 基本规则</h4>
<ul>
<li>游戏使用10×10网格</li>
<li>每位玩家放置3架十字形飞机</li>
<li>每架飞机占据11个格子</li>
<li>飞机可以朝4个方向放置</li>
</ul>
</div>
<div class="tutorial-step">
<h4>✈️ 飞机结构</h4>
<div class="plane-demo">
<div style="font-family: monospace; text-align: center; font-size: 12px; line-height: 1.2;">
<span style="color: #f59e0b;"> ●</span> ← 机头(关键目标)<br>
<span style="color: #8b5cf6;">◆■◆</span> ← 机翼+机身<br>
<span style="color: #6366f1;"> ■</span> ← 机身<br>
<span style="color: #8b5cf6;">◆■◆</span> ← 机翼+机身<br>
<span style="color: #6b7280;"> ▲</span> ← 机尾<br>
<span style="color: #6b7280;"> ▲</span> ← 机尾
</div>
</div>
</div>
<div class="tutorial-step">
<h4>🎮 游戏流程</h4>
<ol>
<li><strong>布置阶段:</strong> 拖拽放置3架飞机</li>
<li><strong>战斗阶段:</strong> 轮流点击攻击目标</li>
<li><strong>胜利条件:</strong> 摧毁敌方3架飞机</li>
</ol>
</div>
<div class="tutorial-step">
<h4>💡 策略提示</h4>
<ul>
<li>机头是唯一的致命弱点</li>
<li>通过命中信息推断飞机位置</li>
<li>合理布局避免飞机被发现</li>
<li>优先攻击可能的机头位置</li>
</ul>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" onclick="this.closest('.modal-overlay').remove()">
开始游戏
</button>
</div>
</div>
</div>
`;
this.showModal(tutorialHTML);
}
showRanking() {
window.location.href = 'mobile_leaderboard_1.html';
}
showSettings() {
const settingsHTML = `
<div class="modal-overlay" id="settingsModal">
<div class="modal-content">
<div class="modal-header">
<h3>⚙️ 游戏设置</h3>
<button class="modal-close">&times;</button>
</div>
<div class="modal-body">
<div class="setting-group">
<h4>🎨 界面设置</h4>
<div class="setting-item">
<label>
<input type="checkbox" checked> 显示网格坐标
</label>
</div>
<div class="setting-item">
<label>
<input type="checkbox" checked> 启用触摸振动
</label>
</div>
</div>
<div class="setting-group">
<h4>🎮 游戏设置</h4>
<div class="setting-item">
<label>
<select>
<option>30秒</option>
<option selected>60秒</option>
<option>90秒</option>
</select>
回合时间限制
</label>
</div>
<div class="setting-item">
<label>
<input type="checkbox" checked> 启用攻击动画
</label>
</div>
</div>
<div class="setting-group">
<h4>💾 数据管理</h4>
<div class="setting-item">
<button class="btn btn-secondary" style="width: 100%; margin-top: 8px;">清除游戏记录</button>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" onclick="this.closest('.modal-overlay').remove()">
保存设置
</button>
</div>
</div>
</div>
`;
this.showModal(settingsHTML);
}
// 工具方法
navigateToPlacement() {
// 这里应该导航到飞机放置界面
window.location.href = 'mobile_plane_placement_1.html';
}
showLoading(message = '加载中...') {
this.isLoading = true;
const overlay = document.getElementById('loadingOverlay');
const text = overlay.querySelector('.loading-text');
text.textContent = message;
overlay.style.display = 'flex';
}
hideLoading() {
this.isLoading = false;
const overlay = document.getElementById('loadingOverlay');
overlay.style.display = 'none';
}
showToast(message, type = 'info') {
const toast = document.createElement('div');
toast.className = `toast toast-${type}`;
toast.textContent = message;
// 添加toast样式到文档
if (!document.querySelector('#toastStyles')) {
const style = document.createElement('style');
style.id = 'toastStyles';
style.textContent = `
.toast {
position: fixed;
top: 80px;
left: 50%;
transform: translateX(-50%);
background: var(--bg-elevated);
color: var(--text-primary);
padding: 12px 20px;
border-radius: 8px;
border: 1px solid var(--border-primary);
z-index: 1001;
animation: toastSlide 0.3s ease-out;
max-width: 300px;
text-align: center;
font-size: 14px;
}
.toast-success { border-color: var(--secondary-color); }
.toast-warning { border-color: var(--accent-color); }
.toast-error { border-color: var(--danger-color); }
@keyframes toastSlide {
0% { opacity: 0; transform: translateX(-50%) translateY(-10px); }
100% { opacity: 1; transform: translateX(-50%) translateY(0); }
}
`;
document.head.appendChild(style);
}
document.body.appendChild(toast);
setTimeout(() => {
toast.remove();
}, 3000);
}
showModal(htmlContent) {
// 添加模态框样式
if (!document.querySelector('#modalStyles')) {
const style = document.createElement('style');
style.id = 'modalStyles';
style.textContent = `
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(10px);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
padding: 20px;
animation: modalFadeIn 0.3s ease-out;
}
.modal-content {
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 16px;
max-width: 400px;
width: 100%;
max-height: 80vh;
overflow-y: auto;
animation: modalSlideIn 0.3s ease-out;
}
.modal-header {
padding: 20px 20px 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h3 {
color: var(--text-primary);
font-size: 18px;
margin: 0;
}
.modal-close {
background: none;
border: none;
color: var(--text-secondary);
font-size: 24px;
cursor: pointer;
padding: 0;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
}
.modal-body {
padding: 20px;
}
.modal-footer {
padding: 0 20px 20px;
}
.tutorial-step {
margin-bottom: 24px;
}
.tutorial-step h4 {
color: var(--primary-color);
margin-bottom: 12px;
font-size: 16px;
}
.tutorial-step ul, .tutorial-step ol {
color: var(--text-secondary);
font-size: 14px;
line-height: 1.6;
padding-left: 20px;
}
.tutorial-step li {
margin-bottom: 6px;
}
.plane-demo {
background: var(--bg-primary);
border: 1px solid var(--border-secondary);
border-radius: 8px;
padding: 12px;
margin: 12px 0;
}
.setting-group {
margin-bottom: 20px;
}
.setting-group h4 {
color: var(--primary-color);
margin-bottom: 12px;
font-size: 16px;
}
.setting-item {
margin-bottom: 12px;
}
.setting-item label {
display: flex;
align-items: center;
gap: 8px;
color: var(--text-secondary);
font-size: 14px;
cursor: pointer;
}
.setting-item select {
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
border-radius: 6px;
color: var(--text-primary);
padding: 4px 8px;
font-size: 14px;
}
@keyframes modalFadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes modalSlideIn {
0% { transform: translateY(30px) scale(0.9); opacity: 0; }
100% { transform: translateY(0) scale(1); opacity: 1; }
}
`;
document.head.appendChild(style);
}
const modalContainer = document.createElement('div');
modalContainer.innerHTML = htmlContent;
document.body.appendChild(modalContainer.firstElementChild);
// 绑定关闭事件
const modal = document.querySelector('.modal-overlay:last-child');
const closeBtn = modal.querySelector('.modal-close');
closeBtn.addEventListener('click', () => modal.remove());
modal.addEventListener('click', (e) => {
if (e.target === modal) modal.remove();
});
}
showContextMenu(element) {
// 长按上下文菜单功能(预留)
if (navigator.vibrate) {
navigator.vibrate(50);
}
}
createStarField() {
const starField = document.getElementById('starField');
const starCount = Math.floor(Math.random() * 50) + 30;
for (let i = 0; i < starCount; i++) {
const star = document.createElement('div');
star.className = 'star';
star.style.left = Math.random() * 100 + '%';
star.style.top = Math.random() * 100 + '%';
star.style.animationDelay = Math.random() * 3 + 's';
starField.appendChild(star);
}
}
checkNetworkStatus() {
const updateStatus = () => {
this.isOnline = navigator.onLine;
const statusText = document.getElementById('networkStatus');
const body = document.body;
if (this.isOnline) {
statusText.textContent = '在线';
body.classList.remove('offline');
} else {
statusText.textContent = '离线';
body.classList.add('offline');
}
};
updateStatus();
setInterval(updateStatus, 5000);
}
handleOnline() {
this.isOnline = true;
this.showToast('网络连接已恢复', 'success');
this.checkNetworkStatus();
}
handleOffline() {
this.isOnline = false;
this.showToast('网络连接已断开,切换到离线模式', 'warning');
this.checkNetworkStatus();
}
handleVisibilityChange() {
if (document.hidden) {
// 应用进入后台
console.log('应用进入后台');
} else {
// 应用回到前台
console.log('应用回到前台');
this.checkNetworkStatus();
}
}
getDeviceInfo() {
return {
userAgent: navigator.userAgent,
platform: navigator.platform,
memory: navigator.deviceMemory || 'unknown',
cores: navigator.hardwareConcurrency || 'unknown',
connection: navigator.connection?.effectiveType || 'unknown',
viewport: {
width: window.innerWidth,
height: window.innerHeight
}
};
}
monitorMemoryUsage() {
if ('memory' in performance) {
setInterval(() => {
const memory = performance.memory;
if (memory.usedJSHeapSize / memory.jsHeapSizeLimit > 0.9) {
console.warn('内存使用率过高:', (memory.usedJSHeapSize / memory.jsHeapSizeLimit * 100).toFixed(1) + '%');
}
}, 10000);
}
}
async registerServiceWorker() {
try {
// 这里可以注册Service Worker实现离线功能
console.log('Service Worker 支持可用');
} catch (error) {
console.warn('Service Worker 注册失败:', error);
}
}
handleError(message, error) {
console.error(message, error);
this.showToast(message, 'error');
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// 应用启动
document.addEventListener('DOMContentLoaded', () => {
new MobileGameApp();
});
// 页面加载完成动画
window.addEventListener('load', () => {
const appContainer = document.querySelector('.app-container');
appContainer.style.opacity = '0';
appContainer.style.transform = 'translateY(20px)';
appContainer.style.transition = 'all 0.8s cubic-bezier(0.4, 0, 0.2, 1)';
setTimeout(() => {
appContainer.style.opacity = '1';
appContainer.style.transform = 'translateY(0)';
}, 100);
});
</script>
</body>
</html>