用html5写一个宠物小精灵游戏
我来为您创建一个完整的HTML5宠物小精灵风格的游戏。这是一个功能齐全的小游戏,包含了捕捉、战斗和训练系统。```html
<!DOCTYPE html>
<html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>宠物小精灵冒险</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.game-container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.2);
width: 90%;
max-width: 800px;
padding: 30px;
}
.game-header {
text-align: center;
margin-bottom: 30px;
}
.game-header h1 {
color: #333;
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
}
.game-stats {
display: flex;
justify-content: space-around;
margin-bottom: 30px;
background: #f8f9fa;
padding: 15px;
border-radius: 10px;
}
.stat-item {
text-align: center;
}
.stat-value {
font-size: 1.5em;
font-weight: bold;
color: #667eea;
}
.battle-area {
background: #e9ecef;
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
min-height: 300px;
position: relative;
overflow: hidden;
}
.pokemon-container {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.pokemon {
text-align: center;
background: white;
padding: 20px;
border-radius: 15px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
transition: transform 0.3s ease;
}
.pokemon:hover {
transform: translateY(-5px);
}
.pokemon-sprite {
width: 120px;
height: 120px;
background: #f0f0f0;
border-radius: 50%;
margin: 0 auto 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 3em;
position: relative;
overflow: hidden;
}
.pokemon-name {
font-weight: bold;
color: #333;
margin-bottom: 5px;
}
.health-bar {
width: 150px;
height: 20px;
background: #ddd;
border-radius: 10px;
overflow: hidden;
margin: 10px auto;
}
.health-fill {
height: 100%;
background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
transition: width 0.5s ease;
border-radius: 10px;
}
.battle-log {
background: white;
border-radius: 10px;
padding: 15px;
height: 150px;
overflow-y: auto;
margin-bottom: 20px;
border: 2px solid #e9ecef;
}
.log-entry {
padding: 5px 0;
border-bottom: 1px solid #eee;
font-size: 0.9em;
}
.controls {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 15px;
margin-bottom: 20px;
}
.btn {
padding: 15px 25px;
border: none;
border-radius: 10px;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
text-transform: uppercase;
letter-spacing: 1px;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.btn-attack {
background: linear-gradient(135deg, #ff6b6b, #ee5a6f);
color: white;
}
.btn-catch {
background: linear-gradient(135deg, #4ecdc4, #44a08d);
color: white;
}
.btn-heal {
background: linear-gradient(135deg, #a8e6cf, #7fcdcd);
color: #333;
}
.btn-new {
background: linear-gradient(135deg, #ffd93d, #ff6b6b);
color: #333;
}
.pokemon-collection {
background: #f8f9fa;
border-radius: 15px;
padding: 20px;
margin-top: 20px;
}
.collection-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 15px;
margin-top: 15px;
}
.collection-item {
background: white;
border-radius: 10px;
padding: 10px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.collection-item:hover {
border-color: #667eea;
transform: scale(1.05);
}
.collection-item.active {
border-color: #667eea;
background: #e3f2fd;
}
.collection-sprite {
width: 60px;
height: 60px;
background: #f0f0f0;
border-radius: 50%;
margin: 0 auto 5px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5em;
}
.damage-animation {
animation: shake 0.5s ease-in-out;
}
.catch-animation {
animation: bounce 0.6s ease-in-out;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-10px); }
75% { transform: translateX(10px); }
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
padding: 30px;
border-radius: 20px;
text-align: center;
max-width: 400px;
animation: modalAppear 0.3s ease;
}
@keyframes modalAppear {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
.modal h2 {
color: #333;
margin-bottom: 20px;
}
.modal-btn {
background: #667eea;
color: white;
padding: 10px 30px;
border: none;
border-radius: 10px;
font-size: 1.1em;
cursor: pointer;
margin: 10px;
}
@media (max-width: 600px) {
.pokemon-container {
flex-direction: column;
gap: 20px;
}
.controls {
grid-template-columns: 1fr;
}
}
</style>
</head> <body> <div class="game-container"> <div class="game-header"> <h1>🎮 宠物小精灵冒险</h1> <p>捕捉、训练、战斗!成为最强训练师!</p> </div>
<div class="game-stats">
<div class="stat-item">
<div class="stat-value" id="player-level">1</div>
<div>训练师等级</div>
</div>
<div class="stat-item">
<div class="stat-value" id="pokeballs">10</div>
<div>精灵球</div>
</div>
<div class="stat-item">
<div class="stat-value" id="pokemon-count">1</div>
<div>拥有精灵</div>
</div>
<div class="stat-item">
<div class="stat-value" id="win-count">0</div>
<div>胜利次数</div>
</div>
</div>
<div class="battle-area">
<div class="pokemon-container">
<div class="pokemon" id="player-pokemon">
<div class="pokemon-sprite" id="player-sprite">🐉</div>
<div class="pokemon-name" id="player-name">火龙</div>
<div class="health-bar">
<div class="health-fill" id="player-health" style="width: 100%"></div>
</div>
<div class="pokemon-info">HP: <span id="player-hp">100</span>/100</div>
</div>
<div style="font-size: 2em;">⚔️</div>
<div class="pokemon" id="enemy-pokemon">
<div class="pokemon-sprite" id="enemy-sprite">🐢</div>
<div class="pokemon-name" id="enemy-name">杰尼龟</div>
<div class="health-bar">
<div class="health-fill" id="enemy-health" style="width: 100%"></div>
</div>
<div class="pokemon-info">HP: <span id="enemy-hp">80</span>/80</div>
</div>
</div>
<div class="battle-log" id="battle-log">
<div class="log-entry">战斗开始!遇到了野生的<span id="enemy-name-log">杰尼龟</span>!</div>
</div>
</div>
<div class="controls">
<button class="btn btn-attack" onclick="attack()">⚔️ 攻击</button>
<button class="btn btn-catch" onclick="catchPokemon()">🎯 捕捉</button>
<button class="btn btn-heal" onclick="heal()">💊 治疗</button>
<button class="btn btn-new" onclick="newBattle()">🔄 新战斗</button>
</div>
<div class="pokemon-collection">
<h3>我的精灵收藏</h3>
<div class="collection-grid" id="collection-grid">
<!-- 动态生成 -->
</div>
</div>
</div>
<!-- 模态框 -->
<div class="modal" id="modal">
<div class="modal-content">
<h2 id="modal-title">提示</h2>
<p id="modal-message">消息内容</p>
<button class="modal-btn" onclick="closeModal()">确定</button>
</div>
</div>
<script>
// 游戏数据
const pokemonData = [
{ name: '火龙', emoji: '🐉', hp: 100, attack: 25, catchRate: 0.3 },
{ name: '杰尼龟', emoji: '🐢', hp: 80, attack: 20, catchRate: 0.4 },
{ name: '妙蛙种子', emoji: '🌱', hp: 90, attack: 22, catchRate: 0.35 },
{ name: '皮卡丘', emoji: '⚡', hp: 70, attack: 30, catchRate: 0.25 },
{ name: '超梦', emoji: '💫', hp: 150, attack: 40, catchRate: 0.1 },
{ name: '梦幻', emoji: '🌟', hp: 120, attack: 35, catchRate: 0.15 },
{ name: '喷火龙', emoji: '🐲', hp: 130, attack: 38, catchRate: 0.2 },
{ name: '水箭龟', emoji: '🐢', hp: 120, attack: 32, catchRate: 0.25 }
];
// 游戏状态
let gameState = {
playerPokemon: pokemonData[0],
enemyPokemon: null,
playerHP: 100,
enemyHP: 80,
pokeballs: 10,
level: 1,
winCount: 0,
collection: [pokemonData[0]],
currentPokemonIndex: 0
};
// 初始化游戏
function init() {
newBattle();
updateUI();
updateCollection();
}
// 更新UI
function updateUI() {
document.getElementById('player-level').textContent = gameState.level;
document.getElementById('pokeballs').textContent = gameState.pokeballs;
document.getElementById('pokemon-count').textContent = gameState.collection.length;
document.getElementById('win-count').textContent = gameState.winCount;
// 更新玩家精灵信息
document.getElementById('player-name').textContent = gameState.playerPokemon.name;
document.getElementById('player-sprite').textContent = gameState.playerPokemon.emoji;
document.getElementById('player-hp').textContent = gameState.playerHP;
document.getElementById('player-health').style.width = (gameState.playerHP / gameState.playerPokemon.hp * 100) + '%';
// 更新敌人精灵信息
if (gameState.enemyPokemon) {
document.getElementById('enemy-name').textContent = gameState.enemyPokemon.name;
document.getElementById('enemy-sprite').textContent = gameState.enemyPokemon.emoji;
document.getElementById('enemy-hp').textContent = gameState.enemyHP;
document.getElementById('enemy-health').style.width = (gameState.enemyHP / gameState.enemyPokemon.hp * 100) + '%';
}
}
// 更新收藏
function updateCollection() {
const grid = document.getElementById('collection-grid');
grid.innerHTML = '';
gameState.collection.forEach((pokemon, index) => {
const item = document.createElement('div');
item.className = 'collection-item';
if (index === gameState.currentPokemonIndex) {
item.classList.add('active');
}
item.innerHTML = `
<div class="collection-sprite">${pokemon.emoji}</div>
<div>${pokemon.name}</div>
`;
item.onclick = () => selectPokemon(index);
grid.appendChild(item);
});
}
// 选择精灵
function selectPokemon(index) {
if (index < gameState.collection.length) {
gameState.currentPokemonIndex = index;
gameState.playerPokemon = gameState.collection[index];
gameState.playerHP = gameState.playerPokemon.hp;
updateUI();
updateCollection();
addLog(`切换到了 ${gameState.playerPokemon.name}!`);
}
}
// 攻击
function attack() {
if (!gameState.enemyPokemon || gameState.enemyHP <= 0) return;
// 玩家攻击
const playerDamage = Math.floor(Math.random() * gameState.playerPokemon.attack) + 10;
gameState.enemyHP = Math.max(0, gameState.enemyHP - playerDamage);
addLog(`${gameState.playerPokemon.name} 造成了 ${playerDamage} 点伤害!`);
// 添加攻击动画
document.getElementById('enemy-pokemon').classList.add('damage-animation');
setTimeout(() => {
document.getElementById('enemy-pokemon').classList.remove('damage-animation');
}, 500);
updateUI();
// 检查敌人是否被击败
if (gameState.enemyHP <= 0) {
gameState.winCount++;
gameState.level = Math.floor(gameState.winCount / 3) + 1;
addLog(`${gameState.enemyPokemon.name} 被击败了!获得胜利!`);
showModal('胜利!', `你击败了 ${gameState.enemyPokemon.name}!获得经验值!`);
updateUI();
return;
}
// 敌人反击
setTimeout(() => {
const enemyDamage = Math.floor(Math.random() * gameState.enemyPokemon.attack) + 5;
gameState.playerHP = Math.max(0, gameState.playerHP - enemyDamage);
addLog(`${gameState.enemyPokemon.name} 反击造成了 ${enemyDamage} 点伤害!`);
// 添加受伤动画
document.getElementById('player-pokemon').classList.add('damage-animation');
setTimeout(() => {
document.getElementById('player-pokemon').classList.remove('damage-animation');
}, 500);
updateUI();
// 检查玩家是否被击败
if (gameState.playerHP <= 0) {
addLog(`${gameState.playerPokemon.name} 被击败了!`);
showModal('失败', '你的精灵被击败了!治疗后再来挑战吧!');
}
}, 1000);
}
// 捕捉
function catchPokemon() {
if (!gameState.enemyPokemon || gameState.enemyHP <= 0) return;
if (gameState.pokeballs <= 0) {
showModal('提示', '精灵球用完了!继续战斗获得新的精灵球!');
return;
}
gameState.pokeballs--;
// 计算捕捉成功率
const catchChance = gameState.enemyPokemon.catchRate + (1 - gameState.enemyHP / gameState.enemyPokemon.hp) * 0.3;
if (Math.random() < catchChance) {
// 捕捉成功
gameState.collection.push(gameState.enemyPokemon);
addLog(`成功捕捉了 ${gameState.enemyPokemon.name}!`);
showModal('捕捉成功!', `你成功捕捉了 ${gameState.enemyPokemon.name}!`);
// 添加捕捉动画
document.getElementById('enemy-pokemon').classList.add('catch-animation');
updateCollection();
gameState.enemyPokemon = null;
} else {
// 捕捉失败
addLog(`${gameState.enemyPokemon.name} 挣脱了精灵球!`);
showModal('捕捉失败', '精灵挣脱了!继续攻击降低它的HP!');
// 敌人可能会因为愤怒而攻击
setTimeout(() => {
const enemyDamage = Math.floor(Math.random() * gameState.enemyPokemon.attack) + 10;
gameState.playerHP = Math.max(0, gameState.playerHP - enemyDamage);
addLog(`${gameState.enemyPokemon.name} 愤怒反击造成了 ${enemyDamage} 点伤害!`);
updateUI();
}, 500);
}
updateUI();
}
// 治疗
function heal() {
if (gameState.playerHP >= gameState.playerPokemon.hp) {
showModal('提示', '你的精灵已经满血了!');
return;
}
const healAmount = Math.floor(gameState.playerPokemon.hp * 0.3);
gameState.playerHP = Math.min(gameState.playerPokemon.hp, gameState.playerHP + healAmount);
addLog(`治疗了 ${healAmount} 点生命值!`);
updateUI();
showModal('治疗成功', `你的 ${gameState.playerPokemon.name} 恢复了 ${healAmount} 点生命值!`);
}
// 新战斗
function newBattle() {
// 恢复玩家精灵HP
gameState.playerHP = gameState.playerPokemon.hp;
// 随机选择一个敌人精灵
const availablePokemon = pokemonData.filter(p =>
!gameState.collection.some(cp => cp.name === p.name)
);
if (availablePokemon.length === 0) {
// 如果所有精灵都已收集,随机选择任何精灵
gameState.enemyPokemon = pokemonData[Math.floor(Math.random() * pokemonData.length)];
} else {
gameState.enemyPokemon = availablePokemon[Math.floor(Math.random() * availablePokemon.length)];
}
gameState.enemyHP = gameState.enemyPokemon.hp;
// 随机增加精灵球
if (Math.random() < 0.7) {
gameState.pokeballs += Math.floor(Math.random() * 3) + 1;
}
addLog(`新的战斗开始!遇到了野生的 ${gameState.enemyPokemon.name}!`);
updateUI();
}
// 添加战斗日志
function addLog(message) {
const log = document.getElementById('battle-log');
const entry = document.createElement('div');
entry.className = 'log-entry';
entry.textContent = message;
log.appendChild(entry);
log.scrollTop = log.scrollHeight;
}
// 显示模态框
function showModal(title, message) {
document.getElementById('modal-title').textContent = title;
document.getElementById('modal-message').textContent = message;
document.getElementById('modal').style.display = 'flex';
}
// 关闭模态框
function closeModal() {
document.getElementById('modal').style.display = 'none';
}
// 初始化游戏
window.onload = init;
</script>
</body>
</html>
这个HTML5宠物小精灵游戏包含了以下功能:
🎮 游戏特色:
完整的战斗系统
回合制战斗机制
攻击、捕捉、治疗操作
动态血条显示
精灵收集系统
8种不同的精灵(火龙、杰尼龟、妙蛙种子等)
每个精灵有独特的外观和能力
精灵收藏展示
游戏进度系统
训练师等级系统
胜利次数统计
精灵球数量管理
视觉效果
精美的渐变色设计
攻击和捕捉动画
响应式布局
交互功能
精灵切换
战斗日志
模态框提示
🎯 游戏玩法:
攻击:对野生精灵造成伤害
捕捉:使用精灵球捕捉野生精灵
治疗:恢复当前精灵的生命值
新战斗:开始新的战斗遭遇
游戏完全使用HTML5、CSS3和JavaScript实现,无需外部依赖,可以直接在浏览器中运行。界面美观,功能完整,适合作为学习项目或娱乐游戏。