前端 jQuery 简单实现一个网页格斗游戏示例
效果图
源代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>简易格斗游戏</title><script src="https://cdn.tailwindcss.com"></script><script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script><link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"><script>tailwind.config = {theme: {extend: {colors: {primary: '#3B82F6',secondary: '#10B981',danger: '#EF4444',warning: '#F59E0B',dark: '#1E293B',light: '#F8FAFC'},fontFamily: {sans: ['Inter', 'system-ui', 'sans-serif'],gaming: ['Rajdhani', 'sans-serif']}}}}</script><style type="text/tailwindcss">@layer utilities {.content-auto {content-visibility: auto;}.fighter {position: absolute;transition: transform 0.1s ease-out;transform-origin: center bottom;}.fighter-1 {background-color: #3B82F6;box-shadow: 0 0 15px rgba(59, 130, 246, 0.7);}.fighter-2 {background-color: #EF4444;box-shadow: 0 0 15px rgba(239, 68, 68, 0.7);}.health-bar {height: 10px;transition: width 0.3s ease-in-out;}.punch {animation: punch 0.2s ease-in-out;}.kick {animation: kick 0.2s ease-in-out;}.block {animation: block 0.3s ease-in-out;}.hurt {animation: hurt 0.2s ease-in-out;}.jump {animation: jump 0.5s ease-in-out;}@keyframes punch {0% { transform: translateX(0); }50% { transform: translateX(15px); }100% { transform: translateX(0); }}@keyframes kick {0% { transform: translateY(0); }50% { transform: translateY(-10px) rotateZ(-5deg); }100% { transform: translateY(0); }}@keyframes block {0% { transform: scale(1); opacity: 1; }50% { transform: scale(1.05); opacity: 0.8; }100% { transform: scale(1); opacity: 1; }}@keyframes hurt {0% { transform: translateX(0); background-color: inherit; }50% { transform: translateX(-10px); background-color: white; }100% { transform: translateX(0); background-color: inherit; }}@keyframes jump {0% { transform: translateY(0); }50% { transform: translateY(-50px); }100% { transform: translateY(0); }}.arena {background-image: linear-gradient(to bottom, #374151, #1F2937);position: relative;overflow: hidden;}.arena-floor {background-image: linear-gradient(to right, #4B5563, #6B7280);height: 20px;width: 100%;position: absolute;bottom: 0;}.control-btn {@apply w-16 h-16 flex items-center justify-center rounded-full bg-primary/20 text-primary transition-all duration-200 hover:bg-primary/40 active:scale-95;}}</style><link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@400;500;600;700&display=swap" rel="stylesheet">
</head>
<body class="bg-gradient-to-br from-light to-gray-200 min-h-screen flex flex-col items-center justify-center p-4 font-sans"><div class="max-w-3xl w-full mx-auto"><!-- 游戏标题 --><h1 class="text-[clamp(1.8rem,5vw,2.5rem)] font-bold text-center text-dark mb-4 font-gaming tracking-wider"><span class="text-primary">格斗</span><span class="text-danger">竞技场</span></h1><!-- 游戏状态和控制区 --><div class="flex flex-wrap justify-between items-center mb-4"><div class="flex items-center gap-4 w-full md:w-auto"><div class="bg-white p-3 rounded-lg shadow-md w-full md:w-48"><div class="flex justify-between items-center mb-1"><p class="text-sm font-medium text-gray-700">玩家1</p><p id="player1Score" class="text-lg font-bold text-primary">0</p></div><div class="w-full bg-gray-200 rounded-full h-3 overflow-hidden"><div id="player1Health" class="health-bar bg-primary rounded-full" style="width: 100%"></div></div></div><div class="bg-white p-3 rounded-lg shadow-md w-full md:w-48"><div class="flex justify-between items-center mb-1"><p class="text-sm font-medium text-gray-700">玩家2</p><p id="player2Score" class="text-lg font-bold text-danger">0</p></div><div class="w-full bg-gray-200 rounded-full h-3 overflow-hidden"><div id="player2Health" class="health-bar bg-danger rounded-full" style="width: 100%"></div></div></div></div><div class="flex gap-2 mt-4 md:mt-0"><button id="startBtn" class="px-4 py-2 bg-primary text-white rounded-lg shadow-md hover:bg-primary/90 transition-all duration-200"><i class="fa fa-play mr-1"></i>开始</button><button id="resetBtn" class="px-4 py-2 bg-gray-600 text-white rounded-lg shadow-md hover:bg-gray-700 transition-all duration-200"><i class="fa fa-refresh mr-1"></i>重置</button></div></div><!-- 游戏区域 --><div class="relative"><div id="arena" class="arena aspect-[16/9] rounded-lg shadow-xl border-4 border-dark"><!-- 玩家1 --><div id="player1" class="fighter fighter-1 w-16 h-32 rounded-t-lg" style="left: 15%; bottom: 20px;"></div><!-- 玩家2 --><div id="player2" class="fighter fighter-2 w-16 h-32 rounded-t-lg" style="right: 15%; bottom: 20px;"></div><!-- 地面 --><div class="arena-floor"></div><!-- 游戏开始遮罩 --><div id="startScreen" class="absolute inset-0 bg-dark/80 flex flex-col items-center justify-center z-10"><h2 class="text-3xl font-bold text-white mb-4 font-gaming">格斗竞技场</h2><p class="text-gray-300 mb-6 max-w-md text-center">使用 WASD 控制玩家1,使用方向键控制玩家2。<br>空格键出拳,X键踢腿,C键防御。率先获得3分获胜!</p><button id="playBtn" class="px-6 py-3 bg-primary text-white rounded-lg shadow-lg hover:bg-primary/90 transition-all duration-200 transform hover:scale-105 font-gaming text-lg"><i class="fa fa-play-circle mr-2"></i>开始战斗</button></div><!-- 回合结束遮罩 --><div id="roundOverScreen" class="absolute inset-0 bg-dark/80 flex flex-col items-center justify-center z-10 hidden"><h2 id="roundWinner" class="text-3xl font-bold text-white mb-4 font-gaming"></h2><button id="nextRoundBtn" class="px-6 py-3 bg-primary text-white rounded-lg shadow-lg hover:bg-primary/90 transition-all duration-200 transform hover:scale-105 font-gaming text-lg mt-4"><i class="fa fa-forward mr-2"></i>下一回合</button></div><!-- 游戏结束遮罩 --><div id="gameOverScreen" class="absolute inset-0 bg-dark/80 flex flex-col items-center justify-center z-10 hidden"><h2 id="gameWinner" class="text-3xl font-bold text-white mb-2 font-gaming"></h2><p class="text-xl text-white mb-6">最终比分: <span id="finalScore" class="font-bold"></span></p><button id="newGameBtn" class="px-6 py-3 bg-primary text-white rounded-lg shadow-lg hover:bg-primary/90 transition-all duration-200 transform hover:scale-105 font-gaming text-lg"><i class="fa fa-refresh mr-2"></i>新游戏</button></div><!-- 倒计时 --><div id="countdown" class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-[clamp(3rem,15vw,8rem)] font-bold text-white font-gaming opacity-0 transition-opacity 0.5s"></div></div><!-- 移动端控制按钮 --><div class="mt-6 grid grid-cols-5 gap-2 max-w-2xl mx-auto md:hidden"><div class="col-span-5 flex justify-center gap-4 mb-2"><button id="mobileP1Punch" class="control-btn bg-primary/30 text-primary"><i class="fa fa-hand-rock-o text-xl"></i></button><button id="mobileP1Kick" class="control-btn bg-danger/30 text-danger"><i class="fa fa-shoe-prints text-xl"></i></button><button id="mobileP1Block" class="control-btn bg-gray-600/30 text-gray-600"><i class="fa fa-shield text-xl"></i></button></div><div class="col-span-5 flex justify-center gap-4"><button id="mobileP2Punch" class="control-btn bg-primary/30 text-primary"><i class="fa fa-hand-rock-o text-xl"></i></button><button id="mobileP2Kick" class="control-btn bg-danger/30 text-danger"><i class="fa fa-shoe-prints text-xl"></i></button><button id="mobileP2Block" class="control-btn bg-gray-600/30 text-gray-600"><i class="fa fa-shield text-xl"></i></button></div><div></div><button id="mobileP1Up" class="control-btn mx-auto"><i class="fa fa-chevron-up text-xl"></i></button><div></div><button id="mobileP1Left" class="control-btn"><i class="fa fa-chevron-left text-xl"></i></button><button id="mobileP1Down" class="control-btn mx-auto"><i class="fa fa-chevron-down text-xl"></i></button><button id="mobileP1Right" class="control-btn"><i class="fa fa-chevron-right text-xl"></i></button><div></div><button id="mobileP2Up" class="control-btn mx-auto"><i class="fa fa-chevron-up text-xl"></i></button><div></div><button id="mobileP2Left" class="control-btn"><i class="fa fa-chevron-left text-xl"></i></button><button id="mobileP2Down" class="control-btn mx-auto"><i class="fa fa-chevron-down text-xl"></i></button><button id="mobileP2Right" class="control-btn"><i class="fa fa-chevron-right text-xl"></i></button><div></div></div></div><!-- 游戏说明 --><div class="mt-6 p-4 bg-white rounded-lg shadow-md"><h3 class="font-semibold text-lg mb-2 text-dark">操作说明</h3><div class="grid grid-cols-1 md:grid-cols-2 gap-4"><div><h4 class="font-medium text-primary mb-2">玩家1 (蓝色)</h4><ul class="text-gray-600 space-y-1"><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">W</kbd> - 跳跃</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">A</kbd> - 向左移动</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">D</kbd> - 向右移动</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">空格</kbd> - 出拳</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">X</kbd> - 踢腿</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">C</kbd> - 防御</li></ul></div><div><h4 class="font-medium text-danger mb-2">玩家2 (红色)</h4><ul class="text-gray-600 space-y-1"><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">↑</kbd> - 跳跃</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">←</kbd> - 向左移动</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">→</kbd> - 向右移动</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">L</kbd> - 出拳</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">.</kbd> - 踢腿</li><li><i class="fa fa-keyboard-o mr-1"></i> <kbd class="px-2 py-1 bg-gray-100 rounded text-sm">/</kbd> - 防御</li></ul></div></div></div></div><script>$(document).ready(function() {// 游戏配置const config = {arenaWidth: $('#arena').width(),arenaHeight: $('#arena').height(),fighterWidth: 64, // 玩家宽度 (像素)fighterHeight: 128, // 玩家高度 (像素)moveSpeed: 5, // 移动速度 (像素/帧)jumpHeight: 100, // 跳跃高度 (像素)punchDamage: 10, // 拳伤害kickDamage: 15, // 踢伤害blockEfficiency: 0.3, // 防御效率 (0-1)scoreToWin: 3, // 获胜所需分数roundTime: 90, // 每回合时间 (秒)gravity: 2, // 重力加速度jumpPower: 18, // 跳跃力度knockback: 15, // 击退距离cooldown: 300, // 攻击冷却时间 (毫秒)};// 游戏状态const gameState = {isRunning: false,isPaused: false,round: 1,player1: {element: $('#player1'),x: 15, // 百分比位置y: 0, // 垂直位置 (0是地面)direction: 1, // 1 = 右, -1 = 左health: 100,score: 0,isJumping: false,velocityY: 0,isBlocking: false,lastAttackTime: 0,controls: {up: 87, // Wleft: 65, // Aright: 68, // Dpunch: 32, // 空格kick: 88, // Xblock: 67 // C}},player2: {element: $('#player2'),x: 85, // 百分比位置y: 0,direction: -1, // 面向玩家1health: 100,score: 0,isJumping: false,velocityY: 0,isBlocking: false,lastAttackTime: 0,controls: {up: 38, // 上箭头left: 37, // 左箭头right: 39, // 右箭头punch: 76, // Lkick: 190, // .block: 191 // /}},keys: {}, // 当前按下的键gameLoop: null,roundTime: config.roundTime,timeDisplay: null,countdown: 3,countdownTimer: null};// DOM元素const $arena = $('#arena');const $player1 = $('#player1');const $player2 = $('#player2');const $player1Health = $('#player1Health');const $player2Health = $('#player2Health');const $player1Score = $('#player1Score');const $player2Score = $('#player2Score');const $startBtn = $('#startBtn');const $resetBtn = $('#resetBtn');const $startScreen = $('#startScreen');const $roundOverScreen = $('#roundOverScreen');const $roundWinner = $('#roundWinner');const $nextRoundBtn = $('#nextRoundBtn');const $gameOverScreen = $('#gameOverScreen');const $gameWinner = $('#gameWinner');const $finalScore = $('#finalScore');const $newGameBtn = $('#newGameBtn');const $playBtn = $('#playBtn');const $countdown = $('#countdown');// 更新竞技场尺寸function updateArenaDimensions() {config.arenaWidth = $arena.width();config.arenaHeight = $arena.height();}// 设置玩家位置function setPlayerPosition(player) {// 计算像素位置const x = (player.x / 100) * (config.arenaWidth - config.fighterWidth);const y = config.arenaHeight - config.fighterHeight - 20 - player.y; // 20是地面高度// 应用位置player.element.css({left: `${x}px`,bottom: `${y}px`,transform: `scaleX(${player.direction})`});}// 初始化玩家function initPlayers() {gameState.player1.x = 15;gameState.player1.y = 0;gameState.player1.direction = 1;gameState.player1.health = 100;gameState.player1.isJumping = false;gameState.player1.velocityY = 0;gameState.player1.isBlocking = false;gameState.player2.x = 85;gameState.player2.y = 0;gameState.player2.direction = -1;gameState.player2.health = 100;gameState.player2.isJumping = false;gameState.player2.velocityY = 0;gameState.player2.isBlocking = false;updateHealthBars();setPlayerPosition(gameState.player1);setPlayerPosition(gameState.player2);}// 更新生命值条function updateHealthBars() {$player1Health.css('width', `${gameState.player1.health}%`);$player2Health.css('width', `${gameState.player2.health}%`);}// 更新分数显示function updateScores() {$player1Score.text(gameState.player1.score);$player2Score.text(gameState.player2.score);}// 检查碰撞function checkCollision(player1, player2) {// 计算像素位置const p1X = (player1.x / 100) * (config.arenaWidth - config.fighterWidth);const p2X = (player2.x / 100) * (config.arenaWidth - config.fighterWidth);// 碰撞检测 (简化版)const collisionDistance = config.fighterWidth * 0.7; // 稍微缩小碰撞范围return Math.abs(p1X - p2X) < collisionDistance;}// 应用攻击function applyAttack(attacker, defender, damage) {const now = Date.now();// 检查冷却时间if (now - attacker.lastAttackTime < config.cooldown) {return false;}// 记录攻击时间attacker.lastAttackTime = now;// 检查是否碰撞if (!checkCollision(attacker, defender)) {return false;}// 检查是否防御if (defender.isBlocking) {damage *= config.blockEfficiency; // 减少伤害// 防御动画defender.element.addClass('block');setTimeout(() => defender.element.removeClass('block'), 300);} else {// 受伤动画defender.element.addClass('hurt');setTimeout(() => defender.element.removeClass('hurt'), 200);// 击退效果const knockbackDir = attacker.direction;defender.x += knockbackDir * config.knockback / (config.arenaWidth / 100);// 确保不超出边界defender.x = Math.max(0, Math.min(100, defender.x));}// 减少生命值defender.health = Math.max(0, defender.health - damage);updateHealthBars();// 检查是否生命值归零if (defender.health <= 0) {endRound(attacker);}return true;}// 玩家移动function movePlayers() {// 玩家1移动const p1 = gameState.player1;if (gameState.keys[p1.controls.left]) {p1.x = Math.max(0, p1.x - config.moveSpeed / (config.arenaWidth / 100));p1.direction = -1;}if (gameState.keys[p1.controls.right]) {p1.x = Math.min(100, p1.x + config.moveSpeed / (config.arenaWidth / 100));p1.direction = 1;}if (gameState.keys[p1.controls.up] && !p1.isJumping) {p1.isJumping = true;p1.velocityY = -config.jumpPower;p1.element.addClass('jump');setTimeout(() => p1.element.removeClass('jump'), 500);}if (gameState.keys[p1.controls.block]) {p1.isBlocking = true;} else {p1.isBlocking = false;}if (gameState.keys[p1.controls.punch]) {if (applyAttack(p1, gameState.player2, config.punchDamage)) {p1.element.addClass('punch');setTimeout(() => p1.element.removeClass('punch'), 200);}}if (gameState.keys[p1.controls.kick]) {if (applyAttack(p1, gameState.player2, config.kickDamage)) {p1.element.addClass('kick');setTimeout(() => p1.element.removeClass('kick'), 200);}}// 玩家2移动const p2 = gameState.player2;if (gameState.keys[p2.controls.left]) {p2.x = Math.max(0, p2.x - config.moveSpeed / (config.arenaWidth / 100));p2.direction = -1;}if (gameState.keys[p2.controls.right]) {p2.x = Math.min(100, p2.x + config.moveSpeed / (config.arenaWidth / 100));p2.direction = 1;}if (gameState.keys[p2.controls.up] && !p2.isJumping) {p2.isJumping = true;p2.velocityY = -config.jumpPower;p2.element.addClass('jump');setTimeout(() => p2.element.removeClass('jump'), 500);}if (gameState.keys[p2.controls.block]) {p2.isBlocking = true;} else {p2.isBlocking = false;}if (gameState.keys[p2.controls.punch]) {if (applyAttack(p2, gameState.player1, config.punchDamage)) {p2.element.addClass('punch');setTimeout(() => p2.element.removeClass('punch'), 200);}}if (gameState.keys[p2.controls.kick]) {if (applyAttack(p2, gameState.player1, config.kickDamage)) {p2.element.addClass('kick');setTimeout(() => p2.element.removeClass('kick'), 200);}}// 应用重力applyGravity(p1);applyGravity(p2);// 更新位置setPlayerPosition(p1);setPlayerPosition(p2);}// 应用重力function applyGravity(player) {if (player.isJumping) {player.velocityY += config.gravity;player.y += player.velocityY;// 落地检测if (player.y >= 0) {player.y = 0;player.velocityY = 0;player.isJumping = false;}}}// 开始倒计时function startCountdown() {$countdown.text(gameState.countdown);$countdown.css('opacity', '1');gameState.countdownTimer = setInterval(() => {gameState.countdown--;$countdown.text(gameState.countdown);if (gameState.countdown <= 0) {clearInterval(gameState.countdownTimer);$countdown.css('opacity', '0');startRound();}}, 1000);}// 开始回合function startRound() {initPlayers();gameState.isRunning = true;gameState.roundTime = config.roundTime;// 开始游戏循环if (gameState.gameLoop) {clearInterval(gameState.gameLoop);}gameState.gameLoop = setInterval(gameLoop, 16); // 约60FPS// 开始倒计时if (gameState.timeDisplay) {clearInterval(gameState.timeDisplay);}gameState.timeDisplay = setInterval(updateRoundTime, 1000);}// 结束回合function endRound(winner) {gameState.isRunning = false;clearInterval(gameState.gameLoop);clearInterval(gameState.timeDisplay);// 增加分数winner.score++;updateScores();// 显示回合结束屏幕$roundWinner.text(`${winner === gameState.player1 ? '玩家1' : '玩家2'} 获胜!`);$roundOverScreen.removeClass('hidden');// 检查是否有玩家达到获胜分数if (gameState.player1.score >= config.scoreToWin || gameState.player2.score >= config.scoreToWin) {setTimeout(endGame, 1000);}}// 结束游戏function endGame() {$roundOverScreen.addClass('hidden');// 确定获胜者const winner = gameState.player1.score > gameState.player2.score ? gameState.player1 : gameState.player2;$gameWinner.text(`${winner === gameState.player1 ? '玩家1' : '玩家2'} 赢得比赛!`);$finalScore.text(`${gameState.player1.score} - ${gameState.player2.score}`);// 显示游戏结束屏幕$gameOverScreen.removeClass('hidden');}// 更新回合时间function updateRoundTime() {gameState.roundTime--;// 时间到,结束回合if (gameState.roundTime <= 0) {// 确定生命值较高的玩家获胜const winner = gameState.player1.health > gameState.player2.health ? gameState.player1 : gameState.player2;endRound(winner);}}// 游戏主循环function gameLoop() {if (!gameState.isRunning || gameState.isPaused) return;movePlayers();}// 开始新游戏function startGame() {gameState.round = 1;gameState.player1.score = 0;gameState.player2.score = 0;updateScores();$startScreen.addClass('hidden');$gameOverScreen.addClass('hidden');startCountdown();}// 重置游戏function resetGame() {clearInterval(gameState.gameLoop);clearInterval(gameState.timeDisplay);clearInterval(gameState.countdownTimer);gameState.isRunning = false;gameState.isPaused = false;gameState.countdown = 3;initPlayers();$startScreen.removeClass('hidden');$roundOverScreen.addClass('hidden');$gameOverScreen.addClass('hidden');}// 初始化游戏function initGame() {updateArenaDimensions();initPlayers();// 绑定事件$(document).keydown((e) => {gameState.keys[e.keyCode] = true;});$(document).keyup((e) => {gameState.keys[e.keyCode] = false;});$startBtn.click(startGame);$resetBtn.click(resetGame);$playBtn.click(startGame);$nextRoundBtn.click(() => {$roundOverScreen.addClass('hidden');gameState.countdown = 3;startCountdown();});$newGameBtn.click(resetGame);// 移动端控制$('#mobileP1Up').mousedown(() => gameState.keys[gameState.player1.controls.up] = true).mouseup(() => gameState.keys[gameState.player1.controls.up] = false);$('#mobileP1Left').mousedown(() => gameState.keys[gameState.player1.controls.left] = true).mouseup(() => gameState.keys[gameState.player1.controls.left] = false);$('#mobileP1Right').mousedown(() => gameState.keys[gameState.player1.controls.right] = true).mouseup(() => gameState.keys[gameState.player1.controls.right] = false);$('#mobileP1Punch').mousedown(() => gameState.keys[gameState.player1.controls.punch] = true).mouseup(() => gameState.keys[gameState.player1.controls.punch] = false);$('#mobileP1Kick').mousedown(() => gameState.keys[gameState.player1.controls.kick] = true).mouseup(() => gameState.keys[gameState.player1.controls.kick] = false);$('#mobileP1Block').mousedown(() => gameState.keys[gameState.player1.controls.block] = true).mouseup(() => gameState.keys[gameState.player1.controls.block] = false);$('#mobileP2Up').mousedown(() => gameState.keys[gameState.player2.controls.up] = true).mouseup(() => gameState.keys[gameState.player2.controls.up] = false);$('#mobileP2Left').mousedown(() => gameState.keys[gameState.player2.controls.left] = true).mouseup(() => gameState.keys[gameState.player2.controls.left] = false);$('#mobileP2Right').mousedown(() => gameState.keys[gameState.player2.controls.right] = true).mouseup(() => gameState.keys[gameState.player2.controls.right] = false);$('#mobileP2Punch').mousedown(() => gameState.keys[gameState.player2.controls.punch] = true).mouseup(() => gameState.keys[gameState.player2.controls.punch] = false);$('#mobileP2Kick').mousedown(() => gameState.keys[gameState.player2.controls.kick] = true).mouseup(() => gameState.keys[gameState.player2.controls.kick] = false);$('#mobileP2Block').mousedown(() => gameState.keys[gameState.player2.controls.block] = true).mouseup(() => gameState.keys[gameState.player2.controls.block] = false);// 窗口大小改变时更新竞技场尺寸$(window).resize(updateArenaDimensions);}// 启动游戏initGame();});</script>
</body>
</html>
这个格斗游戏示例具有以下特点:
- 双人对战系统 - 支持两名玩家同时控制角色进行对战
- 完整的动作系统 - 包含移动、跳跃、出拳、踢腿和防御等动作
- 回合制游戏 - 先获得 3 分的玩家获胜
- 生命值和计分系统 - 显示玩家生命值和得分
- 键盘和触屏控制 - 支持键盘操作和移动端触屏按钮
- 物理系统 - 包含重力和碰撞检测
- 视觉反馈 - 攻击、防御和受伤都有相应的动画效果
- 游戏状态管理 - 包含倒计时、回合结束和游戏结束状态
玩家 1 使用 WASD 控制移动,空格键出拳,X 键踢腿,C 键防御;玩家 2 使用方向键控制移动,L 键出拳,. 键踢腿,/ 键防御。游戏中先获得 3 分的玩家获胜。
这个格斗游戏使用了以下外部资源和插件:
-
Tailwind CSS
- 版本:v3
- 通过 CDN 引入:https://cdn.tailwindcss.com
- 作用:提供工具类 CSS,用于快速构建响应式布局和视觉效果
-
Font Awesome
- 版本:v4.7.0
- 通过 CDN 引入:https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css
- 作用:提供游戏中使用的各种图标(如按钮图标、控制说明图标)
-
jQuery
- 版本:v3.6.0
- 通过 CDN 引入:https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
- 作用:简化 DOM 操作和事件处理,实现游戏逻辑
-
Rajdhani 字体
- 通过 Google Fonts 引入:https://fonts.googleapis.com/css2?family=Rajdhani:wght@400;500;600;700&display=swap
- 作用:提供游戏标题和界面的专用字体,增强游戏风格
这些资源都是通过 CDN 直接引入的,无需额外安装,确保了游戏的快速加载和兼容性。游戏的核心逻辑完全基于原生 JavaScript 实现,没有使用其他游戏引擎或框架。