Socket.io 是一个基于 Node.js 的实时通信库,可以在客户端和服务器之间建立实时、双向的通信通道。在游戏开发中,Socket.io 可以用于实现多人在线游戏的实时通信功能,例如实时对战游戏、多人合作游戏等。
Socket.io 的基本使用
Socket.io 的基本使用非常简单,只需要在服务器端和客户端分别引入 Socket.io 库,然后在服务器端启动 Socket.io 服务,客户端连接到服务器即可。以下是一个简单的示例:
服务器端代码
// www.javascriptcn.com code example
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});以上代码创建了一个 Express 应用,并在其上创建了一个 Socket.io 服务。当客户端连接到服务器时,会触发 connection 事件,我们可以在回调函数中打印一条日志。当客户端断开连接时,会触发 disconnect 事件。
客户端代码
// www.javascriptcn.com code example
<!doctype html>
<html>
<head>
<title>Socket.io Example</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<script>
const socket = io();
socket.on('connect', () => {
console.log('connected to server');
});
socket.on('disconnect', () => {
console.log('disconnected from server');
});
</script>
</body>
</html>以上代码在页面中引入了 Socket.io 库,并在页面加载完成后创建了一个 Socket.io 客户端实例,并监听 connect 和 disconnect 事件,打印日志。
Socket.io 在游戏开发中的应用
在游戏开发中,我们通常需要实现以下功能:
- 实时同步游戏状态,例如玩家位置、血量、状态等。
- 实现实时聊天功能,让玩家可以在游戏中交流。
- 实现实时对战功能,让玩家可以在游戏中对战。
下面我们将分别介绍如何使用 Socket.io 实现这些功能。
实时同步游戏状态
在游戏中,玩家可能会有多个,因此我们需要在服务器端维护一个游戏状态对象,包含所有玩家的状态。每当玩家状态发生变化时,服务器将更新状态对象,并将状态对象广播给所有客户端。以下是一个示例:
服务器端代码
// www.javascriptcn.com code example
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
let gameState = {};
io.on('connection', (socket) => {
console.log('a user connected');
// 发送游戏状态给新加入的玩家
socket.emit('gameState', gameState);
// 更新游戏状态
socket.on('updateGameState', (newGameState) => {
gameState = newGameState;
socket.broadcast.emit('gameState', gameState);
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});以上代码中,我们维护了一个 gameState 对象,表示游戏状态。当客户端连接到服务器时,我们将 gameState 对象发送给客户端。当客户端更新游戏状态时,我们将更新后的状态对象广播给所有客户端。
客户端代码
// www.javascriptcn.com code example
<!doctype html>
<html>
<head>
<title>Game Example</title>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
let gameState = {};
// 接收游戏状态
socket.on('gameState', (newGameState) => {
gameState = newGameState;
// 更新游戏界面
updateGameUI();
});
// 更新游戏状态
function updateGameState(newGameState) {
gameState = newGameState;
socket.emit('updateGameState', gameState);
}
</script>
</head>
<body>
<!-- 游戏界面 -->
</body>
</html>以上代码中,我们创建了一个 gameState 对象,用于保存游戏状态。当客户端收到新的游戏状态时,我们更新 gameState 对象,并调用 updateGameUI 函数更新游戏界面。当玩家操作游戏时,我们将更新后的游戏状态发送给服务器,让服务器更新游戏状态并广播给所有客户端。
实现实时聊天功能
在游戏中,玩家可能需要交流,因此我们需要实现实时聊天功能。以下是一个示例:
服务器端代码
// www.javascriptcn.com code example
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('a user connected');
// 监听聊天消息
socket.on('chatMessage', (message) => {
console.log(`chat message: ${message}`);
// 广播聊天消息给所有客户端
io.emit('chatMessage', message);
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});以上代码中,我们监听 chatMessage 事件,当客户端发送聊天消息时,我们将该消息广播给所有客户端。
客户端代码
// www.javascriptcn.com code example
<!doctype html>
<html>
<head>
<title>Chat Example</title>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
// 发送聊天消息
function sendChatMessage() {
const message = document.getElementById('chatInput').value;
socket.emit('chatMessage', message);
}
// 接收聊天消息
socket.on('chatMessage', (message) => {
const chatBox = document.getElementById('chatBox');
const chatMessage = document.createElement('div');
chatMessage.innerHTML = message;
chatBox.appendChild(chatMessage);
});
</script>
</head>
<body>
<div id="chatBox"></div>
<input type="text" id="chatInput" />
<button onclick="sendChatMessage()">Send</button>
</body>
</html>以上代码中,我们在页面上创建了一个聊天框和一个输入框,当玩家输入聊天消息后,我们将该消息发送给服务器。当客户端收到聊天消息时,我们将该消息显示在聊天框中。
实现实时对战功能
在游戏中,玩家可能需要对战,因此我们需要实现实时对战功能。以下是一个示例:
服务器端代码
// www.javascriptcn.com code example
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
let players = {};
io.on('connection', (socket) => {
console.log('a user connected');
// 新玩家加入游戏
socket.on('joinGame', (playerId) => {
players[playerId] = {
socket: socket,
x: 0,
y: 0,
hp: 100
};
// 广播新玩家加入游戏
socket.broadcast.emit('playerJoined', playerId);
});
// 玩家移动
socket.on('movePlayer', (playerId, x, y) => {
players[playerId].x = x;
players[playerId].y = y;
// 广播玩家移动
socket.broadcast.emit('playerMoved', playerId, x, y);
});
// 玩家发起攻击
socket.on('attack', (attackerId, targetId) => {
const attacker = players[attackerId];
const target = players[targetId];
target.hp -= 10;
// 广播攻击结果
io.emit('attackResult', attackerId, targetId, target.hp);
});
socket.on('disconnect', () => {
console.log('user disconnected');
// 广播玩家离开游戏
socket.broadcast.emit('playerLeft', playerId);
delete players[playerId];
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});以上代码中,我们维护了一个 players 对象,表示所有玩家的状态。当玩家加入游戏时,我们将其加入 players 对象,并广播给所有客户端。当玩家移动时,我们更新 players 对象,并广播给所有客户端。当玩家发起攻击时,我们更新被攻击玩家的状态,并广播攻击结果给所有客户端。当玩家离开游戏时,我们将其从 players 对象中删除,并广播给所有客户端。
客户端代码
// www.javascriptcn.com code example
<!doctype html>
<html>
<head>
<title>Game Example</title>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
let playerId;
// 新玩家加入游戏
function joinGame() {
playerId = Math.random().toString(36).substr(2, 8);
socket.emit('joinGame', playerId);
}
// 玩家移动
function movePlayer(x, y) {
socket.emit('movePlayer', playerId, x, y);
}
// 玩家发起攻击
function attack(targetId) {
socket.emit('attack', playerId, targetId);
}
// 接收其他玩家加入游戏
socket.on('playerJoined', (playerId) => {
// 在游戏中添加新玩家
addPlayer(playerId);
});
// 接收其他玩家移动
socket.on('playerMoved', (playerId, x, y) => {
// 更新玩家位置
updatePlayerPosition(playerId, x, y);
});
// 接收攻击结果
socket.on('attackResult', (attackerId, targetId, hp) => {
// 更新被攻击玩家的血量
updatePlayerHp(targetId, hp);
});
// 接收其他玩家离开游戏
socket.on('playerLeft', (playerId) => {
// 在游戏中删除玩家
removePlayer(playerId);
});
</script>
</head>
<body onload="joinGame()">
<!-- 游戏界面 -->
</body>
</html>以上代码中,玩家加入游戏后,我们将其分配一个 playerId,并发送给服务器。当玩家移动时,我们将其位置发送给服务器。当玩家发起攻击时,我们将攻击目标的 playerId 发送给服务器。当客户端收到其他玩家加入游戏、移动、离开游戏和攻击结果时,我们将更新游戏界面。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67da49b1a941bf713422e778