【51CTO.com Quick Translation】 Introduction Horizon is a well-known cross-platform scalable backend framework suitable for building cross-platform JavaScript-based mobile applications, especially those that require real-time capabilities. This framework was developed by programmers from the RethinkDB product, so it uses RethinkDB as the default database. If you are not familiar with RethinkDB, then you only need to know that it is an open source database that supports real-time functions (https://www.rethinkdb.com). The Horizon framework exposes a set of client APIs to allow you to interact with the underlying database. This means that you don't have to write any backend code. All you have to do is build a new server, run it, and Horizon will automatically manage the rest. With Horizon, you can easily synchronize data between real-time connected clients and servers. If you want to learn more about Horizon, please check out its FAQ page (http://horizon.io/faq/). In this tutorial, you will use Icon and Horizon to develop a Tic-Tac-Toe game. Therefore, the premise of reading this article is that you already know Icon and Horizon, so I am not going to explain the specific code related to Icon in the program. Of course, if you want some background knowledge about Icon, I suggest you check this website http://ionicframework.com/getting-started/. If you want to continue reading this article, please download the sample project source code of the article first (https://github.com/anchetaWern/ionic-horizon-tictactoe). The following figure shows a snapshot of the final result of this article's sample application. Install Horizon RethinkDB is used as the database for Horizon. Therefore, you need to install RethinkDB before installing Horizon. For detailed information about installing RethinkDB, you can find the answer from the URL https://www.rethinkdb.com/docs/install/. Once RethinkDB is installed, you can install Horizon using npm by executing the following command in your terminal: npm install -g horizon Horizon Server Development The Horizon server is used as the backend for the application. Whenever the application executes code, it communicates with the database. You can create a new Horizon server by executing the following command in your terminal: hz init tictactoe-server This command will create the RethinkDB database and provide the files used by Horizon. Once the server is created, you can run it by executing: hz serve --dev In the above command, you specify -dev as an option. This means that you want to run a development server. The following options are set in the development server: --secure no: This means that websockets and files will not be served over an encrypted connection. --permissions no: Disables permission constraints. This means that any client can perform any operation they want in the database. Horizon's permission system is based on whitelists. This means that, by default, all users have no permission to do anything. You must explicitly specify which operations are allowed. --auto-create-collection yes: Automatically create a collection when it is first used. In Horizon, a collection is equivalent to a table in a relational database. Setting this option to true means that every time a client uses a new collection, it will be automatically created. --auto-create-index yes: Automatically create index on first use. --start-rethinkdb yes: Automatically start a new instance of RethinkDB in the current directory. --allow-unauthenticated yes: Allow unauthenticated users to perform database operations. --allow-anonymous yes: Allow anonymous users to perform database operations. --serve-static ./dist: Enables serving of static files. This is useful if you want to test interacting with the Horizon API in a browser. The Horizon server runs on port 8181 by default, so you can access the server by visiting http://localhost:8181. Note: The --dev option should never be used in a production environment, as it opens a large number of vulnerabilities that can be easily exploited by attackers. Building an Ionic App Now, we are fully prepared. Next, we will create an Ionic application framework with the following command: ionic start tictactoe blank Install Chance.js Next, you need to install chance.js, which is a JavaScript utility library for generating random data. In this application, we use it to generate a unique ID for the player. You can install chance.js through the bower tool using the following command: bower install chance Create index.html Now, open the file www/index.html and modify its content as follows:
Most of the code above comes from the boilerplate code generated by the Icon Blank Wizard template. Now, let's add a reference to the chance.js script:
The Horizon server will automatically provide the Horizon script service. The code is as follows:
[Note] If you want to deploy this content later, you must modify the URL. Next, the main application logic is located in the following script file:
Write the main program app.js The file app.js is where the code that initializes the application is run. Next, you need to open the file www/js/app.js and add the following content below the run function:
This will set up a route for the default application page. This route will specify the template to use for the page and the URL where it can be accessed. Develop the controller program HomeController.Js Now, we create a controller file HomeController.js in the path www/js/controllers and modify its code as follows:
Now, let's analyze the above code. First, the default state is set. Among them, the has_joined variable is used to determine whether the player has entered a room. Secondly, the ready variable is used to determine whether the user has connected to the Horizon server. When this variable value is false, the application interface cannot be displayed to the user.
The code to connect to the server is as follows:
As I mentioned earlier, the Horizon server uses port 8181 by default. That's why we use local:8181 as the port. If you are connecting to a remote server, this should correspond to the IP address or domain name assigned to the server. When a user connects to the server, the onReady event will be fired. It is at this point that we set ready to true so that we can show the UI portion of the application to the user.
Enter the room Whenever the user clicks the Join button, the join function will be executed:
Inside this function, connect to a collection called tictactoe. 【Note】Because we are in development mode; therefore, if the collection does not exist, the system will automatically create it for you.
Next, generate an ID and set it as the current user's ID:
Next, set the player username and default player score.
Note: Both variables are bound to the template; therefore, you can display and update them at any time. Next, we query the document with the condition that the room attribute is the current room and the type attribute is user. Do not confuse this query with the subscribe function, as we are not monitoring data changes here. Moreover, we use the fetch function here; this means that the operation is performed only when the user enters a room. The relevant code is as follows:
Once the result comes back, the number of users is checked. Of course, TicTacToe can only be played by two players, so if a user tries to join a room that already has two players, they will be alerted.
The else statement in the code above will continue the logic of accepting users, which determines the cards that will be assigned to users based on the current number of users. The first person to join the room gets the "X" card, while the second person gets the "O" card.
Once you select a card, store the new user in the collection and invert the has_joined switch to display the tic-tac-toe board.
Next, listen for changes in the collection. This time, instead of fetching, use a watch method. Specifically, the callback function is executed every time a new document is added or an existing document matching the query is updated (or deleted). When the callback function executes, it loops through all the results and sets the opponent's details - if the user ID of the document does not match the current user's ID. This is how we use it in this program to show the current user who their opponent is.
Next we subscribe to the move event, which fires every time a player places their card on the board, which causes the document to change. If this happens, we loop through all the moves and add the text to the corresponding cells. From now on, the code will use the word "block" to refer to each cell on the board. The text added corresponds to the card each user has played; in addition, the class name is replaced with "col done" in the code. Among them, col corresponds to the grid implementation class in Ionic programming, and done is a class used to indicate that a card has already been placed on a specific block. We use this method to check if the user can still place cards on the grid. After updating the chessboard UI, the player's score is updated by calling the updateScores function (this function will be added later).
Place Card Whenever the user clicks on a square on the board, the placePiece function is called, and the ID value of the corresponding square is provided as a parameter to this function. This allows us to manipulate the game squares as we like. In this program, this function is used to check whether a game square is of the done type. If the done flag is not set, a new move is created and the current room, square ID value and corresponding card are displayed.
Update player score To update the player's score, you need to build an array containing the possible winning combinations, like this:
In this code, [1, 4, 7] corresponds to the first row and [1, 2, 3] corresponds to the first column. The order does not matter as long as the corresponding numbers exist. The following graphic will help you understand this more intuitively. Next, you need to initialize the score of each individual card and loop through each possible combination. For each loop iteration, initialize the total number of cards that have been placed on the board. Then loop through each possible combination. Use the id to check if the corresponding grid already has a card. If so, get the actual card and add 1 to the total number of cards. After the loop is finished, check if the total number of cards is equal to 3. If the total number of cards is equal to 3, increase the score of the card until all possible combinations are iterated through. Once completed, update the score values of the current player and the opponent.
Create a main template file Now, create a template file home.html in the directory www/templates and add the following code:
Now, let's analyze the above code. First, a general wrapper is created, which will not be displayed until the user connects to the Horizon server:
The form code for joining a game room is as follows:
The relevant code for the design of the tic-tac-toe chess board is as follows:
The code corresponding to the player score part is as follows:
Writing style files The following is the style definition of the client application:
Run the application Now you can test the application in your browser by executing the following command from the application's root directory:
This will start the server and serve your local project and open a new tab in your default browser. If you want to test it with friends, you can publish the Horizon server to the internet using Ngrok with the following command:
This command will generate a URL that you can use as the host address when you connect to your Horizon server:
In addition, change the reference to the horizon.js file in the index.html file:
To create a mobile version of your app, you need to add a platform (e.g., Android) to your project. This assumes that you have the Android SDK installed on your computer.
Next, we generate the .apk file with the following command:
At this point, you can send this .apk file to your friends to play the game together. Of course, you can also play the game by yourself, it's all your business. summary In this tutorial, you have developed a very simple application; therefore, there are many aspects that can be improved appropriately to achieve better results. The following are some of the contents for your reference and improvement. Consider these as your skill homework. Develop a 4×4 or 5×5 version: The 3×3 version you have developed so far will almost always lead to a stalemate, especially if both players playing tic-tac-toe are experts. Scoring logic: You have to loop a lot to get the player's score. Maybe you can come up with a better solution. Beautify the game style: The current game style is very plain, in fact, it simulates the tic-tac-toe game suitable for playing on paper. Add animations: You could try adding a "slide down" animation to the board when a user joins a room, or a "pop up" animation when a player places a card on the board. You can use the animate.css file to implement these types of animations. Add SNS login support: Adding SNS functionality to such a simple application may be a bit much, but if you want to understand how authentication works in the Horizon framework, this is a good exercise. Using Horizon authentication, you can let users log in to their Facebook, Twitter, or Github accounts. Add a Play Again feature: You can try adding a "Play Again" button after the game is finished. When this button is pressed, the system will clear the leaderboard and scores so that the player can play again. Add real-time leaderboard feature: Add a competition leaderboard to show who won the game. [Translated by 51CTO. Please indicate the original translator and source as 51CTO.com when reprinting on partner sites] |
<<: New features of SpriteKit in iOS 10: Tile Maps (Part 1)
>>: WOT2016 Wang Qingyou: Listen to the Chief Architect Discussing Large APP Server Architecture
Many people think Osteoporosis is a problem only ...
This blog post is from 51CTO blogger jxw167. If y...
When we use WeChat, there are actually 3 function...
How to make 1000 yuan a day. Is there any way to ...
With the popularity of the Metaverse, related con...
How to log out of QQ? The answer was found some t...
When I was taking the elevator today, the Platinu...
The trend of new energy vehicles is irreversible!...
Some people may think You should turn off the gas...
Commander: Shut down the engine and switch to unc...
Why are information flow ads so popular among adv...
In the past few days, Ms. Liu cleaned her house a...
Author: Shi Xiangqi and Li Chuanfu On September 2...
As of early January 2020, the number of monthly a...