简单的多人游戏系统开发

· Technology

Repo

还是向 tsoding 学习,看他视频可以学到很多,例如一开始使用 json 传递数据,后面为了优化性能,需要去做一些统计,发现性能关键问题,做去思考优化。

后端这边我用 Go 去写。

玩家移动

当玩家移动时,需要计算新的位置,server 这边收到需要移动的消息,会在下一帧中同步移动消息到所有 player,并在 server 中计算新的位置,则 client 收到消息则更新 player 的 state 为 server 最新的发送的,并在下一帧中更新计算新的位置。这样两边同步计算,不需要依赖 server 端的计算,尽可能的尽快渲染。因为网络通信都有会延迟。

通过 mask,可以记录短时间内多次移动情况。

// 通过累加方向上的变化量来更新玩家的位置。通过计算并归一化方向向量,确保玩家在多个方向同时移动时,不会因为累加的方向影响到移动的速度(归一化确保移动速度一致)。
// 归一化:归一化方向向量的作用是确保无论玩家同时移动几个方向(例如斜方向),玩家的移动速度始终保持一致。
// 坐标更新:最后,结合玩家速度和帧时间,计算出新的位置,并使用 properMod 确保位置值不超出游戏世界的边界。
func (p *PlayerOnServer) update(deltaTime float64) {
	dx := 0.0
	dy := 0.0
	for dir := 0; dir < directionCount; dir++ {
		if ((p.Moving >> dir) & 1) != 0 {
			dx += float64(directions[dir][0])
			dy += float64(directions[dir][1])
		}
	}
 
	l := dx*dx + dy*dy
 
	if l != 0 {
		length := math.Sqrt(l)
		dx /= length
		dy /= length
	}
 
	p.X = float32(properMod(float64(p.X)+dx*playerSpeed*deltaTime, worldWidth))
	p.Y = float32(properMod(float64(p.Y)+dy*playerSpeed*deltaTime, worldHeight))
}

Websocket

javascript WebSocket

“text frames” – contain text data that parties send to each other.

“binary data frames” – contain binary data that parties send to each other.

“ping/pong frames” are used to check the connection, sent from the server, the browser responds to these automatically.

there’s also “connection close frame” and a few other service frames.

In the browser, we directly work only with text or binary frames.

 
// The message types are defined in RFC 6455, section 11.8.
 
const (
 
  // TextMessage denotes a text data message. The text message payload is
 
  // interpreted as UTF-8 encoded text data.
 
  TextMessage = 1
 
 
 
  // BinaryMessage denotes a binary data message.
 
  BinaryMessage = 2
 
 
 
  // CloseMessage denotes a close control message. The optional message
 
  // payload contains a numeric code and text. Use the FormatCloseMessage
 
  // function to format a close message payload.
 
  CloseMessage = 8
 
 
 
  // PingMessage denotes a ping control message. The optional message payload
 
  // is UTF-8 encoded text.
 
  PingMessage = 9
 
 
 
  // PongMessage denotes a pong control message. The optional message payload
 
  // is UTF-8 encoded text.
 
  PongMessage = 10
 
)
 
 
 
 
 

在 js 这边可以处理的 binaryMessage 两种格式,一种默认使用的是 Blob,一种是 ArrayBuffer

type BinaryType = "arraybuffer" | "blob";

A call socket.send(body) allows body in string or a binary format, including Blob, ArrayBuffer, etc. No settings are required: just send it out in any format.

When we receive the data, text always comes as string. And for binary data, we can choose between Blob and ArrayBuffer formats.

That’s set by socket.binaryType property, it’s "blob" by default, so binary data comes as Blob objects.

Blob is a high-level binary object, it directly integrates with and other tags, so that’s a sane default. But for binary processing, to access individual data bytes, we can change it to "arraybuffer":

Comments (0)

    Send comment

    Markdown supported. Please keep comments clean.