Thiết lập một trò chơi đa người qua Socket.io | hyperPad Documentation

Loading...

Logo

z-f2VkDQ.jpg

Phần 1: Giới thiệu

Các yêu cầu ưu tiên

Trong hướng dẫn này, chúng ta sẽ tập trung vào cách thiết lập một máy chủ và kết nối trò chơi của bạn với nó để bạn có thể kích hoạt các chức năng chơi nhiều người cho dự án của mình thông qua các hành vi Socket.io. Chúng ta sẽ đề cập đến các tính năng và hành vi nâng cao trong hyperPad và việc rất được khuyến nghị là xem qua một số hướng dẫn khác trước và làm quen với phần mềm trước khi tiếp tục.

Hướng dẫn này giả định rằng bạn có hiểu biết tốt về các chức năng cốt lõi của hyperPad cũng như hiểu biết tối thiểu về lập trình bằng văn bản, vì chúng tôi sẽ chú trọng vào kịch bản Javascript để xây dựng một máy chủ trò chơi. Hướng dẫn này cũng giả định bạn có hiểu biết cơ bản về mạng và sự khác biệt giữa một máy chủ và các máy khách của nó.

Mục tiêu chính của hướng dẫn này là dạy bạn những gì bạn cần làm để thêm chức năng multiplayer vào trò chơi của bạn; không phải là để tạo ra trò chơi đó. Chúng ta sẽ khám phá mối quan hệ giữa các khách hàng Socket.io và máy chủ, cũng như cách chúng giao tiếp với nhau với các hành vi Socket.io.

Các yêu cầu

Để tạo và chạy máy chủ, bạn sẽ cần một máy tính có khả năng chạy Node.JS (Mac, Windows, v.v.). Việc cài đặt Node.JS và thiết lập nó cho mục đích của chúng ta sẽ được đề cập trong hướng dẫn này. Nếu bạn đang chạy máy chủ trong mạng gia đình, bạn sẽ cần thay đổi cài đặt chuyển tiếp cổng của gateway của mình nếu bạn muốn có các kết nối đến từ bên ngoài mạng cục bộ của bạn.

Đối với hướng dẫn này, chúng tôi đã tạo ra một trò chơi demo đơn giản. Trong đó, chúng tôi có hai người chơi đang chơi một trò chơi đuổi bắt trong một mê cung nhỏ. Chúng tôi sẽ khám phá cách các hành vi Socket.io được sử dụng trong dự án ví dụ, vì vậy bạn nên tải và mở dự án trong hyperPad.

Dự án ví dụ hoàn chỉnh của hyperPad có thể được tải về tại đây: Multiplayer tag tutorial.tap

Tổng quan

Trong hướng dẫn này, chúng ta sẽ đi qua các điều cơ bản để tạo một máy chủ cho trò chơi của bạn. Máy chủ sẽ xử lý hầu hết các chi tiết trong trò chơi như điểm số, phòng trò chơi, v.v. Sau đó, chúng ta sẽ tạo ra các hành vi gửi thông tin từ trò chơi của chúng ta đến máy chủ và ngược lại.

Dưới đây là quy trình tổng thể của trò chơi của chúng ta:

1. Từ menu chính, chúng ta sẽ kết nối với máy chủ và cho phép người dùng quyết định tạo hoặc tham gia một trò chơi.

a. Nếu tạo một trò chơi, tải phòng chờ.

b. Nếu tham gia một trò chơi, tải danh sách các phòng trò chơi có sẵn.

c. Khi hai người chơi có mặt trong phòng chờ, trò chơi sẽ bắt đầu.

2. Trong một trò chơi, máy chủ sẽ ngẫu nhiên đặt người chơi trong một trong bốn khu vực và chỉ định một trong số họ là "Nó".

a. Đánh dấu người chơi khác sẽ ngẫu nhiên hóa vị trí của họ, hoán đổi trạng thái "Nó" và cộng một điểm cho người chơi đã đánh dấu người khác.

b. Nếu không có người nào bị đánh dấu trong một khoảng thời gian nhất định, máy chủ sẽ trừ 1 điểm từ người chơi hiện đang là "Nó" và hoán đổi trạng thái "Nó" trước khi ngẫu nhiên đặt lại vị trí của người chơi trong các khu vực hồi sinh.

3. Khi một người chơi đạt được một số điểm nhất định, một lớp phủ sẽ được tải lên để tuyên bố người chiến thắng. Sau đó, người chơi sẽ ngắt kết nối khỏi phòng và trở về menu chính.

Phần 2: Thiết lập máy chủ

Tạo một máy chủ Socket.io yêu cầu chúng ta chạy một ứng dụng Javascript sử dụng thư viện Socket.io, lắng nghe các kết nối của người chơi. Socket.io là một thư viện mạng Javascript giúp đơn giản hóa rất nhiều công việc nền tảng trong việc xây dựng một ứng dụng mạng cho chúng ta. Chi tiết sẽ theo sau.

Tải về và cài đặt Node.JS

Để bắt đầu, hãy truy cập Node.JS và tải xuống trên máy tính (Mac, Windows, v.v.) mà bạn muốn chạy máy chủ. Khi tải xong, hãy chạy trình cài đặt và làm theo hướng dẫn của nó. Tất cả các tùy chọn trong quá trình cài đặt có thể để mặc định. Node.JS cho phép chúng ta chạy các ứng dụng Javascript độc lập mà không cần đến trình duyệt web.

Tải về và chạy máy chủ ví dụ

Tiếp theo, tải về ví dụ máy chủ Multiplayer của hướng dẫn này trên GitHub:

https://github.com/hyperPad/multiplayerServerExample

Nhấn nút "Clone or download" và chọn "Download ZIP". Việc này sẽ tải về một bản sao của mã cho ví dụ máy chủ.

chrome_2019-08-05_14-22-14.png

Giải nén tệp ZIP đã tải xuống. Bên trong bạn sẽ thấy một vài tệp nhỏ, nhưng tệp đáng chú ý nhất ở đây là tệp "index.js" là mã cho máy chủ của chúng ta. Tiếp theo, mở dòng lệnh/terminal bên trong thư mục ví dụ máy chủ.

Gõ "npm install" và nhấn Enter, sau đó để nó chạy. npm là một trình quản lý gói đọc tệp package.json và tải về các gói cần thiết cho máy chủ của chúng ta. (Bao gồm cả Socket.io!)

cmd_2019-08-05_14-55-19.png

Khi lệnh kết thúc, chúng ta đã có mọi thứ cần thiết để chạy máy chủ. Trong terminal, gõ "node ." và máy chủ sẽ bắt đầu.

cmd_2019-08-05_15-02-38.png

Thế là xong! Máy chủ của chúng ta hiện đang lắng nghe trên cổng 3000 cho các kết nối Socket.io đến.

"node ." sẽ khởi động Node.JS cho thư mục hiện tại, nơi nó sẽ tìm tệp index trong thư mục và chạy nó. Mặc định, đây là tệp Javascript "index.js", nơi mà phần lớn mã của máy chủ của chúng ta được đặt và sẽ được phân tích trong suốt hướng dẫn này.

Giữ cho terminal mở, vì việc đóng nó cũng sẽ đóng máy chủ. Bạn sẽ thấy nó in ra các thông báo khi người chơi kết nối hoặc ngắt kết nối, và khi các phòng được tạo hoặc bị xóa, cũng như các sự kiện khác.

Lưu ý: Để cho phép các kết nối đến từ bên ngoài mạng gia đình, bạn sẽ cần mở cổng 3000 trên gateway gia đình của bạn. Quy trình này thay đổi từ mạng này sang mạng khác, nhưng một hướng dẫn thường có thể được tìm thấy bằng cách tìm kiếm trên internet cho một hướng dẫn chuyển tiếp cổng cho modem/router nhà của bạn. Bạn có thể cần đóng và khởi động lại máy chủ Node.JS khi bạn thay đổi cài đặt chuyển tiếp cổng.

Phần 3: Kết nối với máy chủ

Khi bạn đã bắt đầu với những điều cơ bản của máy chủ, chúng ta có thể kết nối đến nó trong một trò chơi hyperPad. Điều này nên được thiết lập để trở thành điều đầu tiên xảy ra trong dự án của bạn, bất kể bạn đang ở trong cảnh nào (vì mọi thứ cần giao tiếp với máy chủ). Tốt nhất là gắn hành vi này vào một đối tượng trên Lớp Toàn cầu để nó sẽ áp dụng trên tất cả các cảnh.

Untitled.jpg

Trong dự án ví dụ, nhãn Lớp Toàn cầu "Máy chủ" chứa nội dung trên. (Tải xuống dự án có thể tìm thấy trong Phần 1 của hướng dẫn này dưới mục Các yêu cầu.)

Các hành vi này thực sự là tất cả những gì bạn cần để kết nối với máy chủ. Đầu tiên, dưới tab tùy chỉnh, hãy kéo hành vi Socket.io Client và thả nó xuống. Ở đây, bạn sẽ nhập URL của máy chủ của bạn dưới tab URL trong cửa sổ thuộc tính của nó. Trong hình trên, URL của máy chủ của chúng tôi là "http://192.168.0.191:3000", bao gồm cả giao thức và cổng. Bạn sẽ muốn thay đổi điều này để phù hợp với URL máy chủ của bạn hoặc nó sẽ không hoạt động khi bạn bắt đầu trò chơi.

Bây giờ chúng ta đã có thông tin máy chủ mà chúng ta muốn, nhưng chúng ta vẫn cần kết nối với nó. Vì vậy, tất cả những gì chúng ta cần là hành vi Kết nối với Socket. Kéo một cái xuống, mở thuộc tính của nó và chọn client trong ô trống và đặt thuộc tính Chức năng là "Kết nối".

Bây giờ, khi dự án của chúng ta tải lên, chúng ta sẽ tự động kết nối với máy chủ của chúng ta.

mceclip1.png

Phần 4: Tạo và tham gia phòng

Bước tiếp theo là tạo các phòng trò chơi của chúng ta, nơi người chơi có thể tham gia và chơi cùng nhau.

mceclip2.png

Đây là màn hình Menu Chính đơn giản của chúng ta. Tất cả những gì cần làm là nhấn một trong những nút để bắt đầu một phòng hoặc tìm các phòng có sẵn.

Tạo phòng

Hãy xem cách chúng ta giao tiếp với máy chủ để tạo phòng của mình.

mceclip3.png

Khá đơn giản phải không? Vậy để tóm tắt nhanh, một khi chúng ta chạm vào nút của mình chúng ta sẽ được yêu cầu nhập tên phòng. Khi điều đó hoàn tất, tên đó sẽ được phát ra đến máy chủ nơi phòng được tạo và chúng ta tải lên cảnh phòng chờ.

Từ đây, chúng tôi sẽ thường xuyên sử dụng Emit to Socket. Điều này bởi vì nó là cách chính của chúng tôi để gửi dữ liệu đến máy chủ. Hãy nghĩ đơn giản rằng nó là phiên bản "trực tuyến" của Broadcast Message và Receive Message (Emit to Socket thực hiện cả hai hành động cùng một lúc).

Bây giờ, chúng ta cần thêm một số thông tin vào máy chủ của chúng ta để nó sẽ tạo phòng khi nó nhận được thông điệp từ hành vi Emit của chúng ta.

mceclip4.png

socket.on('createRoom', (roomName, callback) => {

Dòng này tạo một sự kiện socket (dưới dạng một biểu thức lambda) trên máy chủ, lắng nghe các Emits với sự kiện 'createRoom'.

Tham số đầu tiên là giá trị mà chúng tôi truyền qua hành vi Emit to Socket, trong trường hợp này là tên phòng mà người dùng đã nhập vào. Ở đây, chúng tôi đã đặt tên tham số đó là 'roomName'.

Tham số thứ hai là một hàm mà chúng tôi sẽ gọi sau đó trong sự kiện socket để thông báo cho client. Hành vi Emit to Socket sẽ chỉ tiếp tục thực hiện nếu hàm callback được gọi trên máy chủ. Ở đây, chúng tôi đã đặt tên tham số đó là 'callback'.

const room = {
id: uuid(),
name: roomName,
sockets: []
};

Điều này sẽ tạo ra một phiên bản của một cấu trúc sẽ giữ thông tin thiết yếu về một phòng.

'id' sẽ là một định danh duy nhất được tạo ra bởi hàm tiện ích 'uuid()'. Điều này sẽ giúp chúng ta xác định chính xác phòng này so với danh sách nhiều phòng được tạo khác sau này.

'name' sẽ được đặt là tên mà người dùng đã nhập vào trước đó.

'sockets' sẽ được khởi tạo như một mảng rỗng. Về sau, điều này sẽ theo dõi các socket của người chơi được kết nối với phòng đó.

rooms[room.id] = room;

'rooms' là một danh sách toàn cầu của các phòng hiện đang hoạt động. Vì chúng ta đang tạo một phòng mới, chúng ta sẽ lưu trữ nó trong danh sách theo ID của nó.

joinRoom(socket, room);

Điều này sẽ gọi hàm toàn cầu 'joinRoom' (dòng 29), sẽ thêm socket của người chơi vào mảng 'sockets' của phòng. Vì người chơi đã tạo ra phòng, điều này cũng sẽ khiến họ tham gia vào phòng đó.

callback();
});

Cuối cùng, chúng tôi kích hoạt hàm callback để thông báo cho client rằng phòng đã được tạo. Điều này sẽ cho phép Emit to Socket tiếp tục thực hiện, điều này sẽ tải cảnh Phòng Chờ tiếp theo. Điều này cũng đánh dấu sự kết thúc của sự kiện socket 'createRoom'.

Tham gia phòng

Tham gia phòng có chút khác biệt vì chúng ta sẽ cần truy cập thông tin từ một cảnh khác từ nút.

mceclip5.png

Đối với các phòng tham gia, chúng tôi đã đặt đầu tiên của hành vi chúng ta trên lớp toàn cầu bên cạnh nơi chúng ta kết nối với máy chủ. Bằng cách này, chúng tôi có thể truy cập thông tin từ bất kỳ cảnh nào của chúng tôi, trong trường hợp này là danh sách phòng của chúng tôi. Đối với nút, khi chạm vào nó sẽ đơn giản tải người chơi vào cảnh danh sách phòng.

Ở đây chúng tôi có hành vi thứ hai của chúng tôi để giao tiếp với máy chủ. Sự kiện Socket có thể được xem như Nhận Thông điệp vì nó sẽ chỉ kích hoạt khi thông điệp đã được phát sóng từ máy chủ.

Cách tốt nhất để nghĩ khi sử dụng Sự kiện Socket và Emit to Socket là Sự kiện Socket phản ứng chỉ với thông tin đến từ máy chủ, trong khi Emit to Socket được gọi để phản ứng với các hành động thực hiện tại địa phương.

Đối với logic của chúng tôi, khi chúng tôi kết nối với máy chủ, chúng tôi sẽ Emit yêu cầu 'getRoomNames' để lấy bất kỳ tên phòng nào có sẵn.

mceclip19.png

Rồi, chúng ta sẽ thiết lập một nhãn mà người chơi có thể nhấn vào để vào.

mceclip6.png

Đây là cảnh Danh sách Phòng của chúng ta. Ở đây là nơi bất kỳ phòng trò chơi nào có sẵn sẽ được tải và hiển thị. Chỉ cần nhấn vào tên phòng sẽ tải người chơi vào. Nhờ vào các hành vi trước đó của chúng tôi, danh sách sẽ tự động tải tất cả các phòng mở và tạo nhãn tên phòng trên màn hình. Nếu không có gì xuất hiện, chúng tôi có nút Làm mới danh sách đơn giản lặp lại hành vi để tải chúng thêm lần nữa.

mceclip8.png

Ở đây chúng ta có logic để thiết lập danh sách. Chúng ta sẽ không đi quá chi tiết ở đây vì chúng tôi chỉ muốn biết cách điều này kết nối với máy chủ của chúng tôi.

Bắt đầu, chúng ta có hành vi Emit to Socket. Điều này yêu cầu máy chủ gửi thông tin về các phòng có sẵn. Từ đó, chúng ta có hành vi Get Array Value. Tất cả dữ liệu gửi từ máy chủ sẽ được gửi dưới dạng một Mảng và thông tin cần thiết sẽ ở các giá trị đầu tiên. Vì vậy, chúng tôi đặt Get Array Value của mình để lấy giá trị tại chỉ mục 0. Từ đó, các hành vi của chúng tôi sẽ trích xuất dữ liệu và tạo nhãn cho mỗi phòng, phát động chúng trên màn hình của chúng tôi.

Tiếp theo, chúng ta sẽ kiểm tra đối tượng mà chúng ta cần nhấn, trong cảnh của chúng tôi nó là nhãn có tên là Tên Phòng.

mceclip9.png

Văn bản này hoạt động như nút của chúng tôi khi được phát động, nhưng chúng tôi vẫn cần đính kèm ID phòng mà chúng tôi muốn kết nối với. Để làm điều đó, chúng tôi đầu tiên cần lấy ID phòng, và chúng tôi làm điều đó với hành vi Get Attribute và đặt nó thành động. Sau đó, chúng tôi phát ra đến máy chủ rằng chúng tôi muốn tham gia phòng này và vào phòng chờ.

mceclip10.png

socket.on('joinRoom', (roomId, callback) => {

Đây là điểm vào cho sự kiện socket 'joinRoom'. Giá trị của tham số đầu tiên sẽ là ID phòng mà chúng tôi muốn tham gia đã được phát ra đến máy chủ. Ở đây, chúng tôi đã đặt tên tham số là 'roomId'.

const room = rooms[roomId];
joinRoom(socket, room);

Với roomId được cung cấp bởi client, chúng tôi có thể tìm ra phiên bản phòng chính xác trên máy chủ. Với điều đó, chúng tôi sẽ gọi hàm toàn cầu 'joinRoom' (dòng 29) với socket của người chơi muốn kết nối và phiên bản phòng. Chúng tôi sẽ xem xét hàm 'joinRoom' ngay sau đây.

callback();
});

Cuối cùng, chúng tôi kích hoạt hàm callback để thông báo cho client rằng hãy tiếp tục tải cảnh Phòng chờ, đánh dấu sự kết thúc của sự kiện socket 'joinRoom'.

Vậy, điều gì đang xảy ra chính xác trong hàm 'joinRoom'? Hãy cùng xem nào.

mceclip11.png

room.socket.push(socket);

Như đã đề cập trước đó, mảng thành viên 'room.socket' theo dõi các socket được kết nối trong một phòng. Dòng này thực hiện điều đó bằng cách thêm socket vào mảng.

socket.join(room.id, () => {
socket.roomId = room.id;
console.log(socket.id, "Tham gia", room.id);
});

Đây là cuộc gọi chính thức để kết nối client với một phòng. Đầu tiên chúng tôi yêu cầu socket tham gia một phòng bằng ID của nó. Khi điều đó hoàn tất thì hàm callback tiếp theo sẽ được gọi, nơi chúng tôi đính kèm ID phòng cho socket. Cuối cùng, chúng tôi ghi lại trong bảng điều khiển rằng một người chơi đã tham gia một phòng!

mceclip12.png

Phòng chờ

Phòng chờ đơn giản là một cảnh mà chúng ta tải người chơi vào khi họ chờ những người chơi khác tham gia, hoặc để trò chơi bắt đầu.

mceclip13.png

Khi vào phòng, chúng tôi sẽ phát một thông điệp 'ready' đến máy chủ. Khi máy chủ đã nhận được hai thông điệp như vậy, nó sẽ gửi một thông điệp thông báo rằng nó sẽ bắt đầu trò chơi ('initGame'). Chúng tôi nhận thông điệp đó với Sự kiện Socket và do đó, tải lên cấp độ trò chơi của chúng tôi. Đối với các hành vi của chúng tôi, đó là tất cả. Bạn có thể thêm một nút sẽ ngắt kết nối bạn khỏi phòng và gửi bạn trở lại menu chính nếu bạn muốn.

Ở phía máy chủ, hãy phân tích mã để xem điều gì đang diễn ra ở đó.

mceclip14.png

Đây là sự kiện 'ready' được gọi khi một client đã tham gia một phòng và sẵn sàng kết nối.

const room = rooms[socket.roomId];

Bởi vì chúng tôi đã gán ID phòng cho socket, chúng tôi có thể lấy phòng để kiểm tra xem trò chơi có thể bắt đầu hay không.

if (room.sockets.length == 2) {

Ở đây chúng tôi kiểm tra xem có hai người chơi đang chờ trong phòng. Giả sử điều đó đúng, và chúng tôi tiếp tục để bắt đầu trò chơi.

for (const client of room.sockets) {
client.emit('initGame');
}

Bây giờ có hai người chơi, chúng tôi lặp qua từng socket và phát sự kiện 'initGame' để mỗi client tải cảnh Cấp độ, như đã mô tả trước đó.

Phần 5: Gameplay

Giờ thì chúng ta sẽ đi vào phần quan trọng. Đây là nơi 90% công việc của chúng tôi sẽ diễn ra. Dưới đây là cấp độ trò chơi mà chúng tôi thiết kế cho hướng dẫn này.

mceclip15.png

Trước khi chúng tôi đi vào điều đó, chúng tôi có một nhãn có tiêu đề "Lógica Trò Chơi", hãy mở nó ra và xem qua.

mceclip16.png

Wow, đó là rất nhiều hành vi! Đừng lo, đây chỉ là cách chúng tôi phát động người chơi vào trò chơi. Hãy xem qua kỹ hơn;

mceclip17.png

Chúng tôi bắt đầu với một hành vi Emit to Socket thông báo máy chủ rằng trò chơi đã bắt đầu, với sự kiện 'startGame'. Sau đó, chúng tôi lấy mảng mà máy chủ trả về, lấy giá trị đầu tiên của nó và với Get Dictionary Value, chúng tôi lấy các thuộc tính khác nhau mà đối tượng của chúng tôi sẽ cần. Một cây riêng lẻ sẽ thực hiện tương tự, ngoại trừ đối thủ của người chơi. Cuối cùng, chúng tôi phát thông điệp 'init' cho đối tượng người chơi của chúng tôi để bắt đầu mọi thứ.

Hãy xem điều gì đang xảy ra ở phía máy chủ khi chúng tôi phát sự kiện 'startGame'.

mceclip20.png

Phần đầu tiên của sự kiện socket mà bạn thấy ở đây là thiết lập các giá trị ban đầu cho mỗi client, sau đó thêm bất kỳ client nào không phải là client phát ra vào mảng 'others' cục bộ.

mceclip21.png

Trong phần thứ hai, một danh sách từ điển cục bộ được gọi là 'ack' được tạo ra. Trong đó, chúng tôi có thông tin về bản thân mình, và các client cạnh tranh khác. Chúng tôi sau đó gửi thông tin đó trở lại client bằng cách chuyển từ điển 'ack' vào hàm callback, trở thành giá trị kết quả của phép phát hành hành vi Emit to Socket gọi.

Sau đó, một cuộc gọi timeout kéo dài 5 giây được thực hiện để cuối cùng bắt đầu vòng đấu, sau khi mọi người đã có tất cả thông tin cần thiết để chơi trò chơi. Hàm 'beginRound' (dòng 99) điều khiển một số logic cụ thể cho dự án này. Chúng tôi sẽ không đi chi tiết quá nhiều về điều đó, nhưng về cơ bản nó kiểm tra nơi đặt người chơi, kiểm tra điểm số, cũng như thông báo cho các client ai là Nó.

Như đã đề cập trước đó, tin nhắn 'init' được gọi trên nhãn "Lógica Trò Chơi" khi mọi thứ sẵn sàng để tiếp tục. Trong đối tượng người chơi, chúng tôi sẽ xem các hành vi trên đó nơi mà nó nhận thông điệp 'init'.

mceclip22.png

Tại đây, bạn có thể thấy rằng chúng tôi có một số cây hành vi cho người chơi của chúng tôi. Đầu tiên, chúng tôi sẽ bắt đầu với cây ở phía trên bên trái.

mceclip23.png

Đây là hành vi thực sự khởi động mọi thứ khác trong trò chơi của chúng tôi.

Đầu tiên, chúng tôi nhận thông điệp 'init' gửi từ nhãn "Lógica Trò Chơi". Từ đó, chúng tôi lấy ID máy chủ của đối tượng của chúng tôi và bật một trong các Sự kiện Socket cũng như thiết lập màn hình trò chơi của chúng tôi để có thể theo dõi chính xác nhân vật của chúng tôi.

Đồng bộ hóa di chuyển

mceclip24.png

Đây là một trong những hành vi quan trọng nhất của chúng tôi. Cây nhỏ này được thiết kế để cập nhật vị trí của người chơi trên máy chủ mỗi khi chúng tôi di chuyển cần điều khiển. Bạn có thể đã nhận ra nó cũng tham chiếu đến một số giá trị từ điển. Chúng tôi lấy những giá trị đó từ một hành vi từ điển độc lập chứa các giá trị X và Y của người chơi.

Hãy xem sự kiện 'moved' trên máy chủ.

mceclip25.png

data = JSON.parse(data);

Các từ điển, khi được gửi từ một client đến máy chủ, cần được phân tích để đọc dữ liệu dễ dàng. Điều này là do các từ điển trong hyperPad được mã hóa thành một cấu trúc JSON khi phát đến một máy chủ. Dòng này phân tích cấu trúc chuỗi JSON và lưu trữ danh sách từ điển lại vào biến 'data' cục bộ.

socket.x = data.x;
socket.y = data.y;

Ở đây, chúng tôi cập nhật vị trí X và Y được lưu trữ trên socket với các giá trị mới được cung cấp bởi client.

for (const client of room.sockets) {
if (client == socket) {
continue;
}
client.emit(socket.id, {
x: socket.x,
y: socket.y,
score: socket.score,
isIt: socket.isIt
});
}

Tiếp theo, chúng tôi lặp lại qua tất cả các client để cập nhật cho họ về vị trí mới của chúng tôi và các chi tiết khác, loại trừ chính mình (tức là client phát ra không cần biết vị trí của chính mình).

mceclip26.png

Cây này quản lý phần lớn trò chơi của chúng tôi. Chúng tôi sử dụng một Sự kiện Socket khi máy chủ kiểm tra ai là người chơi được đánh dấu là Nó, điều này được phát bởi 'beginRound' (dòng 99) trên máy chủ.

Rồi, chúng tôi lấy ID máy chủ của đối tượng từ mảng và sử dụng Dictionary Value để phân tích nó thành các phần dữ liệu khác nhau mà nó chứa. Từ đó, chúng tôi lấy điểm số của chúng tôi, xem chúng tôi có được đánh dấu là Nó hay không, cũng như vị trí x và y của đối tượng và sau đó áp dụng chúng vào các thuộc tính của đối tượng. Phần còn lại của các hành vi là để thiết lập và điều khiển giao diện người dùng trong trò chơi của chúng tôi.

Kết luận

Có rất nhiều thứ để tiếp thu ở đây, nhưng hy vọng nếu bạn đã đến đây, bạn sẽ có một hiểu biết về cách sử dụng các hành vi Socket.io để tạo trải nghiệm chơi đa người cho người chơi của bạn.

Hãy thử đi! Lấy một trò chơi hiện có mà bạn đã tạo và thử thêm một số chức năng trực tuyến, chẳng hạn như một cảnh bảng xếp hạng điểm cao kết nối đến một máy chủ và yêu cầu danh sách 10 điểm hàng đầu với tên người chơi để hiển thị.

Việc dạy một ngôn ngữ kịch bản như Javascript trong một bài viết đơn lẻ là rất khó. May mắn thay, nếu bạn gặp sự cố, có rất nhiều tài nguyên khác để giúp bạn với việc viết các ứng dụng Javascript cho Node.JS và Socket.io;

Nh learn Javascript - https://developer.mozilla.org/bm/docs/Web/JavaScript

Nh learn Socket.io - https://socket.io/docs/

Nh learn Node.JS - https://nodejs.org/en/docs/