Cocos creator 3.x uses the official frame synchronization service to develop a real-time battle WeChat mini-game tutorial (3)

The above two chapters show the creation of matching rules and game matching according to the rules . This chapter mainly explains the frame synchronization.

Contents of this chapter:

After the player confirms to start the game, frame synchronization is officially started, and the frame synchronization service will send game frames according to the period set in the matching rules, and the client will process them

When it comes to frame synchronization, we have to mention another synchronization mode: state synchronization. The currently easier-to-understand description is that frame synchronization is used for synchronous operations, and the operation results are processed on the client side. For example, in a 1V1 battle game, player A clicks the fire button and uploads a frame to the game service to tell the service that I am firing. The game The service will send this frame to B in real time, and then B will process the logic after A fires, such as B losing blood and so on. The status service is that A fires, sends the request to the server, calculates the remaining blood of B on the server, and then sends it to B from the server to tell B how much blood you have left, and B's client can display a blood deduction animation. The main difference between the two is where the calculation logic is processed, the frame synchronization tells you the operation, and the state service tells you the result.

Since we are talking about frame synchronization, after reading the above instructions, we probably know when to upload frames. Let's create a battle scene, put a tank on the left, put a tank on the right, and then put a button for The tank is firing, like Jiangzi:
insert image description here
When does this scene come in? The eventTarget.on('battle', function(){//The game has officially started, jump to the battle scene}) in the previous chapter is to jump to this The place of the scene.
In the start() of this scene, we need to determine whether it is on the left or the right according to the player's selfClientId. For example, if selfClientId = 1, the position of the tank is set to the left, and if selfClientId = 2, the position of the tank is set to the right.
Then we add the fire button event:

onbtnFireClick(){
    
    
	this.gameserver.uploadFrame([
        JSON.stringify({
    
    
          r: 45//射击角度,
          i: 1, //子弹类型
          e: 'Fire',//帧类型,表示开火
          n: databus.selfClientId,//自己的clientId
         })
   ]);
}

We can see that this fire button does not have any local logic, it just uploads a frame to the game service, the content is a json text, which contains the content you want to broadcast What bullets, and which player am I in the room (ClientId issued by the room service)
, how do other players receive this frame? bindEvents() is ready when instantiating the game service. If there are players (including yourself) upload the frame, the onSyncFrame event will be received

//监听收到同个房间的帧同步消息
    onSyncFrame(res) {
    
    
        if (!this.reconnecting) {
    
    
            (res.actionList || []).forEach(oneFrame => {
    
    
                let obj = JSON.parse(oneFrame);
                if (obj.e === 'Fire') {
    
    
                    switch (obj.n) {
    
    
                        case 1:
                            eventTarget.emit('leftTankFire', obj.r, obj.i);
                            break
                        case 2:
                            eventTarget.emit('rightTankFire', obj.r, obj.i);
                            break
                    }
                } 
            });
        }
    }

obj.e will filter out the frames whose type is Fire, that is, fire, and obj.n is the uploaded ClientId to determine whether the tank on the left is firing or the tank on the right is firing. The remaining parameters are angle and bullet type. eventTarget.emit is the event emission and monitoring function in cocos creator, used to trigger node events, so we mount script A on the left tank node, eventTarget.on('leftTankFire', function(){ in start() //The tank of the current node fires}), mount script B on the right tank node, monitor 'rightTankFire' in start() and you're done.
If our clientId is 1, click the fire button to upload a frame, onSyncFrame synchronizes to the frame and sends the launch event to the tank of A script, if the other party clicks the fire button, then the frame we synchronized to clientId 2 will be sent to the B script For tanks, the performance of both clients is consistent.

Fire is done, so what about moving? According to the definition of frame synchronization, synchronous operation, then I control the joystick to the left, what frame do I want to send, should the sending type be 'Move', and at the same time carry the parameters of moving direction and speed? Normally, the frame synchronization is like this, but I find it troublesome (because the joystick function of the stand-alone version has been realized, and I don’t want to make major changes...), combined with the concept of state synchronization, the operation of moving the joystick is localized, Then upload the xy coordinates of the current node as a frame in update(), similar to this:

update(){
    
    
	this.gameserver.uploadFrame([
	                JSON.stringify({
    
    
	                    x: this.player.position.x,
	                    y: this.player.position.y,
	                    e: 'Move',
	                    n: databus.selfClientId,
	                })
	            ]);
}

The client receiving the frame can set the position of the corresponding node to the x and y of the frame content according to the clientId (that is, add the logic of obj.e === 'Move' in the onSyncFrame method, transmit it to the corresponding node, and the node will monitor it later modify itself).

In this way, the frame synchronization of moving and firing is almost the same. The frame synchronization of WeChat mini games is simply a client uploading json, and all clients in the same room will receive this json in real time, just like broadcasting , as long as you see It means that there is no problem if the event is triggered according to the predetermined time point, and it is enough to handle the event logic by yourself. 2V2 is just adding 3 and 4 under case 1 and 2. At the beginning, it is recommended to only do 1V1 or 2V2. If the optimization is not in place, 3V3 or 5V5 will be stuck and affect the player experience, and the traffic is not enough, it is difficult to form a team... Say More tears haha.

Let’s write so much in this chapter. The next chapter will introduce some details of frame synchronization, such as displaying the opponent’s player’s nickname, what skin the opponent’s tank uses, how to end frame synchronization and display the settlement page, etc…

Simple online example:
WeChat mini-game "Elite Tanker" 1V1 matchmaking

Guess you like

Origin blog.csdn.net/hangsky1990/article/details/131344468
Recommended