Create a multiplayer online game based on WebRTC

Source: Internet
Author: User

The goal of this project is to develop an online multiplayer game with as few server resources as possible, while expecting to run the game on one user's browser while allowing another player to connect. In addition, it is hoped that the program is as simple as possible for analysis in blogs.

Application of the technology

I found WebRTC when I first came into contact with the technology, and I thought the technology was right for the project. WebRTC is a new network standard designed to provide instant communication capabilities to Web browsers. Most WebRTC cases are about creating a video or audio stream, but this technology can also be used to transfer binary data. In this project, it is more inclined to use the data channel to transfer the user's input to the host, and the game state is transferred to the player.

However, WebRTC does not completely eliminate the dependency on the server. In order to establish a connection, two servers must transfer a small amount of information. Once the connection is established, the next whole connection process is pure peer.

Library

The WebRTC API is relatively complex, so a good simplified library is necessary. Peerjs is currently one of the most versatile libraries, but has not been updated for two years. There were a few serious holes in the use of Peerjs and I had to give up using it. Simple-peer is a good alternative, providing a lot of simple interfaces for creating WebRTC connections. Here's his code:

var simplepeer =Require' Simple-peer ')var peer1 =New Simplepeer ({initiator:True})var peer2 =New Simplepeer () Peer1.on (' Signal ',function(data) {When Peer1 had signaling data, give it to Peer2 somehow peer2.signal (data)}) Peer2.on (' signal ', function (data) { //when peer2 have signaling data, give it to Peer1 somehow peer1.signal (data)} ) Peer1.on (' Connect ', function () { //wait for ' connect ' event before using the data channel Peer1.send (
                           
                             ' Hey peer2, how is it going? ')}) Peer2.on (
                            ' data ', function (data) { //Got a data channel message Console.log (' got a message from Peer1: ' + Data}})     
                                  
Establishment connection

In order to create a connection between two browsers, a signal output transmission of approximately 2kb is required. Using the Firebase Live database is a good choice because it allows you to easily synchronize data between two browsers, and the free tier provides a lot of storage space.

From the user's point of view, the host gives the player a four-letter code to connect to the game. From a browser point of view, this process is just a little more complicated. As a reference, my database rules are as follows:

{"Rules": {"Rooms": {//4 Digit-Used toConnect players"$room _code": {" host": { "$player": { "$data": { "data": { //data from the host For the Player}}}, "players": { "$player": {"$data": {  "data": { //data from the Player for the host}}}, ' Createdat ': { //Timestamp set by Host ' when ' is created}}}}} 
Create a Room

To create a valid room, the host first generates code by randomly attempting a 4-character code until it finds a room that is not used. If the room does not exist in the database, or if the room was created 30 minutes ago, the room is considered unused. The host should delete the room at the beginning of the game, but I want to make sure to avoid the zombie room. When the host finds an open room, the host's browser adds itself as a host to the room and waits for the player to join.

function Getopenroom (database) {ReturnNew Promise(Resolve, reject) = {Const CODE = Generateroomcode ();Const = DATABASE.REF (' rooms/' +code); Room.once (' Value ').Then ((snapshot) = {Const ROOMDATA = Snapshot.val ();if (Roomdata = =NULL) {The DoesNot exist Createroom (guest).Then (resolve (code)); }else {Const ROOMTIMEOUT = 1800000; // min Const now = Date.now (); const mssincecreated = Now-roomdata.createdat; if (mssincecreated > Roomtimeout) {//It's an old guest so  wipe it and create a new one Room.remo ve (). Then (() = Createroom (guest). Then (resolve (code));} else { //the   different code resolve (Getopenroom (database));}})});}) 
Join the game

The player joins the game by entering the room code and user name. The participating player's browser will alert the host by adding entries in the route rooms/[code]/players . When the player obtains their signal data, the data is sent to the route rooms/[code]/players/[name] .

Codeand name is enteredby userConst PEER =New Simplepeer ({Initiator:true});This.peer = peer;This.setstate ({Host:peer});Sending signaling data from Playerpeer.On(' Signal ', (signaldata) = {Const NAMEREF = Database.ref ('/rooms/' +code+'/players/' +name);const newsignaldataref = Nameref.push (); Newsignaldataref.set ({data:JSON.stringify ( Signaldata)}); /listen for signaling data from host for meconst hostsignalref = database. ref ( '/rooms/' +code+ '/host/' +name); hostsignalref. on ( ' child_added ', (res) + = { Peer.signal (Json.parse (Res.val (). data));            

The host will wait until the new player is added. Once the player is connected, the host receives the signal they send and uses its own signal to route back rooms/[code]/host/[name] .

ListenForNew Playersplayersref.On(' Child_added ', (res) = {const playername = Res.key; //Create Peer channel const Peer =  New Simplepeer (); //Listen for signaling data from specific player Playerref.on ( ' child_added ', (res) = Peer.signal (Json.parse (Res.val (). data)); //Upload signaling data from host const signaldataref = Database.ref ( '/rooms/' +code+ '/host/' +playerName); peer.< Span class= "Hljs-literal" >on ( ' signal ', (signaldata) + = { Const NEWSIGNALDATAREF = Signaldataref.push (); Newsignaldataref.set ({data:JSON.stringify (Signaldata)}); });});

After this, the host connects with the user peer.on(‘data’, cb) peer.send(data) . Once connected to the host, the player's machine terminates its Firebase connection, and the host performs the same operation when the game starts.

Done! In this step I have established a two-way connection between the player and the host, just like the old traditional server. The next step is to start the game and transfer the data between players.

Get user input

Once the user presses the key, their input is transmitted in JSON format. Like what{ up: true }

The host keeps track of each player's injection and controls the player's actions based on these inputs.

Share Game Status

In order to ensure the game development process is simple, I prefer to use the 2D framework Phaser. The game runs on the host machine, and the basic physical operations such as collisions are at the host. Each frame, the location and size of all sprites will be transferred to each player. To simplify the process, I use sprite data to redraw the entire game in the player's browser. Although this solution is practical, a more complex game may require a more efficient process of sharing the game state.

Game screen

The game I used to test the above code is a simple horizontal version of 2D games. There is a randomly occurring platform in the game, and the last player to stay on the platform wins. If there is a problem with the game, it is because I did not spend a lot of energy on the polishing game.

Attention

Because the game's server is running on one of the players ' machines, the player can manipulate the game by modifying the code. This online program is good for games that friends play, as long as your friends don't cheat.

Summarize

I built a peer-to-hand game where each player only needs to use 2KB server bandwidth. In this case, my game can support up to 500,000 players per month with the FIREBSE trial version. In addition, the code in this article is sufficient for most applications. All in all, WebRTC is a very smart technology, looking forward to more projects based on its birth!

http://geek.csdn.net/news/detail/210754

Create a multiplayer online game based on WebRTC

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.