Designing a Fishing Game in PHP

Building a fishing game in PHP involves front-end and back-end working together. Here are the core implementation ideas and code examples:

1. System Design

  1. Front end: HTML5 Canvas + JavaScript to draw the game scene
  2. Back end: PHP handles the game logic and database operations
  3. Database: MySQL stores player data
  4. Communication: AJAX handles front-end/back-end interaction

2. Core Feature Implementation

1. Database Design (MySQL)

1
2
3
4
5
6
7
CREATE TABLE players (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE,
password VARCHAR(255),
gold INT DEFAULT 1000,
score INT DEFAULT 0
);

2. PHP Back-End Logic (wired up to the front end)

Core game file: game.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
session_start();
// connect to the database
$db = new mysqli('localhost', 'username', 'password', 'fishing_game');

class FishingGame {
private $db;

public function __construct($db) {
$this->db = $db;
}

// fishing logic
public function catchFish($playerId, $cannonType, $fishType) {
$cost = $this->getCannonCost($cannonType);
$reward = $this->getFishReward($fishType);

// deduct gold
$this->db->query("UPDATE players SET gold = gold - $cost WHERE id = $playerId");

// catch check (simplified probability)
$success = (rand(1, 100) > 30); // 70% success rate

if($success) {
$this->db->query("UPDATE players SET gold = gold + $reward, score = score + $reward WHERE id = $playerId");
return ['success' => true, 'reward' => $reward];
}
return ['success' => false];
}

private function getCannonCost($type) {
$costs = [1 => 5, 2 => 10, 3 => 20]; // cost per cannon type
return $costs[$type] ?? 5;
}

private function getFishReward($type) {
$rewards = [1 => 10, 2 => 25, 3 => 50]; // reward per fish type
return $rewards[$type] ?? 10;
}
}

// instantiate the game
$game = new FishingGame($db);

// handle the AJAX request
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$playerId = $_SESSION['player_id'];
$data = json_decode(file_get_contents('php://input'), true);

if(isset($data['action']) && $data['action'] === 'catch') {
$response = $game->catchFish(
$playerId,
$data['cannon'],
$data['fishType']
);
header('Content-Type: application/json');
echo json_encode($response);
exit;
}
}
?>

3. Core Front-End Implementation (JavaScript)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script>
// game config
const FISH_TYPES = {
1: { speed: 2, color: '#FF9900', size: 30 },
2: { speed: 3, color: '#00CCFF', size: 50 },
3: { speed: 1, color: '#FF66CC', size: 80 }
};

class FishingGame {
constructor() {
this.canvas = document.getElementById('gameCanvas');
this.ctx = this.canvas.getContext('2d');
this.fishes = [];
this.player = { gold: 1000, score: 0 };
this.init();
}

init() {
this.generateFish();
this.gameLoop();
this.canvas.addEventListener('click', this.handleClick.bind(this));
}

generateFish() {
// spawn fish at random
setInterval(() => {
const type = Math.floor(Math.random() * 3) + 1;
this.fishes.push({
type,
x: -50,
y: Math.random() * 500 + 50,
...FISH_TYPES[type]
});
}, 2000);
}

handleClick(e) {
const rect = this.canvas.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const clickY = e.clientY - rect.top;

// check which fish was clicked
const cannonType = 1; // default cannon type
for(let i = this.fishes.length - 1; i >= 0; i--) {
const fish = this.fishes[i];
const distance = Math.sqrt(
Math.pow(fish.x - clickX, 2) +
Math.pow(fish.y - clickY, 2)
);

if(distance < fish.size) {
this.sendCatchRequest(fish.type, cannonType);
this.fishes.splice(i, 1);
break;
}
}
}

async sendCatchRequest(fishType, cannonType) {
const response = await fetch('game.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'catch',
fishType: fishType,
cannon: cannonType
})
});

const result = await response.json();
if(result.success) {
this.player.gold += result.reward;
this.player.score += result.reward;
this.showEffect('+'+result.reward);
}
}

gameLoop() {
this.ctx.clearRect(0, 0, 800, 600);

// draw the background
this.ctx.fillStyle = '#3399FF';
this.ctx.fillRect(0, 0, 800, 600);

// update and draw the fish
this.fishes.forEach(fish => {
fish.x += fish.speed;
if(fish.x > 850) fish.x = -50;

this.ctx.beginPath();
this.ctx.fillStyle = fish.color;
this.ctx.arc(fish.x, fish.y, fish.size/2, 0, Math.PI * 2);
this.ctx.fill();
});

// draw the UI
this.ctx.fillStyle = '#000';
this.ctx.font = '20px Arial';
this.ctx.fillText(`Gold: ${this.player.gold}`, 20, 30);
this.ctx.fillText(`Score: ${this.player.score}`, 20, 60);

requestAnimationFrame(() => this.gameLoop());
}
}

new FishingGame();
</script>

3. Suggested Feature Extensions

  1. Advanced features:

    • Add multiple weapon systems (laser cannon, fishing net)
    • Implement special fish behaviour (BOSS fish, fish school migration)
    • Item system (double gold, freeze effect)
  2. Performance optimization:

    • WebSocket for real-time communication
    • Object pooling to reuse fish objects
    • Sprite sheets instead of solid-color drawing
  3. Security hardening:

    • Cannon cost validation
    • Rate limiting (anti-cheat)
    • Encrypted data transmission
  4. Monetization features:

    • In-app purchase gold system
    • Daily quest rewards
    • Player leaderboards

4. Deployment Notes

  1. Use PHP 7.4+ for the best performance
  2. Enable OPCache to speed up PHP execution
  3. Serve front-end assets through a CDN
  4. Back up player data regularly

A complete implementation also needs a user system (registration/login), an in-game shop, social features and so on. In real development, consider a game engine such as Phaser.js instead of the raw Canvas API to speed things up.