经典游戏 + 现代技术
海战棋(Battleship)是个经典游戏。但让它支持 4 人同时对战、有武器冷却和连胜加成,就变得很有意思了。
后端架构
Node.js + Express
→ Socket.io(实时通信)
→ 游戏房间管理
→ 棋盘状态同步
→ 炮击逻辑
→ 命中判定 + 连胜加成棋盘生成与舰船放置
12×12 棋盘,每方配置 5 艘船:航母(5格)、战列舰(4格)、巡洋舰(3格)、驱逐舰(2格)、潜艇(2格)。
const SHIP_DEFS = [
{ name: '航母', len: 5 },
{ name: '战列舰', len: 4 },
{ name: '巡洋舰', len: 3 },
{ name: '驱逐舰', len: 2 },
{ name: '潜艇', len: 2 },
];
function randomPlace(ships, gridSize) {
for (const ship of ships) {
let placed = false;
while (!placed) {
const horizontal = Math.random() > 0.5;
const row = Math.floor(Math.random() * gridSize);
const col = Math.floor(Math.random() * gridSize);
placed = tryPlace(grid, ship, row, col, horizontal);
}
}
}炮击与冷却机制
不是简单地一人一炮。每艘存活的船就是一个"炮台",每次射击后进入冷却:
const BASE_COOLDOWN = 3500; // 基础冷却 3.5 秒
const STREAK_DISCOUNT = 400; // 命中一次减少 0.4 秒冷却
const MIN_COOLDOWN = 1200; // 最低冷却 1.2 秒这意味着——打得越准,射速越快。这是一个很强的正反馈机制,鼓励玩家认真瞄准而不是乱打。
房间管理
Socket.io 的 room 机制天然适合:
io.on('connection', (socket) => {
socket.on('join_game', (gameId) => {
socket.join(gameId);
// 通知房间内其他玩家
socket.to(gameId).emit('player_joined', playerInfo);
});
socket.on('fire', (target) => {
const result = gameState.fire(playerId, target);
io.to(gameId).emit('fire_result', result);
});
});状态同步策略
采用"服务器权威"模式:所有游戏逻辑跑在服务端,客户端只负责渲染。每次操作由客户端发起,服务端验证后广播结果。这样杜绝了作弊的可能性。
前端
纯 HTML + CSS + Canvas,用 Socket.io 客户端连接。支持拖拽放置舰船、点击炮击。游戏结束时有击杀统计和 MVP 评选。
4 个人在同一局里互相炮击的混乱场面,非常欢乐 😂