
支持横屏,后续可添加游戏资源,和功能拓展
html
<!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">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>霓虹格斗竞技场</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #0a0e27 0%, #1a0033 50%, #0a0e27 100%);
color: #fff;
height: 100vh;
overflow: hidden;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
/* 强制横屏提示 */
.orientation-warning {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
display: none;
justify-content: center;
align-items: center;
z-index: 1000;
flex-direction: column;
}
.orientation-warning.show {
display: flex;
}
.rotate-icon {
font-size: 4rem;
margin-bottom: 1rem;
animation: rotate 2s infinite;
}
@keyframes rotate {
0% { transform: rotate(-90deg); }
100% { transform: rotate(90deg); }
}
/* 赛博朋克背景效果 */
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 50%, rgba(255, 119, 198, 0.3) 0%, transparent 50%),
radial-gradient(circle at 50% 20%, rgba(255, 219, 98, 0.2) 0%, transparent 50%);
animation: pulse 8s infinite alternate;
z-index: -1;
}
@keyframes pulse {
0% { opacity: 0.5; }
100% { opacity: 1; }
}
/* 主容器 */
.game-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
position: relative;
}
/* 角色选择界面 */
.character-select {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(10, 14, 39, 0.95);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 100;
backdrop-filter: blur(10px);
transition: all 0.5s ease;
}
.character-select.hidden {
opacity: 0;
pointer-events: none;
}
.select-title {
font-size: 2rem;
margin-bottom: 1rem;
text-align: center;
background: linear-gradient(90deg, #00ffff, #ff00ff, #00ffff);
background-size: 200% auto;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradient 3s linear infinite;
text-shadow: 0 0 30px rgba(0, 255, 255, 0.5);
}
@keyframes gradient {
0% { background-position: 0% 50%; }
100% { background-position: 200% 50%; }
}
/* 横屏时一行显示角色 */
.characters {
display: flex;
gap: 1rem;
margin-bottom: 1.5rem;
flex-wrap: nowrap;
justify-content: center;
max-width: 95%;
overflow-x: auto;
padding: 0 1rem;
}
/* 竖屏时允许换行 */
@media (orientation: portrait) {
.characters {
flex-wrap: wrap;
max-height: 60vh;
overflow-y: auto;
}
}
.character-card {
width: 120px;
height: 160px;
background: linear-gradient(145deg, #1a1a3e, #2a2a5e);
border-radius: 15px;
padding: 0.8rem;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid transparent;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
position: relative;
overflow: hidden;
flex-shrink: 0;
}
.character-card::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, #00ffff, #ff00ff, #00ffff);
border-radius: 15px;
opacity: 0;
z-index: -1;
transition: opacity 0.3s ease;
}
.character-card:hover {
transform: translateY(-5px) scale(1.05);
box-shadow: 0 15px 30px rgba(0, 255, 255, 0.4);
}
.character-card:hover::before {
opacity: 1;
}
.character-card.selected {
border-color: #00ffff;
box-shadow: 0 0 20px rgba(0, 255, 255, 0.6);
}
.character-avatar {
width: 100%;
height: 60px;
background: #000;
border-radius: 10px;
margin-bottom: 0.5rem;
display: flex;
justify-content: center;
align-items: center;
font-size: 2.5rem;
position: relative;
overflow: hidden;
}
.character-name {
font-size: 0.9rem;
text-align: center;
margin-bottom: 0.3rem;
color: #00ffff;
}
.character-stats {
font-size: 0.7rem;
color: #aaa;
text-align: center;
}
.stat-bar {
height: 3px;
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
margin: 0.2rem 0;
overflow: hidden;
}
.stat-fill {
height: 100%;
border-radius: 2px;
}
.health-fill { background: linear-gradient(90deg, #ff3366, #ff6b6b); }
.speed-fill { background: linear-gradient(90deg, #3366ff, #66b3ff); }
.power-fill { background: linear-gradient(90deg, #ffcc00, #ff9900); }
.start-button {
padding: 0.8rem 2rem;
font-size: 1.2rem;
background: linear-gradient(90deg, #00ffff, #ff00ff);
border: none;
border-radius: 50px;
color: white;
cursor: pointer;
transition: all 0.3s ease;
text-transform: uppercase;
letter-spacing: 2px;
font-weight: bold;
box-shadow: 0 5px 15px rgba(0, 255, 255, 0.4);
margin-top: 1rem;
}
.start-button:hover {
transform: scale(1.1);
box-shadow: 0 8px 25px rgba(0, 255, 255, 0.6);
}
.start-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* 游戏界面 */
.game-arena {
width: 100%;
height: 100%;
display: none;
flex-direction: column;
}
.game-arena.active {
display: flex;
}
.game-header {
padding: 0.5rem 1rem;
background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(10px);
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid rgba(0, 255, 255, 0.3);
}
.player-info {
display: flex;
align-items: center;
gap: 1rem;
}
.player-avatar {
width: 40px;
height: 40px;
background: rgba(0, 0, 0, 0.5);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.5rem;
border: 2px solid;
}
.player-details {
display: flex;
flex-direction: column;
gap: 0.3rem;
}
.player-name {
font-size: 1rem;
font-weight: bold;
}
.health-bar-container {
width: 150px;
height: 12px;
background: rgba(0, 0, 0, 0.5);
border-radius: 6px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.health-bar {
height: 100%;
background: linear-gradient(90deg, #ff3366, #ff6b6b);
transition: width 0.3s ease;
box-shadow: 0 0 10px rgba(255, 51, 102, 0.5);
}
.energy-bar-container {
width: 150px;
height: 8px;
background: rgba(0, 0, 0, 0.5);
border-radius: 4px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.energy-bar {
height: 100%;
background: linear-gradient(90deg, #00ffff, #0099ff);
transition: width 0.3s ease;
box-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
}
.game-canvas {
flex: 1;
position: relative;
background: linear-gradient(to bottom, #0a0e27 0%, #1a0033 100%);
overflow: hidden;
}
.fighter {
position: absolute;
bottom: 80px;
width: 80px;
height: 120px;
transition: left 0.1s ease;
}
.fighter-body {
width: 100%;
height: 100%;
border-radius: 10px;
position: relative;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
}
.fighter-head {
width: 40px;
height: 40px;
border-radius: 50%;
margin-bottom: 5px;
position: relative;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.fighter-torso {
width: 50px;
height: 50px;
border-radius: 8px;
position: relative;
}
.fighter-limbs {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.fighter-arm {
position: absolute;
width: 12px;
height: 40px;
border-radius: 6px;
top: 15px;
}
.fighter-arm.left {
left: 5px;
transform-origin: top center;
animation: leftArm 1s infinite alternate;
}
.fighter-arm.right {
right: 5px;
transform-origin: top center;
animation: rightArm 1s infinite alternate-reverse;
}
@keyframes leftArm {
0% { transform: rotate(-10deg); }
100% { transform: rotate(10deg); }
}
@keyframes rightArm {
0% { transform: rotate(10deg); }
100% { transform: rotate(-10deg); }
}
.fighter-leg {
position: absolute;
width: 15px;
height: 45px;
border-radius: 8px;
bottom: 0;
}
.fighter-leg.left {
left: 20px;
transform-origin: top center;
animation: leftLeg 1s infinite alternate;
}
.fighter-leg.right {
right: 20px;
transform-origin: top center;
animation: rightLeg 1s infinite alternate-reverse;
}
@keyframes leftLeg {
0% { transform: rotate(-5deg); }
100% { transform: rotate(5deg); }
}
@keyframes rightLeg {
0% { transform: rotate(5deg); }
100% { transform: rotate(-5deg); }
}
.fighter.player .fighter-body {
background: linear-gradient(135deg, #00ffff, #0099ff);
box-shadow: 0 0 30px rgba(0, 255, 255, 0.5);
}
.fighter.player .fighter-head {
background: linear-gradient(135deg, #00ffff, #0099ff);
}
.fighter.player .fighter-torso {
background: linear-gradient(135deg, #0099ff, #0066cc);
}
.fighter.player .fighter-arm,
.fighter.player .fighter-leg {
background: linear-gradient(135deg, #0099ff, #0066cc);
}
.fighter.ai .fighter-body {
background: linear-gradient(135deg, #ff00ff, #cc00cc);
box-shadow: 0 0 30px rgba(255, 0, 255, 0.5);
}
.fighter.ai .fighter-head {
background: linear-gradient(135deg, #ff00ff, #cc00cc);
}
.fighter.ai .fighter-torso {
background: linear-gradient(135deg, #cc00cc, #990099);
}
.fighter.ai .fighter-arm,
.fighter.ai .fighter-leg {
background: linear-gradient(135deg, #cc00cc, #990099);
}
.fighter.attacking .fighter-arm.right {
animation: attack 0.3s ease;
}
@keyframes attack {
0% { transform: rotate(0deg); }
50% { transform: rotate(-60deg) translateX(15px); }
100% { transform: rotate(0deg); }
}
.fighter.hurt {
animation: hurt 0.5s ease;
}
@keyframes hurt {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-10px); }
40% { transform: translateX(10px); }
60% { transform: translateX(-10px); }
80% { transform: translateX(10px); }
}
.fighter.blocking {
opacity: 0.7;
}
.fighter.blocking::after {
content: '';
position: absolute;
width: 100px;
height: 100px;
border: 3px solid rgba(0, 255, 255, 0.6);
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: blockPulse 1s infinite;
}
@keyframes blockPulse {
0% { transform: translate(-50%, -50%) scale(0.8); opacity: 1; }
100% { transform: translate(-50%, -50%) scale(1.2); opacity: 0; }
}
/* 增强的特效 */
.effect {
position: absolute;
pointer-events: none;
}
.hit-effect {
width: 80px;
height: 80px;
background: radial-gradient(circle, rgba(255, 255, 0, 0.9), rgba(255, 165, 0, 0.6), transparent);
border-radius: 50%;
animation: hitEffect 0.6s ease forwards;
box-shadow: 0 0 30px rgba(255, 255, 0, 0.8);
}
@keyframes hitEffect {
0% { transform: scale(0) rotate(0deg); opacity: 1; }
50% { transform: scale(1.5) rotate(180deg); opacity: 0.8; }
100% { transform: scale(2.5) rotate(360deg); opacity: 0; }
}
.block-effect {
width: 100px;
height: 100px;
border: 4px solid rgba(0, 255, 255, 0.9);
border-radius: 50%;
animation: blockEffect 0.6s ease forwards;
box-shadow: 0 0 20px rgba(0, 255, 255, 0.8);
}
@keyframes blockEffect {
0% { transform: scale(0.5) rotate(0deg); opacity: 1; }
100% { transform: scale(2) rotate(360deg); opacity: 0; }
}
.special-effect {
width: 150px;
height: 150px;
background: radial-gradient(circle, rgba(255, 0, 255, 0.9), rgba(147, 0, 211, 0.6), transparent);
border-radius: 50%;
animation: specialEffect 1.2s ease forwards;
box-shadow: 0 0 40px rgba(255, 0, 255, 0.8);
}
@keyframes specialEffect {
0% { transform: scale(0) rotate(0deg); opacity: 1; }
50% { transform: scale(2) rotate(180deg); opacity: 0.7; }
100% { transform: scale(4) rotate(720deg); opacity: 0; }
}
/* 王者荣耀风格控制按钮 */
.game-controls {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 200px;
pointer-events: none;
z-index: 50;
}
/* 左侧方向键 */
.direction-controls {
position: absolute;
left: 20px;
bottom: 20px;
width: 150px;
height: 150px;
pointer-events: auto;
}
.dpad-container {
position: relative;
width: 100%;
height: 100%;
}
.dpad-btn {
position: absolute;
background: rgba(0, 0, 0, 0.6);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 10px;
color: rgba(255, 255, 255, 0.8);
font-size: 1.5rem;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: all 0.2s ease;
backdrop-filter: blur(5px);
}
.dpad-btn:active {
background: rgba(0, 255, 255, 0.4);
border-color: rgba(0, 255, 255, 0.8);
transform: scale(0.95);
}
.dpad-up {
width: 50px;
height: 50px;
top: 0;
left: 50px;
}
.dpad-down {
width: 50px;
height: 50px;
bottom: 0;
left: 50px;
}
.dpad-left {
width: 50px;
height: 50px;
top: 50px;
left: 0;
}
.dpad-right {
width: 50px;
height: 50px;
top: 50px;
right: 0;
}
.dpad-center {
width: 50px;
height: 50px;
top: 50px;
left: 50px;
background: rgba(0, 0, 0, 0.3);
pointer-events: none;
}
/* 右侧攻击键 */
.action-controls {
position: absolute;
right: 20px;
bottom: 20px;
width: 180px;
height: 150px;
pointer-events: auto;
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: flex-end;
align-items: flex-end;
}
.action-btn {
width: 55px;
height: 55px;
background: rgba(255, 0, 0, 0.6);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
color: white;
font-size: 0.9rem;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: all 0.2s ease;
backdrop-filter: blur(5px);
text-shadow: 0 0 5px rgba(0, 0, 0, 0.8);
}
.action-btn.attack {
background: rgba(255, 0, 0, 0.7);
border-color: rgba(255, 100, 100, 0.8);
box-shadow: 0 0 15px rgba(255, 0, 0, 0.5);
}
.action-btn.special {
background: rgba(255, 165, 0, 0.7);
border-color: rgba(255, 200, 100, 0.8);
box-shadow: 0 0 15px rgba(255, 165, 0, 0.5);
}
.action-btn.block {
background: rgba(0, 100, 255, 0.7);
border-color: rgba(100, 150, 255, 0.8);
box-shadow: 0 0 15px rgba(0, 100, 255, 0.5);
}
.action-btn.jump {
background: rgba(0, 255, 0, 0.7);
border-color: rgba(100, 255, 100, 0.8);
box-shadow: 0 0 15px rgba(0, 255, 0, 0.5);
}
.action-btn:active {
transform: scale(0.9);
filter: brightness(1.3);
}
.action-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.game-message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 2rem;
font-weight: bold;
text-align: center;
text-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
z-index: 50;
pointer-events: none;
}
.victory-message {
color: #00ff00;
animation: victoryPulse 1s infinite;
}
.defeat-message {
color: #ff0000;
animation: defeatShake 0.5s infinite;
}
@keyframes victoryPulse {
0%, 100% { transform: translate(-50%, -50%) scale(1); }
50% { transform: translate(-50%, -50%) scale(1.1); }
}
@keyframes defeatShake {
0%, 100% { transform: translate(-50%, -50%) translateX(0); }
25% { transform: translate(-50%, -50%) translateX(-10px); }
75% { transform: translate(-50%, -50%) translateX(10px); }
}
.ground {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 80px;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.6));
border-top: 2px solid rgba(0, 255, 255, 0.2);
}
.ground::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 2px;
background: linear-gradient(90deg, transparent, #00ffff, transparent);
animation: groundGlow 3s infinite;
}
@keyframes groundGlow {
0%, 100% { opacity: 0.3; }
50% { opacity: 1; }
}
.countdown {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 5rem;
font-weight: bold;
color: #00ffff;
text-shadow: 0 0 30px rgba(0, 255, 255, 0.8);
animation: countdownPulse 1s ease;
z-index: 40;
}
@keyframes countdownPulse {
0% { transform: translate(-50%, -50%) scale(0); opacity: 0; }
50% { transform: translate(-50%, -50%) scale(1.2); opacity: 1; }
100% { transform: translate(-50%, -50%) scale(1); opacity: 0.8; }
}
.restart-btn {
position: absolute;
top: 20px;
right: 20px;
padding: 0.5rem 1rem;
background: rgba(255, 255, 255, 0.2);
border: 2px solid rgba(255, 255, 255, 0.4);
border-radius: 20px;
color: white;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.3s ease;
backdrop-filter: blur(5px);
z-index: 60;
}
.restart-btn:hover {
background: rgba(255, 255, 255, 0.3);
border-color: rgba(255, 255, 255, 0.6);
}
</style>
</head>
<body>
<!-- 横屏提示 -->
<div class="orientation-warning" id="orientationWarning">
<div class="rotate-icon">📱</div>
<div>请横屏游戏以获得最佳体验</div>
</div>
<div class="game-container">
<!-- 角色选择界面 -->
<div class="character-select" id="characterSelect">
<h1 class="select-title">选择战士</h1>
<div class="characters" id="characterCards">
<!-- 角色卡片将通过JS生成 -->
</div>
<button class="start-button" id="startBtn" disabled>开始战斗</button>
</div>
<!-- 游戏竞技场 -->
<div class="game-arena" id="gameArena">
<div class="game-header">
<div class="player-info">
<div class="player-avatar" id="playerAvatar">⚔️</div>
<div class="player-details">
<div class="player-name" id="playerName">玩家</div>
<div class="health-bar-container">
<div class="health-bar" id="playerHealth" style="width: 100%"></div>
</div>
<div class="energy-bar-container">
<div class="energy-bar" id="playerEnergy" style="width: 100%"></div>
</div>
</div>
</div>
<div class="player-info">
<div class="player-details" style="align-items: flex-end;">
<div class="player-name" id="aiName">AI</div>
<div class="health-bar-container">
<div class="health-bar" id="aiHealth" style="width: 100%"></div>
</div>
<div class="energy-bar-container">
<div class="energy-bar" id="aiEnergy" style="width: 100%"></div>
</div>
</div>
<div class="player-avatar" id="aiAvatar">🤖</div>
</div>
</div>
<div class="game-canvas" id="gameCanvas">
<div class="ground"></div>
<div class="fighter player" id="player">
<div class="fighter-body">
<div class="fighter-head"></div>
<div class="fighter-torso"></div>
<div class="fighter-limbs">
<div class="fighter-arm left"></div>
<div class="fighter-arm right"></div>
<div class="fighter-leg left"></div>
<div class="fighter-leg right"></div>
</div>
</div>
</div>
<div class="fighter ai" id="ai">
<div class="fighter-body">
<div class="fighter-head"></div>
<div class="fighter-torso"></div>
<div class="fighter-limbs">
<div class="fighter-arm left"></div>
<div class="fighter-arm right"></div>
<div class="fighter-leg left"></div>
<div class="fighter-leg right"></div>
</div>
</div>
</div>
</div>
<!-- 王者荣耀风格控制 -->
<div class="game-controls">
<!-- 左侧方向键 -->
<div class="direction-controls">
<div class="dpad-container">
<button class="dpad-btn dpad-up" id="upBtn">↑</button>
<button class="dpad-btn dpad-down" id="downBtn">↓</button>
<button class="dpad-btn dpad-left" id="leftBtn">←</button>
<button class="dpad-btn dpad-right" id="rightBtn">→</button>
<div class="dpad-btn dpad-center"></div>
</div>
</div>
<!-- 右侧攻击键 -->
<div class="action-controls">
<button class="action-btn attack" id="attackBtn">攻击</button>
<button class="action-btn special" id="specialBtn">技能</button>
<button class="action-btn block" id="blockBtn">格挡</button>
<button class="action-btn jump" id="jumpBtn">跳跃</button>
</div>
</div>
<button class="restart-btn" id="restartBtn">重新开始</button>
</div>
</div>
<script>
// 游戏角色数据
const characters = [
{
id: 'cyberNinja',
name: '赛博忍者',
icon: '🥷',
health: 100,
speed: 8,
power: 7,
color: '#00ffff'
},
{
id: 'techWarrior',
name: '科技战士',
icon: '🤖',
health: 120,
speed: 5,
power: 9,
color: '#ff00ff'
},
{
id: 'neonSamurai',
name: '霓虹武士',
icon: '⚔️',
health: 90,
speed: 7,
power: 8,
color: '#ffff00'
},
{
id: 'gladiator',
name: '角斗士',
icon: '🛡️',
health: 130,
speed: 4,
power: 7,
color: '#ff6600'
},
{
id: 'assassin',
name: '暗影刺客',
icon: '🗡️',
health: 80,
speed: 10,
power: 9,
color: '#9900ff'
},
{
id: 'mage',
name: '元素法师',
icon: '🔮',
health: 85,
speed: 6,
power: 10,
color: '#9933ff'
},
{
id: 'berserker',
name: '狂战士',
icon: '🪓',
health: 110,
speed: 6,
power: 8,
color: '#ff3333'
}
];
// 游戏状态
let selectedCharacter = null;
let aiCharacter = null;
let gameState = 'select'; // select, countdown, playing, ended
let playerHealth = 100;
let aiHealth = 100;
let playerEnergy = 100;
let aiEnergy = 100;
let playerPos = 100;
let aiPos = 0;
let isJumping = false;
let isBlocking = false;
let isAttacking = false;
let isSpecialAttacking = false;
let aiActionTimer = null;
let gameTimer = null;
let moveTimer = null;
// DOM元素
const characterSelect = document.getElementById('characterSelect');
const gameArena = document.getElementById('gameArena');
const characterCards = document.getElementById('characterCards');
const startBtn = document.getElementById('startBtn');
const player = document.getElementById('player');
const ai = document.getElementById('ai');
const gameCanvas = document.getElementById('gameCanvas');
const orientationWarning = document.getElementById('orientationWarning');
// 检测屏幕方向
function checkOrientation() {
if (window.innerHeight > window.innerWidth) {
orientationWarning.classList.add('show');
} else {
orientationWarning.classList.remove('show');
}
}
// 初始化
window.addEventListener('resize', checkOrientation);
window.addEventListener('orientationchange', checkOrientation);
checkOrientation();
// 初始化角色选择界面
function initCharacterSelect() {
characters.forEach(char => {
const card = document.createElement('div');
card.className = 'character-card';
card.dataset.id = char.id;
card.innerHTML = `
<div class="character-avatar">${char.icon}</div>
<div class="character-name">${char.name}</div>
<div class="character-stats">
<div>生命</div>
<div class="stat-bar">
<div class="stat-fill health-fill" style="width: ${char.health}%"></div>
</div>
<div>速度</div>
<div class="stat-bar">
<div class="stat-fill speed-fill" style="width: ${char.speed * 10}%"></div>
</div>
<div>力量</div>
<div class="stat-bar">
<div class="stat-fill power-fill" style="width: ${char.power * 10}%"></div>
</div>
</div>
`;
card.addEventListener('click', () => selectCharacter(char.id));
characterCards.appendChild(card);
});
}
// 选择角色
function selectCharacter(id) {
document.querySelectorAll('.character-card').forEach(card => {
card.classList.remove('selected');
});
const selectedCard = document.querySelector(`.character-card[data-id="${id}"]`);
selectedCard.classList.add('selected');
selectedCharacter = characters.find(char => char.id === id);
startBtn.disabled = false;
}
// 开始游戏
function startGame() {
if (!selectedCharacter) return;
// 随机选择AI角色
const availableChars = characters.filter(char => char.id !== selectedCharacter.id);
aiCharacter = availableChars[Math.floor(Math.random() * availableChars.length)];
// 设置角色信息
document.getElementById('playerName').textContent = selectedCharacter.name;
document.getElementById('playerAvatar').textContent = selectedCharacter.icon;
document.getElementById('aiName').textContent = aiCharacter.name;
document.getElementById('aiAvatar').textContent = aiCharacter.icon;
// 初始化游戏状态
playerHealth = selectedCharacter.health;
aiHealth = aiCharacter.health;
playerEnergy = 100;
aiEnergy = 100;
playerPos = 100;
aiPos = window.innerWidth - 180;
// 更新UI
updateHealthBars();
updateEnergyBars();
updatePositions();
// 切换界面
characterSelect.classList.add('hidden');
gameArena.classList.add('active');
// 开始倒计时
startCountdown();
}
// 倒计时
function startCountdown() {
gameState = 'countdown';
let count = 3;
const countdownEl = document.createElement('div');
countdownEl.className = 'countdown';
gameCanvas.appendChild(countdownEl);
const countInterval = setInterval(() => {
count--;
if (count > 0) {
countdownEl.textContent = count;
countdownEl.style.animation = 'none';
setTimeout(() => {
countdownEl.style.animation = 'countdownPulse 1s ease';
}, 10);
} else if (count === 0) {
countdownEl.textContent = 'FIGHT!';
countdownEl.style.color = '#ff0000';
} else {
clearInterval(countInterval);
countdownEl.remove();
startGameplay();
}
}, 1000);
}
// 开始游戏玩法
function startGameplay() {
gameState = 'playing';
startAI();
startGameLoop();
}
// 游戏主循环
function startGameLoop() {
gameTimer = setInterval(() => {
// 恢复能量
if (playerEnergy < 100) {
playerEnergy = Math.min(100, playerEnergy + 0.5);
updateEnergyBars();
}
if (aiEnergy < 100) {
aiEnergy = Math.min(100, aiEnergy + 0.5);
updateEnergyBars();
}
// 检查游戏结束
if (playerHealth <= 0 || aiHealth <= 0) {
endGame();
}
}, 100);
}
// AI行为
function startAI() {
aiActionTimer = setInterval(() => {
if (gameState !== 'playing') return;
const distance = Math.abs(playerPos - aiPos);
const action = Math.random();
// 移动逻辑
if (distance > 150) {
// 向玩家移动
if (playerPos < aiPos) {
moveAI(-aiCharacter.speed);
} else {
moveAI(aiCharacter.speed);
}
} else {
// 战斗逻辑
if (action < 0.3) {
// 30%概率攻击
aiAttack();
} else if (action < 0.5 && aiEnergy >= 30) {
// 20%概率特殊攻击
aiSpecialAttack();
} else if (action < 0.7) {
// 20%概率格挡
aiBlock();
} else if (action < 0.9) {
// 20%概率跳跃
aiJump();
} else {
// 10%概率后退
if (playerPos < aiPos) {
moveAI(aiCharacter.speed);
} else {
moveAI(-aiCharacter.speed);
}
}
}
}, 800);
}
// 玩家移动
function movePlayer(direction) {
if (gameState !== 'playing') return;
playerPos += direction * selectedCharacter.speed * 2;
playerPos = Math.max(20, Math.min(window.innerWidth - 100, playerPos));
updatePositions();
}
// AI移动
function moveAI(direction) {
if (gameState !== 'playing') return;
aiPos += direction * aiCharacter.speed * 2;
aiPos = Math.max(20, Math.min(window.innerWidth - 100, aiPos));
updatePositions();
}
// 玩家跳跃
function playerJump() {
if (gameState !== 'playing' || isJumping) return;
isJumping = true;
player.style.bottom = '180px';
setTimeout(() => {
player.style.bottom = '80px';
isJumping = false;
}, 600);
}
// AI跳跃
function aiJump() {
if (gameState !== 'playing') return;
ai.style.bottom = '180px';
setTimeout(() => {
ai.style.bottom = '80px';
}, 600);
}
// 玩家攻击
function playerAttack() {
if (gameState !== 'playing' || isAttacking || isBlocking) return;
isAttacking = true;
player.classList.add('attacking');
const distance = Math.abs(playerPos - aiPos);
if (distance < 120) {
// 造成伤害
const damage = selectedCharacter.power * 3;
aiHealth = Math.max(0, aiHealth - damage);
updateHealthBars();
// 添加受击效果
ai.classList.add('hurt');
createEffect(aiPos, 120, 'hit');
setTimeout(() => {
ai.classList.remove('hurt');
}, 500);
}
setTimeout(() => {
player.classList.remove('attacking');
isAttacking = false;
}, 300);
}
// AI攻击
function aiAttack() {
if (gameState !== 'playing' || isAttacking) return;
isAttacking = true;
ai.classList.add('attacking');
const distance = Math.abs(playerPos - aiPos);
if (distance < 120) {
// 造成伤害
const damage = aiCharacter.power * 3;
playerHealth = Math.max(0, playerHealth - damage);
updateHealthBars();
// 添加受击效果
player.classList.add('hurt');
createEffect(playerPos, 120, 'hit');
setTimeout(() => {
player.classList.remove('hurt');
}, 500);
}
setTimeout(() => {
ai.classList.remove('attacking');
isAttacking = false;
}, 300);
}
// 玩家特殊攻击
function playerSpecialAttack() {
if (gameState !== 'playing' || isSpecialAttacking || playerEnergy < 30) return;
isSpecialAttacking = true;
playerEnergy -= 30;
updateEnergyBars();
player.classList.add('attacking');
const distance = Math.abs(playerPos - aiPos);
if (distance < 180) {
// 造成大量伤害
const damage = selectedCharacter.power * 6;
aiHealth = Math.max(0, aiHealth - damage);
updateHealthBars();
// 添加特殊效果
ai.classList.add('hurt');
createEffect(aiPos, 120, 'special');
setTimeout(() => {
ai.classList.remove('hurt');
}, 500);
}
setTimeout(() => {
player.classList.remove('attacking');
isSpecialAttacking = false;
}, 500);
}
// AI特殊攻击
function aiSpecialAttack() {
if (gameState !== 'playing' || aiEnergy < 30) return;
aiEnergy -= 30;
updateEnergyBars();
ai.classList.add('attacking');
const distance = Math.abs(playerPos - aiPos);
if (distance < 180) {
// 造成大量伤害
const damage = aiCharacter.power * 6;
playerHealth = Math.max(0, playerHealth - damage);
updateHealthBars();
// 添加特殊效果
player.classList.add('hurt');
createEffect(playerPos, 120, 'special');
setTimeout(() => {
player.classList.remove('hurt');
}, 500);
}
setTimeout(() => {
ai.classList.remove('attacking');
}, 500);
}
// 玩家格挡
function playerBlock() {
if (gameState !== 'playing' || isBlocking) return;
isBlocking = true;
player.classList.add('blocking');
setTimeout(() => {
player.classList.remove('blocking');
isBlocking = false;
}, 1000);
}
// AI格挡
function aiBlock() {
if (gameState !== 'playing') return;
ai.classList.add('blocking');
createEffect(aiPos, 120, 'block');
setTimeout(() => {
ai.classList.remove('blocking');
}, 1000);
}
// 创建特效
function createEffect(x, y, type) {
const effect = document.createElement('div');
effect.className = `effect ${type}-effect`;
effect.style.left = `${x - 40}px`;
effect.style.bottom = `${y}px`;
gameCanvas.appendChild(effect);
setTimeout(() => {
effect.remove();
}, 1200);
}
// 更新位置
function updatePositions() {
player.style.left = `${playerPos}px`;
ai.style.left = `${aiPos}px`;
}
// 更新血条
function updateHealthBars() {
document.getElementById('playerHealth').style.width = `${playerHealth}%`;
document.getElementById('aiHealth').style.width = `${aiHealth}%`;
}
// 更新能量条
function updateEnergyBars() {
document.getElementById('playerEnergy').style.width = `${playerEnergy}%`;
document.getElementById('aiEnergy').style.width = `${aiEnergy}%`;
}
// 游戏结束
function endGame() {
gameState = 'ended';
clearInterval(aiActionTimer);
clearInterval(gameTimer);
const message = document.createElement('div');
message.className = 'game-message';
if (playerHealth <= 0) {
message.textContent = '你输了!';
message.classList.add('defeat-message');
} else {
message.textContent = '你赢了!';
message.classList.add('victory-message');
}
gameCanvas.appendChild(message);
setTimeout(() => {
message.remove();
restartGame();
}, 2000);
}
// 重新开始游戏
function restartGame() {
// 重置游戏状态
gameState = 'select';
playerHealth = 100;
aiHealth = 100;
playerEnergy = 100;
aiEnergy = 100;
playerPos = 100;
aiPos = window.innerWidth - 180;
isJumping = false;
isBlocking = false;
isAttacking = false;
isSpecialAttacking = false;
// 清除定时器
clearInterval(aiActionTimer);
clearInterval(gameTimer);
// 重置UI
player.classList.remove('attacking', 'hurt', 'blocking');
ai.classList.remove('attacking', 'hurt', 'blocking');
updatePositions();
updateHealthBars();
updateEnergyBars();
// 返回角色选择界面
gameArena.classList.remove('active');
characterSelect.classList.remove('hidden');
// 重置选择
selectedCharacter = null;
document.querySelectorAll('.character-card').forEach(card => {
card.classList.remove('selected');
});
startBtn.disabled = true;
}
// 按钮控制
document.getElementById('startBtn').addEventListener('click', startGame);
document.getElementById('restartBtn').addEventListener('click', restartGame);
// 方向键控制
let moveInterval = null;
document.getElementById('leftBtn').addEventListener('touchstart', (e) => {
e.preventDefault();
moveInterval = setInterval(() => movePlayer(-1), 50);
});
document.getElementById('leftBtn').addEventListener('touchend', () => {
clearInterval(moveInterval);
});
document.getElementById('rightBtn').addEventListener('touchstart', (e) => {
e.preventDefault();
moveInterval = setInterval(() => movePlayer(1), 50);
});
document.getElementById('rightBtn').addEventListener('touchend', () => {
clearInterval(moveInterval);
});
document.getElementById('upBtn').addEventListener('click', playerJump);
document.getElementById('downBtn').addEventListener('click', () => {
// 可以添加下蹲或其他动作
});
// 攻击按钮
document.getElementById('attackBtn').addEventListener('click', playerAttack);
document.getElementById('specialBtn').addEventListener('click', playerSpecialAttack);
document.getElementById('blockBtn').addEventListener('click', playerBlock);
document.getElementById('jumpBtn').addEventListener('click', playerJump);
// 键盘控制(用于测试)
document.addEventListener('keydown', (e) => {
if (gameState !== 'playing') return;
switch(e.key) {
case 'ArrowLeft':
movePlayer(-1);
break;
case 'ArrowRight':
movePlayer(1);
break;
case 'ArrowUp':
playerJump();
break;
case ' ':
case 'j':
playerAttack();
break;
case 'k':
playerSpecialAttack();
break;
case 'l':
playerBlock();
break;
}
});
// 初始化
initCharacterSelect();
</script>
</body>
</html>