以下是一个完整的捕鱼游戏HTML5源码示例,包含核心游戏机制和交互功能,这个游戏使用Canvas绘制,玩家可以控制渔网捕鱼,具有得分系统和动画效果。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">捕鱼达人 HTML5游戏</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(to bottom, #87CEEB, #1E90FF);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
}
.game-container {
position: relative;
width: 800px;
height: 600px;
background: linear-gradient(to bottom, #1E90FF, #0047AB);
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
overflow: hidden;
}
canvas {
display: block;
cursor: crosshair;
}
.game-ui {
position: absolute;
top: 0;
left: 0;
right: 0;
padding: 15px;
display: flex;
justify-content: space-between;
background: rgba(0, 0, 0, 0.5);
color: white;
font-size: 18px;
}
.score {
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.controls {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 15px;
}
button {
padding: 10px 20px;
background: #FF6347;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
}
button:hover {
background: #FF4500;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.3);
}
.message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 20px 40px;
border-radius: 10px;
font-size: 24px;
text-align: center;
display: none;
z-index: 10;
}
.bubble {
position: absolute;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
animation: float 8s infinite ease-in-out;
}
@keyframes float {
0% {
transform: translateY(0) translateX(0);
opacity: 0.7;
}
50% {
transform: translateY(-100px) translateX(50px);
opacity: 0.4;
}
100% {
transform: translateY(0) translateX(0);
opacity: 0.7;
}
}
</style>
</head>
<body>
<div class="game-container">
<canvas id="gameCanvas" width="800" height="600"></canvas>
<div class="game-ui">
<div class="score">得分: <span id="scoreValue">0</span></div>
<div>等级: <span id="levelValue">1</span></div>
<div>金币: <span id="coinsValue">100</span></div>
</div>
<div class="controls">
<button id="fireBtn">发射渔网</button>
<button id="pauseBtn">暂停</button>
<button id="resetBtn">重新开始</button>
</div>
<div class="message" id="gameMessage"></div>
</div>
<script>
// 游戏配置
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('scoreValue');
const levelElement = document.getElementById('levelValue');
const coinsElement = document.getElementById('coinsValue');
const messageElement = document.getElementById('gameMessage');
// 游戏状态
let gameState = {
score: 0,
level: 1,
coins: 100,
isPaused: false,
isGameOver: false,
fishes: [],
bullets: [],
particles: [],
bubbles: [],
net: {
x: canvas.width / 2,
y: canvas.height 50,
width: 60,
height: 30,
speed: 5,
isShooting: false,
cooldown: 0
}
};
// 鱼类定义
class Fish {
constructor() {
this.width = 30 + Math.random() * 40;
this.height = this.width * 0.6;
this.x = Math.random() * (canvas.width this.width);
this.y = -this.height;
this.speed = 1 + Math.random() * 2 + (gameState.level * 0.2);
this.direction = Math.random() > 0.5 ? 1 : -1;
this.color = this.getRandomColor();
this.value = Math.floor(this.width / 10);
this.type = this.getType();
}
getRandomColor() {
const colors = ['#FF6347', '#FFD700', '#1E90FF', '#32CD32', '#FF69B4', '#00CED1'];
return colors[Math.floor(Math.random() * colors.length)];
}
getType() {
if (this.width < 35) return 'small';
if (this.width < 55) return 'medium';
return 'large';
}
update() {
this.y += this.speed;
this.x += this.direction * 0.5;
// 边界检查
if (this.x < 0 || this.x > canvas.width this.width) {
this.direction *= -1;
}
}
draw() {
ctx.save();
// 鱼身体
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.ellipse(
this.x + this.width / 2,
this.y + this.height / 2,
this.width / 2,
this.height / 2,
0,
0,
Math.PI * 2
);
ctx.fill();
// 鱼尾巴
ctx.beginPath();
ctx.moveTo(this.x, this.y + this.height / 2);
ctx.lineTo(this.x 15 * this.direction, this.y);
ctx.lineTo(this.x 15 * this.direction, this.y + this.height);
ctx.closePath();
ctx.fill();
// 鱼眼睛
ctx.fillStyle = 'white';
ctx.beginPath();
ctx.arc(
this.x + this.width / 2 + 5 * this.direction,
this.y + this.height / 3,
3,
0,
Math.PI * 2
);
ctx.fill();
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(
this.x + this.width / 2 + 5 * this.direction,
this.y + this.height / 3,
1.5,
0,
Math.PI * 2
);
ctx.fill();
ctx.restore();
}
}
// 子弹类
class Bullet {
constructor(x, y) {
this.x = x;
this.y = y;
this.radius = 5;
this.speed = 8;
this.active = true;
}
update() {
this.y -= this.speed;
if (this.y < 0) {
this.active = false;
}
}
draw() {
ctx.fillStyle = '#FFD700';
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fill();
// 发光效果
ctx.shadowColor = '#FFD700';
ctx.shadowBlur = 10;
ctx.fill();
ctx.shadowBlur = 0;
}
}
// 粒子效果类
class Particle {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.radius = Math.random() * 3 + 1;
this.color = color;
this.speedX = Math.random() * 4 2;
this.speedY = Math.random() * 4 2;
this.alpha = 1;
this.decay = 0.02;
}
update() {
this.x += this.speedX;
this.y += this.speedY;
this.alpha -= this.decay;
if (this.alpha <= 0) {
return false;
}
return true;
}
draw() {
ctx.save();
ctx.globalAlpha = this.alpha;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
}
// 气泡类
class Bubble {
constructor() {
this.radius = Math.random() * 5 + 2;
this.x = Math.random() * canvas.width;
this.y = canvas.height + this.radius;
this.speed = Math.random() * 1 + 0.5;
this.wobble = Math.random() * 2;
this.wobbleSpeed = Math.random() * 0.05;
this.angle = 0;
}
update() {
this.y -= this.speed;
this.angle += this.wobbleSpeed;
this.x += Math.sin(this.angle) * this.wobble;
if (this.y < -this.radius) {
return false;
}
return true;
}
draw() {
ctx.save();
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fill();
ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.stroke();
ctx.restore();
}
}
// 初始化游戏
function init() {
// 创建初始鱼群
for (let i = 0; i < 10; i++) {
setTimeout(() => {
gameState.fishes.push(new Fish());
}, i * 1000);
}
// 创建气泡
for (let i = 0; i < 20; i++) {
setTimeout(() => {
gameState.bubbles.push(new Bubble());
}, i * 300);
}
// 事件监听
document.getElementById('fireBtn').addEventListener('click', fireBullet);
document.getElementById('pauseBtn').addEventListener('click', togglePause);
document.getElementById('resetBtn').addEventListener('click', resetGame);
canvas.addEventListener('mousemove', (e) => {
if (!gameState.isPaused && !gameState.isGameOver) {
const rect = canvas.getBoundingClientRect();
gameState.net.x = e.clientX rect.left gameState.net.width / 2;
// 边界限制
if (gameState.net.x < 0) gameState.net.x = 0;
if (gameState.net.x > canvas.width gameState.net.width) {
gameState.net.x = canvas.width gameState.net.width;
}
}
});
canvas.addEventListener('click', fireBullet);
}
// 发射子弹
function fireBullet() {
if (!gameState.isPaused && !gameState.isGameOver && gameState.coins >= 1) {
gameState.coins--;
coinsElement.textContent = gameState.coins;
gameState.bullets.push(new Bullet(
gameState.net.x + gameState.net.width / 2,
gameState.net.y
));
// 添加射击音效(模拟)
playSound('shoot');
}
}
// 播放音效(模拟)
function playSound(type) {
// 在实际游戏中,这里会播放真实的音效文件
console.log(`Playing sound: ${type}`);
}
// 切换暂停状态
function togglePause() {
gameState.isPaused = !gameState.isPaused;
document.getElementById('pauseBtn').textContent = gameState.isPaused ? '继续' : '暂停';
if (gameState.isPaused) {
showMessage('游戏暂停');
} else {
hideMessage();
}
}
// 重置游戏
function resetGame() {
gameState = {
score: 0,
level: 1,
coins: 100,
isPaused: false,
isGameOver: false,
fishes: [],
bullets: [],
particles: [],
bubbles: [],
net: {
x: canvas.width / 2,
y: canvas.height 50,
width: 60,
height: 30,
speed: 5,
isShooting: false,
cooldown: 0
}
};
scoreElement.textContent = gameState.score;
levelElement.textContent = gameState.level;
coinsElement.textContent = gameState.coins;
document.getElementById('pauseBtn').textContent = '暂停';
hideMessage();
// 重新初始化鱼群
for (let i = 0; i < 10; i++) {
setTimeout(() => {
gameState.fishes.push(new Fish());
}, i * 1000);
}
}
// 显示消息
function showMessage(text) {
messageElement.textContent = text;
messageElement.style.display = 'block';
}
// 隐藏消息
function hideMessage() {
messageElement.style.display = 'none';
}
// 碰撞检测
function checkCollisions() {
// 子弹与鱼碰撞检测
for (let i = gameState.bullets.length 1; i >= 0; i--) {
const bullet = gameState.bullets[i];
for (let j = gameState.fishes.length 1; j >= 0; j--) {
const fish = gameState.fishes[j];
if (
bullet.x > fish.x &&
bullet.x < fish.x + fish.width &&
bullet.y > fish.y &&
bullet.y < fish.y + fish.height
) {
// 碰撞发生
gameState.score += fish.value;
gameState.coins += fish.value;
scoreElement.textContent = gameState.score;
coinsElement.textContent = gameState.coins;
// 创建粒子效果
for (let k = 0; k < 15; k++) {
gameState.particles.push(
new Particle(
fish.x + fish.width / 2,
fish.y + fish.height / 2,
fish.color
)
);
}
// 移除子弹和鱼
gameState.bullets.splice(i, 1);
gameState.fishes.splice(j, 1);
// 播放音效
playSound('catch');
// 检查升级
if (gameState.score >= gameState.level * 100) {
gameState.level++;
levelElement.textContent = gameState.level;
showMessage(`恭喜升级到 ${gameState.level} 级!`);
setTimeout(hideMessage, 2000);
}
break;
}
}
}
}
// 绘制背景
function drawBackground() {
// 水下背景
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, '#1E90FF');
gradient.addColorStop(1, '#0047AB');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 海底
ctx.fillStyle = '#8B4513';
ctx.fillRect(0, canvas.height 30, canvas.width, 30);
// 海底装饰
ctx.fillStyle = '#556B2F';
for (let i = 0; i < 10; i++) {
const x = i * 80 + 20;
ctx.beginPath();
ctx.moveTo(x, canvas.height 30);
ctx.bezierCurveTo(
x + 10, canvas.height 50,
x + 20, canvas.height 40,
x + 30, canvas.height 30
);
ctx.fill();
}
}
// 绘制渔网
function drawNet() {
ctx.fillStyle = '#8B4513';
ctx.fillRect(gameState.net.x, gameState.net.y, gameState.net.width, gameState.net.height);
// 网格效果
ctx.strokeStyle = '#654321';
ctx.lineWidth = 1;
// 水平线
for (let i = 0; i < 4; i++) {
ctx.beginPath();
ctx.moveTo(gameState.net.x, gameState.net.y + i * 10);
ctx.lineTo(gameState.net.x + gameState.net.width, gameState.net.y + i * 10);
ctx.stroke();
}
// 垂直线
for (let i = 0; i < 6; i++) {
ctx.beginPath();
ctx.moveTo(gameState.net.x + i * 10, gameState.net.y);
ctx.lineTo(gameState.net.x + i * 10, gameState.net.y + gameState.net.height);
ctx.stroke();
}
}
// 游戏主循环
function gameLoop() {
if (!gameState.isPaused && !gameState.isGameOver) {
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制背景
drawBackground();
// 更新和绘制气泡
for (let i = gameState.bubbles.length 1; i >= 0; i--) {
if (!gameState.bubbles[i].update()) {
gameState.bubbles.splice(i, 1);
} else {
gameState.bubbles[i].draw();
}
}
// 随机生成新鱼
if (Math.random() < 0.02 + gameState.level * 0.005) {
gameState.fishes.push(new Fish());
}
// 更新和绘制鱼
for (let i = gameState.fishes.length 1; i >= 0; i--) {
gameState.fishes[i].update();
gameState.fishes[i].draw();
// 移除游出屏幕的鱼
if (gameState.fishes[i].y > canvas.height) {
gameState.fishes.splice(i, 1);
}
}
// 更新和绘制子弹
for (let i = gameState.bullets.length 1; i >= 0; i--) {
gameState.bullets[i].update();
gameState.bullets[i].draw();
if (!gameState.bullets[i].active) {
gameState.bullets.splice(i, 1);
}
}
// 更新和绘制粒子
for (let i = gameState.particles.length 1; i >= 0; i--) {
if (!gameState.particles[i].update()) {
gameState.particles.splice(i, 1);
} else {
gameState.particles[i].draw();
}
}
// 绘制渔网
drawNet();
// 碰撞检测
checkCollisions();
// 检查游戏结束
if (gameState.coins <= 0 && gameState.bullets.length === 0) {
gameState.isGameOver = true;
showMessage(`游戏结束! 最终得分: ${gameState.score}`);
}
}
requestAnimationFrame(gameLoop);
}
// 启动游戏
init();
gameLoop();
</script>
</body>
</html>
核心玩法:
游戏元素:

用户界面:
视觉效果:

添加更多鱼类:
增强游戏机制:
音效和音乐:
移动端适配:
这个捕鱼游戏HTML5源码可以直接在浏览器中运行,无需额外依赖,你可以根据需要进一步扩展和定制游戏功能。