Funny Wars is a Websocket two-player real-time game I developed in my sophomore year.
If the server still has enough memory to go down, this address should be accessible. It doesn’t matter if I can’t access it, I have the code for all my individual projects on Github, including this one. At the same time, this Github warehouse is also the one I update all the time. Students who are interested or looking forward to the next project can follow this project on Github. Welcome start and fork.
This game originated from the extracurricular homework assigned by the enterprise teacher in the first phase of sophomore year. I didn’t finish it well because of my poor algorithm, but I always like to make things more interesting or meaningful. With confidence in my server ability, I plan to make it an online points game. I made a date with my classmate, who helped me design the interface sketches, trophy images, and core code for collisions, while I took care of the back end, Ajax, and part of the front end. I wrote the game while dealing with other homework in class. After more than a month of busy work, I finally got online. At that time, the game interface was realized by DOM. As a science student who never failed physics, even if I set the JS timer to 16 milliseconds and followed the 60HZ law, the occasional lag could not be solved.
This is what the first edition looked like:
Ludicrous Battle of the past life
In this life
Since the reconstruction of Demo0, I began to learn Websocket. I wanted to make a chat room, but the UI design was very heavy in the early stage, so I simply began to reconstruct Demo2, using Websocket and a fun two-man battle.
This technology stack is Spring Boot family bucket, Websocket, Canvas, Sina OAuth2 and front-end Vue2.
- Websocket: predecessors have beads and jade in the past, the younger generation will not show shame.
- Vue: When my predecessors posted Vue works, beginners would think it was an animation library, and I thought so at first. The traditional front end often needs to do a lot of DOM data and event binding operations. Document.queryselecotr () is the code we cannot do without before VUE. So it’s not an animation library, it saves you a lot of data-and-event-binding code and allows you to spend more time on design and animation, which is why Vue works tend to look better. For this refactoring, I used Vue to bind DOM data to events, reducing the template-style JS code, and writing Vue should feel like annotated programming for those familiar with Spring.
- OAuth2: Third-party login is something I’ve always wanted to try.
- Canvas: Standard for animations or games. The browser provides you with an animation API. The browser uses its own logic to adjust the animation frequency based on the load on the hardware to achieve a perfect balance of performance and smoothness, which is much more efficient and reliable than writing your own timer.
Should a beginner Vue Javaer use WebPack? Webpack is not a must for developers like me who have never used WebPack. I don’t believe webpack can do things that traditional HTML+CSS+JS can’t.
Websocket can be implemented in almost any back-end language, so this summary does not care about the specific implementation of a particular language.
Websockets are nothing new. Browsers have supported websockets for years, and they have been used in a wide range of applications, from the stereotypical stock quotes and Web chat to online document editing, such as graphite documents, and even Web user behavior analysis (as a typical non-social programmer, I’m very interested in knowing users’ behaviors and preferences without having to communicate with them, and more importantly, their data is more honest than their mouths. The development of Websocket games is slower. On the one hand, a large number of logical operations of Websocket games need CPU consumption, while Canvas, its partner, needs GPU rendering. On the other hand, the consistency and synchronization of Websocket games are more difficult to achieve than initial games. Websocket probably came into the public eye with the release of Agar in mid-2015.
Let’s get down to business.
How did I develop Ludicrous Battles?
I think it can be divided into three parts: data transfer, consistency and performance optimization.
Data transmission:
First, you need to address the transfer of data between the two pages.
Each browser (or page) that has a Websocket long connection with the server is called a client. A more simple scenario is server-side push message to every client, like stock quotes, its implementation principle is the server use an array to save all the clients connected to the establishment of long, when the server needs to push message, as long as issued news can iterate through group, when the user closes the page server response and remove nodes from the array. However, user A sends data to user B, just as player A sends data to player B in the game. In fact, player A cannot establish A connection with player B, but can only send messages to the server, and then use the server to send data to player B indirectly. At this time, the server only acts as A message relay station. Here I made a very successful first step.
Another problem is the targeted push of messages.
In funny big fight with the matching the scene partner is to ensure that the two players can only send your game data to the other party, at the same time to prevent the other players intentionally or unintentionally interfere with the game, imagine when two players are game partner suddenly received its players intentionally sent for one of the game data when rendering embarrassing dislocation. The establishment condition of the front-end Websocket in funny big battle is that LocalStorage has relevant data, which is issued by the server after the user agrees with Sina authorization. The data contains a Token data, which is the user’s unique credential and permission credential for other HTTP requests.
/ / JavaScript structure and to establish a long connection URL: var socket = new WebSocket (" ws: / / demo. Leeys. Top/demo2 / socket? token=" + token);Copy the code
The server checks the validity of the Token during the Websocket handshake. After the verification is successful, the server can confirm that the long connection belongs to a user in the database. In this case, the data structure that stores the Websocket connection must be changed to Map and the USER’s UUID must be used as the key. When two partner players are playing, JS is only responsible for uploading data to the server. There is no need to specify who should be sent in the uploaded data. Only the server knows who should be sent to the data. This is different from cytophagocytosis, which is more like a broadcast mechanism, where any game data uploaded by a player to a server is broadcast to other players.
This is followed by the formulation of the data format for sending and receiving messages.
In a two-player war, you have to exchange data, but there is only one JS file, so you have to imagine in a JS file that you are the sender of the message and write the code to upload the data, and then suddenly imagine that you are the receiver of the message and write the code to receive the data, which is quite interesting. But you need a fixed message format and the same logic between sending and receiving messages.
Performance optimization:
According to the development sequence, I finished the performance optimization part first this time, which is very interesting and also the part I am interested in personally.
Message format: As we all know, the shorter the network message length, the better. Shorter messages mean smaller packets with lower latency and bandwidth savings, allowing for higher concurrency at the same bandwidth. When specifying a message object, send only the necessary data, with a key value of one or two short letters.
Messaging: maybe you will listen to the browser keydown event has occurred, is going to events trigger to send coordinates to the other players, you in the surveillance and the print funny men of X coordinate code, open a console to verify your ideas, you found that after the long press the direction key can continuously trigger events, X coordinates are also constantly change, it looks good. Unfortunately, the direction is right, but the approach is wrong. The network takes time, and you end up seeing teleportation in both browsers, and worse, a delay of nearly a second in changing direction, which is, of course, a slightly weird browser keystroke event. All in all, the results were terrible, not to mention the experience, the upload rate, even a 100 Megabyte server can not withstand such a load. To summarize, this method uses the trigger of a keystroke event to send the joker x-coordinate to Canvas rendering based on the received x-coordinate. It is set to glitch first, then drains bandwidth. The primary reason for the former is that the x-coordinates are not rendered enough times, so that 1/24 of a second of human visual pause cannot fill the huge gap of two shifts.
Internet communication time is like the laws of physics, but programmers invent magic.
The final purpose is to users “feel” the fluid, magic is “cheat”, trick users into the user feel very smooth, in the industry term is “interpolation”, the principle is simple, is a virtual rendering the other players two coordinate difference, when both sides are virtual rendering when there will be a bliss illusion of each other smoothly. My method is that the sender sends the data with the direction of movement, and the receiver assumes that the other party will move in this direction when receiving the data, and updates the X coordinate according to the data packet to prevent excessive deviation. So the whole movement is very smooth. But it still can’t avoid the keyboard long triggered by a large number of events resulting in a large number of data packets sent, imagine when one of the players according to D sports right, the other party after receiving the first data packet has been assuming you are next to the right movement, so the next key data completely there is no need to send to each other, only need you to lift the button to inform the other party, I have to stop, Don’t keep pretending. After optimization, the number of packets sent during the game has been greatly reduced, normally only a few packets per second at most, but the experience is very smooth, I can’t think of a more perfect scheme.
There are still drawbacks. If we use triggered button events to synchronize the position of the ball, then when the players are not moving or the button frequency is low, the data exchange frequency is very low, and the ball will be greatly inconsistent due to collisions or other reasons. I used a compromise — creating a consistencyTimer to send packets to each other every 150 milliseconds to correct the ball and brick.
Consistency:
Finally, there is the question of consistency.
What is consistency? The time spent on network transmission is inevitable, so there must be inconsistencies between the two sides of the game at the same time, especially in high-sensitivity games like shooting. Maybe on your side it shows a hit and on the other side it shows a successful dodge, but how should you judge this situation? The way to deal with this is to allow inconsistencies in the results on both ends. For example, you can see bleeding on the other side, but the other side can see it successfully. Then both sides have a good time, but the final result is judged by the server. Corresponding scene is in the funny big battle, the player A and player B each other partner, players can not pick up the ball, A see the player B player B sees the ball has been caught, this happens because of the ball and players position appeared inconsistent situation on both sides, this is anyone can’t avoid, so at this time the ball should be landing or rebound? My approach is slightly rough, consider to do server to judge the development level of difficulty with square, I simply put the game completely transfer control to the main party invited (invite party) first, the start of the master invited party control the ball, the ball of the XY coordinates and direction, the ball fall to the ground and the collision detection, almost all of the code is run on the main square, so the action of the invited party is? The only function of the invited party is as a foil! The invitee’s job in the code is to post their position and direction of movement, and to render the data sent by the host. Taking control away from one of the parties is the only way to do it without server judgment.
That’s the end of this summary.
Finally, a light topic, including my understanding of games.
Without a partner during the refactoring, I was limited in the number of interesting things I could think of by myself, and if I cut out the funny elements, I felt the game would be more interesting. Using funny elements doesn’t mean I’m a stickler, I haven’t been for years. As for the intent, it’s probably to cater to the current culture of self-deprecating memes on the Internet, but I’m happy to have a lot of people playing, at least without having to write a test to see how much the server can tolerate.
From small to large, I have no talent for the game and the players, has been in the game the players in a suffering to live every day in the hot water, as a child with a few games, most in summer and winter vacations, but one to school I will be a strong man DuanWan masculinity uninstall the game back to the great socialist learning path. Because was slow a game at home to over ten hours, and when I was a child I temper will be very urgent to wait, game unloading at first few weeks, whenever night very lonely demons always hits, but whether it is worth every time I was awake for a one’s fingers itch to pay the cost of damaged more than ten hours, so uninstall the game method is very effective for me. I haven’t played a lot of games since high school, except Kingdom Rush by Uruguayan IRONHIDE, which only comes out once every few years. I would play it for a week in my spare time and then devote myself to studying socialism. Compared to those high school students who played league of Legends in Internet cafes at noon, this is probably my more weird place. Although I have no talent for games, and I’m not a big fan of them, I’ve always believed that games are the ultimate product of human civilization. From weiqi in the Spring and Autumn period to Xiangqi and cuju later, it has to be said that the birth of each kind of game spread so far is an eruption of human wisdom volcano. With the advent of video games, the creation of games became more diverse and accessible to all programmers. Does this make games cheap to make? Not at all. There’s an incredibly complex logic hidden in every pretty little game you see. If you ask me, Game is the hardest product to develop in Code Word, and Game Developer will always stand for Geek. Because of this, I will wait even if the development cycle of tin Sheet company changes from two years to three years or even five years.
July 11th is fast approaching, in honor of the greatest Game Developer in the world, Satoru Iwata.