角色选择系统:

三位不同风格的拳击手(闪电李、重炮王、火焰拳)

每个角色有独特的速度和力量属性

战斗系统:

四种攻击方式:刺拳、勾拳、上勾拳、必杀技

不同攻击造成不同范围的伤害

对手会随机选择攻击方式反击

视觉效果:

动态生命值条

打击特效动画

拳击台场景绘制

响应式设计适应不同屏幕尺寸

控制方式:

鼠标点击按钮攻击

键盘快捷键(Q、W、E、R)控制攻击

游戏状态:

生命值系统

胜负判定

游戏结束提示

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拳王争霸赛</title>
    <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&family=Roboto:wght@400;700&display=swap" rel="stylesheet">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Roboto', sans-serif;
            background: linear-gradient(135deg, #1a1a2e, #16213e);
            color: #fff;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 20px;
            overflow-x: hidden;
        }
        
        header {
            text-align: center;
            margin: 20px 0;
            width: 100%;
        }
        
        h1 {
            font-family: 'Orbitron', sans-serif;
            font-size: 3.5rem;
            text-transform: uppercase;
            background: linear-gradient(to right, #ff512f, #f09819);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            text-shadow: 0 0 10px rgba(240, 152, 25, 0.5);
            margin-bottom: 10px;
            letter-spacing: 3px;
        }
        
        .subtitle {
            font-size: 1.2rem;
            color: #e6e6e6;
            max-width: 800px;
            margin: 0 auto;
            line-height: 1.6;
        }
        
        .game-container {
            display: flex;
            flex-direction: column;
            width: 100%;
            max-width: 1000px;
            background: rgba(10, 15, 35, 0.7);
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            margin: 20px 0;
            backdrop-filter: blur(5px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .game-stats {
            display: flex;
            justify-content: space-between;
            padding: 15px;
            background: rgba(0, 0, 0, 0.4);
            border-radius: 10px;
            margin-bottom: 20px;
        }
        
        .player-stats, .opponent-stats {
            display: flex;
            flex-direction: column;
            align-items: center;
            width: 45%;
        }
        
        .player-name, .opponent-name {
            font-size: 1.8rem;
            font-weight: bold;
            margin-bottom: 10px;
            text-transform: uppercase;
        }
        
        .player-name {
            color: #4ecdc4;
        }
        
        .opponent-name {
            color: #ff6b6b;
        }
        
        .health-bar {
            width: 100%;
            height: 30px;
            background: #333;
            border-radius: 15px;
            overflow: hidden;
            margin-bottom: 10px;
            border: 2px solid #444;
        }
        
        .health-fill {
            height: 100%;
            transition: width 0.3s ease;
        }
        
        .player-health {
            background: linear-gradient(to right, #4ecdc4, #1a936f);
            width: 100%;
        }
        
        .opponent-health {
            background: linear-gradient(to right, #ff6b6b, #ff2e63);
            width: 100%;
        }
        
        .health-text {
            font-size: 1.2rem;
            font-weight: bold;
        }
        
        .game-area {
            display: flex;
            justify-content: space-between;
            height: 400px;
            position: relative;
            background: linear-gradient(to bottom, #2c3e50, #1c2833);
            border-radius: 10px;
            overflow: hidden;
            margin: 20px 0;
            border: 3px solid #34495e;
        }
        
        canvas {
            width: 100%;
            height: 100%;
        }
        
        .controls {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-top: 20px;
            flex-wrap: wrap;
        }
        
        .btn {
            padding: 14px 30px;
            font-size: 1.1rem;
            font-weight: bold;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            transition: all 0.3s ease;
            text-transform: uppercase;
            letter-spacing: 1px;
            outline: none;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }
        
        .btn:hover {
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
        }
        
        .btn:active {
            transform: translateY(1px);
        }
        
        .jab {
            background: linear-gradient(to right, #3498db, #2980b9);
            color: white;
        }
        
        .hook {
            background: linear-gradient(to right, #e74c3c, #c0392b);
            color: white;
        }
        
        .uppercut {
            background: linear-gradient(to right, #f39c12, #d35400);
            color: white;
        }
        
        .special {
            background: linear-gradient(to right, #9b59b6, #8e44ad);
            color: white;
        }
        
        .game-message {
            text-align: center;
            font-size: 1.8rem;
            font-weight: bold;
            height: 60px;
            margin: 20px 0;
            padding: 10px;
            color: #f1c40f;
            text-shadow: 0 0 10px rgba(241, 196, 15, 0.7);
        }
        
        .character-selection {
            display: flex;
            justify-content: space-around;
            margin: 20px 0;
            flex-wrap: wrap;
            gap: 20px;
        }
        
        .character {
            display: flex;
            flex-direction: column;
            align-items: center;
            cursor: pointer;
            padding: 15px;
            border-radius: 10px;
            transition: all 0.3s ease;
            width: 180px;
            background: rgba(30, 40, 60, 0.6);
            border: 2px solid transparent;
        }
        
        .character:hover {
            background: rgba(50, 70, 100, 0.8);
            transform: translateY(-5px);
        }
        
        .character.selected {
            border-color: #f1c40f;
            background: rgba(60, 90, 130, 0.8);
            box-shadow: 0 0 20px rgba(241, 196, 15, 0.5);
        }
        
        .character-img {
            width: 120px;
            height: 120px;
            border-radius: 50%;
            margin-bottom: 10px;
            background: #34495e;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 3rem;
        }
        
        .character-name {
            font-size: 1.3rem;
            font-weight: bold;
            margin-bottom: 5px;
        }
        
        .character-stats {
            font-size: 0.9rem;
            color: #bbb;
            text-align: center;
        }
        
        .instructions {
            background: rgba(0, 0, 0, 0.4);
            padding: 20px;
            border-radius: 10px;
            margin-top: 20px;
            width: 100%;
            max-width: 1000px;
        }
        
        .instructions h2 {
            color: #f1c40f;
            margin-bottom: 15px;
            text-align: center;
        }
        
        .instructions ul {
            padding-left: 20px;
            line-height: 1.8;
        }
        
        .instructions li {
            margin-bottom: 8px;
        }
        
        @media (max-width: 768px) {
            h1 {
                font-size: 2.5rem;
            }
            
            .game-area {
                height: 300px;
            }
            
            .character {
                width: 140px;
            }
            
            .character-img {
                width: 90px;
                height: 90px;
                font-size: 2rem;
            }
            
            .btn {
                padding: 12px 20px;
                font-size: 1rem;
            }
        }
        
        @media (max-width: 480px) {
            h1 {
                font-size: 2rem;
            }
            
            .game-stats {
                flex-direction: column;
                align-items: center;
                gap: 20px;
            }
            
            .player-stats, .opponent-stats {
                width: 100%;
            }
            
            .controls {
                gap: 10px;
            }
            
            .btn {
                padding: 10px 15px;
                font-size: 0.9rem;
            }
        }
        
        .punch-effect {
            position: absolute;
            width: 100px;
            height: 100px;
            background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,200,0,0) 70%);
            border-radius: 50%;
            pointer-events: none;
            animation: punch 0.3s forwards;
            z-index: 10;
        }
        
        @keyframes punch {
            0% { transform: scale(0.3); opacity: 1; }
            100% { transform: scale(1.5); opacity: 0; }
        }
    </style>
</head>
<body>
    <header>
        <h1>拳王争霸赛</h1>
        <p class="subtitle">选择你的拳击手,击败强大的对手,成为新一代拳王!使用不同的攻击组合来战胜对手,注意你的生命值!</p>
    </header>
    
    <div class="game-container">
        <div class="game-stats">
            <div class="player-stats">
                <div class="player-name" id="player-name">拳击手</div>
                <div class="health-bar">
                    <div class="health-fill player-health" id="player-health"></div>
                </div>
                <div class="health-text">生命值: <span id="player-health-text">100</span></div>
            </div>
            
            <div class="opponent-stats">
                <div class="opponent-name" id="opponent-name">钢铁迈克</div>
                <div class="health-bar">
                    <div class="health-fill opponent-health" id="opponent-health"></div>
                </div>
                <div class="health-text">生命值: <span id="opponent-health-text">100</span></div>
            </div>
        </div>
        
        <div class="game-message" id="game-message">选择角色开始比赛!</div>
        
        <div class="character-selection">
            <div class="character" data-id="1">
                <div class="character-img">🥊</div>
                <div class="character-name">闪电李</div>
                <div class="character-stats">速度: ⭐⭐⭐⭐<br>力量: ⭐⭐</div>
            </div>
            
            <div class="character" data-id="2">
                <div class="character-img">💥</div>
                <div class="character-name">重炮王</div>
                <div class="character-stats">速度: ⭐⭐<br>力量: ⭐⭐⭐⭐</div>
            </div>
            
            <div class="character" data-id="3">
                <div class="character-img">🔥</div>
                <div class="character-name">火焰拳</div>
                <div class="character-stats">速度: ⭐⭐⭐<br>力量: ⭐⭐⭐</div>
            </div>
        </div>
        
        <div class="game-area" id="game-area">
            <canvas id="game-canvas"></canvas>
        </div>
        
        <div class="controls">
            <button class="btn jab" id="jab">刺拳 (Q)</button>
            <button class="btn hook" id="hook">勾拳 (W)</button>
            <button class="btn uppercut" id="uppercut">上勾拳 (E)</button>
            <button class="btn special" id="special">必杀技 (R)</button>
        </div>
    </div>
    
    <div class="instructions">
        <h2>游戏指南</h2>
        <ul>
            <li>从三位拳击手中选择一位开始比赛</li>
            <li>使用四个攻击按钮或键盘按键(Q, W, E, R)发动攻击</li>
            <li>不同的攻击方式造成不同的伤害:刺拳(5-8), 勾拳(8-12), 上勾拳(10-15), 必杀技(15-25)</li>
            <li>对手也会反击,注意你的生命值!</li>
            <li>击败对手成为拳王!</li>
        </ul>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // 游戏状态
            const gameState = {
                playerHealth: 100,
                opponentHealth: 100,
                selectedCharacter: null,
                gameActive: false,
                playerX: 150,
                opponentX: 650,
                punchPosition: {x: 0, y: 0}
            };
            
            // DOM 元素
            const playerHealthEl = document.getElementById('player-health');
            const opponentHealthEl = document.getElementById('opponent-health');
            const playerHealthText = document.getElementById('player-health-text');
            const opponentHealthText = document.getElementById('opponent-health-text');
            const gameMessage = document.getElementById('game-message');
            const canvas = document.getElementById('game-canvas');
            const ctx = canvas.getContext('2d');
            const gameArea = document.getElementById('game-area');
            
            // 设置Canvas尺寸
            function setupCanvas() {
                canvas.width = gameArea.clientWidth;
                canvas.height = gameArea.clientHeight;
            }
            
            // 初始化
            setupCanvas();
            window.addEventListener('resize', setupCanvas);
            
            // 绘制游戏场景
            function drawGameScene() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                
                // 绘制背景
                const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
                gradient.addColorStop(0, "#2c3e50");
                gradient.addColorStop(1, "#1c2833");
                ctx.fillStyle = gradient;
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                
                // 绘制拳击台
                ctx.fillStyle = '#8b0000';
                ctx.fillRect(50, 50, canvas.width - 100, canvas.height - 100);
                
                ctx.strokeStyle = '#ffffff';
                ctx.lineWidth = 3;
                ctx.strokeRect(50, 50, canvas.width - 100, canvas.height - 100);
                
                // 绘制中线
                ctx.beginPath();
                ctx.moveTo(canvas.width/2, 50);
                ctx.lineTo(canvas.width/2, canvas.height - 50);
                ctx.strokeStyle = '#ffffff';
                ctx.lineWidth = 2;
                ctx.setLineDash([10, 10]);
                ctx.stroke();
                ctx.setLineDash([]);
                
                // 绘制选手
                drawFighter(gameState.playerX, 200, '#3498db', 'left');
                drawFighter(gameState.opponentX, 200, '#e74c3c', 'right');
            }
            
            // 绘制拳击手
            function drawFighter(x, y, color, direction) {
                // 身体
                ctx.fillStyle = color;
                ctx.beginPath();
                ctx.arc(x, y, 40, 0, Math.PI * 2);
                ctx.fill();
                
                // 头部
                ctx.fillStyle = '#ffdbac';
                ctx.beginPath();
                ctx.arc(x, y - 70, 30, 0, Math.PI * 2);
                ctx.fill();
                
                // 眼睛
                ctx.fillStyle = '#000';
                const eyeOffset = direction === 'left' ? -10 : 10;
                ctx.beginPath();
                ctx.arc(x + eyeOffset, y - 75, 5, 0, Math.PI * 2);
                ctx.fill();
                
                // 嘴巴
                ctx.strokeStyle = '#000';
                ctx.lineWidth = 2;
                ctx.beginPath();
                ctx.arc(x, y - 65, 10, 0, Math.PI);
                ctx.stroke();
                
                // 手臂
                ctx.fillStyle = color;
                ctx.fillRect(x - 50, y - 40, 100, 20);
                
                // 拳头
                ctx.fillStyle = '#ffdbac';
                if (direction === 'left') {
                    ctx.beginPath();
                    ctx.arc(x - 60, y - 30, 15, 0, Math.PI * 2);
                    ctx.fill();
                } else {
                    ctx.beginPath();
                    ctx.arc(x + 60, y - 30, 15, 0, Math.PI * 2);
                    ctx.fill();
                }
                
                // 腿
                ctx.fillStyle = color;
                ctx.fillRect(x - 15, y + 40, 30, 60);
            }
            
            // 选择角色
            const characters = document.querySelectorAll('.character');
            characters.forEach(char => {
                char.addEventListener('click', () => {
                    if (gameState.gameActive) return;
                    
                    characters.forEach(c => c.classList.remove('selected'));
                    char.classList.add('selected');
                    
                    gameState.selectedCharacter = char.dataset.id;
                    gameState.gameActive = true;
                    gameState.playerHealth = 100;
                    gameState.opponentHealth = 100;
                    
                    gameMessage.textContent = "比赛开始!击败对手!";
                    updateHealthBars();
                });
            });
            
            // 更新生命条
            function updateHealthBars() {
                playerHealthEl.style.width = `${gameState.playerHealth}%`;
                opponentHealthEl.style.width = `${gameState.opponentHealth}%`;
                playerHealthText.textContent = gameState.playerHealth;
                opponentHealthText.textContent = gameState.opponentHealth;
                
                // 检查游戏结束条件
                if (gameState.playerHealth <= 0) {
                    gameState.playerHealth = 0;
                    gameState.gameActive = false;
                    gameMessage.textContent = "你被击败了!再试一次!";
                    setTimeout(resetGame, 3000);
                } else if (gameState.opponentHealth <= 0) {
                    gameState.opponentHealth = 0;
                    gameState.gameActive = false;
                    gameMessage.textContent = "恭喜!你成为了新拳王!";
                    setTimeout(resetGame, 3000);
                }
            }
            
            // 重置游戏
            function resetGame() {
                gameState.gameActive = false;
                gameMessage.textContent = "选择角色开始比赛!";
                characters.forEach(c => c.classList.remove('selected'));
            }
            
            // 攻击功能
            function attack(type) {
                if (!gameState.gameActive) return;
                
                // 计算伤害
                let damage = 0;
                switch(type) {
                    case 'jab':
                        damage = Math.floor(Math.random() * 4) + 5;
                        gameState.punchPosition = {x: gameState.playerX + 100, y: 170};
                        break;
                    case 'hook':
                        damage = Math.floor(Math.random() * 5) + 8;
                        gameState.punchPosition = {x: gameState.playerX + 120, y: 170};
                        break;
                    case 'uppercut':
                        damage = Math.floor(Math.random() * 6) + 10;
                        gameState.punchPosition = {x: gameState.playerX + 110, y: 150};
                        break;
                    case 'special':
                        damage = Math.floor(Math.random() * 11) + 15;
                        gameState.punchPosition = {x: gameState.playerX + 130, y: 140};
                        break;
                }
                
                // 创建打击效果
                createPunchEffect(gameState.punchPosition.x, gameState.punchPosition.y);
                
                // 应用伤害
                gameState.opponentHealth -= damage;
                if (gameState.opponentHealth < 0) gameState.opponentHealth = 0;
                
                gameMessage.textContent = `你使用了${getAttackName(type)},造成${damage}点伤害!`;
                updateHealthBars();
                
                // 对手反击
                setTimeout(() => {
                    if (gameState.gameActive) {
                        opponentAttack();
                    }
                }, 1000);
            }
            
            // 获取攻击名称
            function getAttackName(type) {
                const names = {
                    'jab': '刺拳',
                    'hook': '勾拳',
                    'uppercut': '上勾拳',
                    'special': '必杀技'
                };
                return names[type];
            }
            
            // 对手攻击
            function opponentAttack() {
                if (!gameState.gameActive) return;
                
                const attacks = ['jab', 'hook', 'uppercut'];
                const attackType = attacks[Math.floor(Math.random() * attacks.length)];
                
                let damage = 0;
                switch(attackType) {
                    case 'jab':
                        damage = Math.floor(Math.random() * 4) + 4;
                        gameState.punchPosition = {x: gameState.opponentX - 100, y: 170};
                        break;
                    case 'hook':
                        damage = Math.floor(Math.random() * 5) + 7;
                        gameState.punchPosition = {x: gameState.opponentX - 120, y: 170};
                        break;
                    case 'uppercut':
                        damage = Math.floor(Math.random() * 6) + 9;
                        gameState.punchPosition = {x: gameState.opponentX - 110, y: 150};
                        break;
                }
                
                createPunchEffect(gameState.punchPosition.x, gameState.punchPosition.y);
                
                gameState.playerHealth -= damage;
                if (gameState.playerHealth < 0) gameState.playerHealth = 0;
                
                gameMessage.textContent = `对手使用了${getAttackName(attackType)},造成${damage}点伤害!`;
                updateHealthBars();
            }
            
            // 创建打击效果
            function createPunchEffect(x, y) {
                const effect = document.createElement('div');
                effect.classList.add('punch-effect');
                effect.style.left = `${x - 50}px`;
                effect.style.top = `${y - 50}px`;
                gameArea.appendChild(effect);
                
                setTimeout(() => {
                    effect.remove();
                }, 300);
            }
            
            // 绑定攻击按钮
            document.getElementById('jab').addEventListener('click', () => attack('jab'));
            document.getElementById('hook').addEventListener('click', () => attack('hook'));
            document.getElementById('uppercut').addEventListener('click', () => attack('uppercut'));
            document.getElementById('special').addEventListener('click', () => attack('special'));
            
            // 键盘控制
            document.addEventListener('keydown', (e) => {
                if (!gameState.gameActive) return;
                
                switch(e.key.toLowerCase()) {
                    case 'q':
                        attack('jab');
                        break;
                    case 'w':
                        attack('hook');
                        break;
                    case 'e':
                        attack('uppercut');
                        break;
                    case 'r':
                        attack('special');
                        break;
                }
            });
            
            // 动画循环
            function gameLoop() {
                drawGameScene();
                requestAnimationFrame(gameLoop);
            }
            
            // 启动游戏循环
            gameLoop();
        });
    </script>
</body>
</html>