Code:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fishing Game</title>
<div id="score">Score: 0</div>
<div id="timer">Time: 30</div> <!-- Reduced timer duration -->
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #f0e4d7; /* Light beige for a farm-like background */
margin: 0;
padding: 0;
}
#gameCanvas {
border: 5px solid #6f4e37; /* Dark brown border for a rustic look */
background-color: #87CEEB; /* Light blue for water */
display: block;
margin: 20px auto;
position: relative;
overflow: hidden; /* Prevents items from being visible outside the canvas */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* Shadow for depth */
border-radius: 10px; /* Rounded corners for a softer look */
}
.boat {
width: 100px; /* Wider boat for a more rustic feel */
height: 50px;
background: #8B4513; /* Brown color for boat */
position: absolute;
border-radius: 10px; /* Rounded edges for boat */
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.4); /* Inner shadow for depth */
top: 15px; /* Positioned at the top */
left: calc(50% - 50px); /* Centered horizontally */
transition: background-color 0.3s ease; /* Smooth transition on hover */
}
.boat:hover {
background-color: #A0522D; /* Slightly lighter brown on hover */
}
.hook {
width: 8px; /* Slightly wider hook for better visibility */
height: 60px; /* Longer hook for realism */
background-color: #8B4513; /* Brown color for hook */
position: absolute;
top: 50px; /* Initial position below the boat */
left: calc(50% - 4px); /* Centered horizontally */
border-radius: 4px; /* Slight rounding for realism */
transition: height 0.3s ease; /* Smooth transition on movement */
}
.hook.animate {
animation: dropHook 1s ease-in-out infinite; /* Drop animation for realism */
}
@keyframes dropHook {
0% { top: 50px; }
50% { top: 100px; }
100% { top: 50px; }
}
#score {
font-size: 20px;
color: #6f4e37; /* Dark brown for a rustic look */
position: absolute;
top: 250px;
right: 200px;
background-color: rgba(255, 255, 255, 0.8); /* Slightly transparent white background */
padding: 10px 20px;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); /* Shadow for depth */
font-weight: bold; /* Make the score more prominent */
}
#timer {
font-size: 22px;
color: #b5651d; /* Rusty orange for a farm feel */
position: absolute;
top: 250px;
right: 320px;
background-color: rgba(0, 0, 0, 0.7); /* Dark background for contrast */
padding: 10px 20px;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); /* Shadow for depth */
font-weight: bold; /* Make the timer more prominent */
}
.fish {
background-color: #228B22; /* Dark green for fish */
border-radius: 50%; /* Make fish look more rounded */
border: 2px solid #006400; /* Darker green border for definition */
}
.junk {
background-color: #8B4513; /* Brown color for junk */
border-radius: 50%; /* Make junk items look more rounded */
border: 2px solid #5f3e1a; /* Darker brown border for definition */
}
.fish.animate {
animation: swim 3s linear infinite; /* Add swimming animation for fish */
}
.junk.animate {
animation: sway 2s ease-in-out infinite; /* Add swaying animation for junk */
}
@keyframes swim {
0% { transform: translateX(-50px); }
50% { transform: translateX(50px); }
100% { transform: translateX(-50px); }
}
@keyframes sway {
0% { transform: rotate(-5deg); }
50% { transform: rotate(5deg); }
100% { transform: rotate(-5deg); }
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="1000" height="600"></canvas> <!-- Wider canvas -->
<script>
(function() {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const boatWidth = 80; // Wider boat
const boatHeight = 40;
const hookWidth = 6; // Smaller hook
const hookHeight = 40; // Shorter hook
const stringWidth = 2; // Width of the string
let boatX = canvas.width / 2 - boatWidth / 2;
let boatY = 10; // Boat at the top
let hookY = boatY + boatHeight; // Initial hook position
let hookLowering = false;
let hookAnimationFrame = 0;
let hookAnimationSpeed = 5; // Faster hook animation
let items = [];
let score = 0;
let timer = 30; // Reduced countdown timer
let timerInterval;
let gameLoopId;
function createItem() {
if (Math.random() < 0.05) { // Increased spawn rate
const isFish = Math.random() > 0.5;
const side = Math.random() > 0.5 ? 'left' : 'right';
const speed = Math.random() * 3 + 6; // Increased speed between 2 and 5
const x = side === 'left' ? -20 : canvas.width;
items.push({
x: x,
y: Math.random() * (canvas.height - 20),
side: side,
speed: speed,
type: isFish ? 'fish' : 'junk'
});
}
}
function moveItems() {
items.forEach(item => {
item.x += item.side === 'left' ? item.speed : -item.speed;
});
}
function drawBoat() {
ctx.fillStyle = '#8B4513'; // Boat color
ctx.fillRect(boatX, boatY, boatWidth, boatHeight);
}
function drawHook() {
// Draw the string
ctx.strokeStyle = '#6f4e37'; // Dark brown color for string
ctx.lineWidth = stringWidth;
ctx.beginPath();
ctx.moveTo(boatX + boatWidth / 2, boatY + boatHeight);
ctx.lineTo(boatX + boatWidth / 2, hookY);
ctx.stroke();
// Draw the hook
ctx.fillStyle = '#8B4513'; // Brown color for hook
ctx.fillRect(boatX + boatWidth / 2 - hookWidth / 2, hookY, hookWidth, hookHeight);
}
function drawItems() {
items.forEach(item => {
ctx.save(); // Save the current state
// Set color based on item type
ctx.fillStyle = item.type === 'fish' ? '#228B22' : '#8B4513';
if (item.type === 'fish') {
// Draw fish body
ctx.beginPath();
ctx.ellipse(item.x + 25, item.y + 15, 30, 15, 0, 0, Math.PI * 2); // Main body
ctx.fill();
// Draw fish tail
ctx.beginPath();
ctx.moveTo(item.x + 45, item.y + 15); // Start at the right side of the body
ctx.lineTo(item.x + 60, item.y); // Tail top
ctx.lineTo(item.x + 60, item.y + 30); // Tail bottom
ctx.closePath(); // Complete the triangle
ctx.fill();
// Draw fish fins
ctx.beginPath();
ctx.moveTo(item.x + 10, item.y + 10); // Top fin start
ctx.lineTo(item.x + 20, item.y - 10); // Top fin peak
ctx.lineTo(item.x + 25, item.y + 10); // Top fin end
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.moveTo(item.x + 10, item.y + 20); // Bottom fin start
ctx.lineTo(item.x + 20, item.y + 40); // Bottom fin peak
ctx.lineTo(item.x + 25, item.y + 20); // Bottom fin end
ctx.closePath();
ctx.fill();
} else {
// Draw junk
ctx.fillStyle = '#6A5ACD'; // A dull color for junk, like slate blue
ctx.beginPath();
// Create an irregular polygon to simulate crumpled or broken junk
ctx.moveTo(item.x, item.y);
ctx.lineTo(item.x + 15, item.y + 5);
ctx.lineTo(item.x + 10, item.y + 20);
ctx.lineTo(item.x + 5, item.y + 10);
ctx.closePath();
ctx.fill();
// Optionally add some details for more realism
ctx.fillStyle = '#483D8B'; // Darker color for shadows or highlights
ctx.beginPath();
ctx.moveTo(item.x + 5, item.y + 10);
ctx.lineTo(item.x + 10, item.y + 15);
ctx.lineTo(item.x + 15, item.y + 10);
ctx.closePath();
ctx.fill();
}
ctx.restore(); // Restore to the saved state
});
}
function updateScore(newScore) {
score = newScore;
document.getElementById('score').innerText = `Score: ${score}`;
}
function updateTimer() {
timer--;
document.getElementById('timer').innerText = `Time: ${timer}`;
if (timer <= 0) {
clearInterval(timerInterval);
cancelAnimationFrame(gameLoopId);
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mousedown', handleMouseDown);
document.removeEventListener('mouseup', handleMouseUp);
alert('Time is up! Final Score: ' + score);
}
}
function update() {
createItem();
moveItems();
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBoat();
drawItems();
if (hookLowering) {
hookAnimationFrame += hookAnimationSpeed;
if (hookAnimationFrame > canvas.height - boatY - boatHeight) {
hookAnimationFrame = canvas.height - boatY - boatHeight;
}
hookY = boatY + boatHeight + hookAnimationFrame;
} else {
hookAnimationFrame -= hookAnimationSpeed;
if (hookAnimationFrame < 0) {
hookAnimationFrame = 0;
hookY = boatY + boatHeight;
} else {
hookY = boatY + boatHeight + hookAnimationFrame;
}
}
drawHook();
items.forEach(item => {
if (item.type === 'fish') {
if (item.x < boatX + boatWidth &&
item.x + 20 > boatX &&
item.y < hookY + hookHeight &&
item.y + 20 > hookY) {
items = items.filter(i => i !== item);
updateScore(score + 10); // Add 10 points for catching fish
}
} else if (item.type === 'junk') {
if (item.x < boatX + boatWidth &&
item.x + 20 > boatX &&
item.y < hookY + hookHeight &&
item.y + 20 > hookY) {
items = items.filter(i => i !== item);
updateScore(score - 5); // Subtract 5 points for catching junk
}
}
});
gameLoopId = requestAnimationFrame(update);
}
function handleMouseMove(event) {
boatX = event.clientX - canvas.offsetLeft - boatWidth / 2;
boatX = Math.max(0, Math.min(canvas.width - boatWidth, boatX));
}
function handleMouseDown() {
hookLowering = true;
}
function handleMouseUp() {
hookLowering = false;
}
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mousedown', handleMouseDown);
document.addEventListener('mouseup', handleMouseUp);
timerInterval = setInterval(updateTimer, 1000);
update();
})();
</script>
</body>
</html>
I need to update the story variable $money with the value of the score variable, but I'm having trouble doing it