تطوير الخادم للعبة متعددة اللاعبين باستخدام nodejs و magx

بدأ العديد من المطورين في تطوير خادم متعدد المستخدمين عبر الإنترنت استنادًا إلى مكتبة socket.io . تجعل هذه المكتبة من السهل جدًا تنفيذ تبادل البيانات بين العميل والخادم في الوقت الفعلي ، ولكن لا يزال يتعين عليك التفكير في كل منطق وواجهة التفاعل بين الخادم والعميل ، بالإضافة إلى بنية القياس وتحسين حركة المرور.







أريد أن أتحدث عن مكتبة magx ، والتي باستخدامها لا يمكنك التفكير في مكون الشبكة (الاتصال بين الخادم والعملاء) ، ولكن التركيز فورًا على تطوير منطق اللعبة وواجهة المستخدم للعميل.







عند تصميم بنية لعبة متعددة اللاعبين ، عادة ما يتم أخذ طريقتين في الاعتبار: مع خادم استبدادي وغير سلطوي (عميل سلطوي). يتم دعم كل من هذه الأساليب بواسطة مكتبة magx. لنبدأ بنهج أبسط - غير سلطوي.







خادم غير موثوق



جوهرها هو أن الخادم لا يتحكم في نتائج الإدخال لكل لاعب. يتتبع العملاء بشكل مستقل الإجراءات التي أدخلها اللاعب ومنطق اللعبة محليًا ، وبعد ذلك يرسلون نتيجة إجراء معين إلى الخادم. بعد ذلك ، يقوم الخادم بمزامنة جميع الإجراءات التي تم تنفيذها مع حالة اللعبة للعملاء الآخرين.







من الأسهل التنفيذ من وجهة نظر معمارية ، لأن الخادم مسؤول فقط عن الاتصال بين العملاء ، دون إجراء أي حسابات إضافية يقوم بها العملاء.







باستخدام مكتبة magx ، يمكن تنفيذ مثل هذا الخادم في بضعة أسطر من التعليمات البرمجية:







import * as http from "http"
import { Server, RelayRoom } from "magx"

const server = http.createServer()
const magx = new Server(server)

magx.define("relay", RelayRoom)

// start server
const port = process.env.PORT || 3001
server.listen(port, () => {
  console.info(`Server started on http://localhost:${port}`)
})
      
      





الآن ، لتوصيل العملاء بهذا الخادم وبدء تفاعلهم ، ما عليك سوى تثبيت مكتبة js:







npm install --save magx-client









وربطه بالمشروع:







import { Client } from "magx-client"
      
      





بدلاً من ذلك ، يمكنك استخدام رابط مباشر لاستخدام HTML:







<script src="https://cdn.jsdelivr.net/npm/magx-client@0.7.1/dist/magx.js"></script>
      
      





بعد الاتصال ، ستتيح لك بضعة أسطر فقط تكوين الاتصال والتفاعل مع الخادم:







// authenticate to server
await client.authenticate()

// create or join room
const rooms = await client.getRooms("relay")
room = rooms.length 
  ? await client.joinRoom(rooms[0].id)
  : await client.createRoom("relay")

console.log("you joined room", name)

// handle state patches
room.onPatch((patch) => updateState(patch))

// handle state snapshot
room.onSnapshot((snapshot) => setState(snapshot))

// handle joined players
room.onMessage("player_join", (id) => console.log("player join", id))

// handle left players
room.onMessage("player_leave", (id) => console.log("player leave", id))
      
      





تم وصف مثال مفصل لكيفية بناء تفاعل بين العملاء وخادم غير موثوق في المثال المقابل في مشروع magx -amples .







خادم موثوق



, , - .







- . , , , , .







, . , (cheating).







. magx , (worker). , .







/ . — . Mosx — , magx - , .









, . mosx — @mx.Object, , @mx. :







@mx.Object
export class Player {
  @mx public x = Math.floor(Math.random() * 400)
  @mx public y = Math.floor(Math.random() * 400)
}

@mx.Object
export class State {
  @mx public players = new Map<string, Player>()

  public createPlayer(id: string) {
    this.players.set(id, new Player())
  }

  public removePlayer(id: string) {
    this.players.delete(id)
  }

  public movePlayer(id: string, movement: any) {
    const player = this.players.get(id)
    if (!player) { return }
    player.x += movement.x ? movement.x * 10 : 0
    player.y += movement.y ? movement.y * 10 : 0
  }
}
      
      





, — Map() . (Array) (number, string, boolean) .









. :







export class MosxStateRoom extends Room<State> {

  public createState(): any {
    // create state
    return new State()
  }

  public createPatchTracker(state: State) {
    // create state change tracker
    return Mosx.createTracker(state)
  }

  public onCreate(params: any) {
    console.log("MosxStateRoom created!", params)
  }

  public onMessage(client: Client, type: string, data: any) {
    if (type === "move") {
      console.log(`MosxStateRoom received message from ${client.id}`, data)
      this.state.movePlayer(client.id, data)
    }
  }

  public onJoin(client: Client, params: any) {
    console.log(`Player ${client.id} joined MosxStateRoom`, params)
    client.send("hello", "world")
    this.state.createPlayer(client.id)
  }

  public onLeave(client: Client) {
    this.state.removePlayer(client.id)
  }

  public onClose() {
    console.log("MosxStateRoom closed!")
  }
}
      
      







— .







const magx = new Server(server, params)

magx.define("mosx-state", MosxStateRoom)
      
      





magx-examples.







?



:







Mosx



  1. @mx
  2. @mx .
  3. @mx.Object.private @mx.private, .
  4. .
  5. Typescript
  6. ( MobX patchpack — )


Magx



  1. API.
  2. :

    • ( webockets)
    • ( )
    • ( )
    • ( )
  3. الغرف المدمجة: اللوبي والتتابع (للخادم غير المعتمد)
  4. مكتبة JS Magx-client للعمل مع الخادم
  5. مراقبة وحدة التحكم magx-Monitor لإدارة غرف الخادم وعملائها وحالة المشاهدة
  6. دعم كامل للطباعة
  7. الحد الأدنى من التبعيات (لمكتبة notepack.io - لتقليل حركة مرور الشبكة)


هذا المشروع صغير جدًا وآمل أن يساعده اهتمام المجتمع في تطويره بشكل أسرع.








All Articles