Inspired by the recent popularity of trivial games, developer iwae has developed a 3D version of the hit match-3 game in Cocos Creator in 24 hours and built a map editor. The source code and video tutorial (Chinese) are at the end of this article.
The simple yet fun game of triple elimination has always been one of the most popular genres of casual games, with a loyal following of players across all ages. What else can you do with triple elimination? This time, we will make a 3D version of the classic triple elimination game (with a map editor) with some variations. The accompanying video tutorial is posted in Bilibili, so you can watch it with the source code if interested.
The game was planned to take 3*8=24 hours to develop, and the main idea is as follows.
Day 1: Thinking about scene serialization and deserialization, building the map editor, art style finalization, and design.
Day 2: Game ray detection, core algorithm, loading, and settlement process.
Day 3: UI Build, Debug, Go Live Release!
Some of you may ask: why make another map editor instead of just saving the whole level as a prefab?
Let’s talk about serialization first.
- Serialization: This is the process of taking Cocos scene data and somehow storing the node information and component information in the scene as a Scene or as a Prefab, which in layman’s terms, is the process of converting a node’s data structure or object into a JSON data stream.
- Deserialization: The process of reducing the Scene or Prefab file in the disk file into nodes and components, that is, lowering the JSON data stream generated in the serialization process into the scene.
Here is a small scene using the engine and map editor, respectively, and compare the differences.
First, compare the JSON file of Prefab generated by the engine, the whole size is more than 10KB, and the engine needs to know the dependencies (UUID) and all the node information in the node (this is necessary to ensure the integrity and scalability of the functionality), so the whole JSON file, the information is complete, while having good compatibility and scalability.
The reduced size of the JSON also reduces the IO overhead when loading, streamlines the data structure, and makes parsing and loading faster. At only 120 bytes in size, the size savings is nearly 98% or more.
But that doesn’t mean it would be better to use custom editor serialization for all scenes within the game. Suppose you make editors for complex UI scenes. In that case, the development time is huge, and you can’t do it with the same good compatibility, scalability, and iterability as engine prefabs.
For loading, it is recommended to use Assetbundle for local or remote loading of the engine’s default prefabs. If you update the prefabs, you must repackage the bundle for replacement. While using custom editor + JSON format, you can store the level information on the server for real-time loading and updating.
Using the engine’s default prefabricated bodies, deserialization requires both editor and gameplay runtimes to be taken into account. For specific projects or mega-scenarios, using a custom editor + Json has three advantages when deserializing.
- Speed: less content, faster parsing.
- Frame optimization: you can do frame loading and frame instantiation for data in JSON to reduce black screen time.
- Custom effects: you can customize the effects when instantiating, such as zoom in and out, position shift, etc., all can be achieved by tween.
Having understood why we need the map editor feature, let’s see how we are going to implement it.
Considering that there may be many custom prefabs and it is impossible to identify their names and locations, the loaddir type in Assetbundle is used here, customizing the bundle name and the path to the folder to be loaded by property.
Load all the objects under the entire folder and instantiate a corresponding toggle to make it easier to do the switching.
It’s more flexible in terms of data storage. You just need to maintain a specific folder under a specific bundle.
“Meow Meow” may have gaps in the map design, so you can’t just use ray detection rayModel to get the location information of the squares. The layer method is used here, so you can use the number keys to switch layers or press the tab button to move up the layers and detect the grid on each layer (the grid will also switch when the layer switches).
Since the grid needs to be set up, you can change the information of the grid by customizing the length, width, and grid size with the information and setting the Scale of the grid by multiplying the three values (the default Quad length and width resolution is one world coordinate).
Also tilingoffset is set for the shader of the grid.
The shader has a wider grid width for every 5 cells and a reduced color for the rest of the grid, with a transparency of 93.
Here the data is stored via a 3-level array, mainly for ease of instantiation, without using Map for queries. The points of interaction between the ray and the grid are converted into the nearest grid points by Math.round operations and compared with the data information in the gridmap, which can be populated.
When destroying objects and adding new ones, the operations, object names, and node information are recorded via arrays, making it easy to do restores.
For data storage, the previously stored information is calendared first to facilitate storing the highest and widest information.
Then the array information is converted to a string and saved through the browser.
In the editor environment, parse the JSON file into a UTF-8 string and then convert the JSON information for deserialization.
Cocos Creator 3.6 has optimized the game size. To further optimize the resource size, I eliminated the physics engine and used the ray function to detect 3D objects. I eliminated the base model that came with the engine and used a homemade Quad.
The overall size of the game is around 3.4M, including 1.7M first pack + 1.7M bundles, which can be kept under 3M if the BGM is removed.
Instancing and batching, the game uses a large number of 3D bricks within the game, each with the same Mesh + different background images + different Icon images.
To further optimize performance, diffuse lighting is used overall, controlling the UV changes of the background and Icon images through a vec2 that is passed through fixed-point data to ensure that the instancing batch is not interrupted.
The ray detection only detects the click ID of the tile and multi-touch once at the beginning and once at the end of the click so that only the same tiles are selected. The selected color is also passed in via fixed-point data, ensuring that instancing does not interrupt the batch.
Rays, ray rules, and commonly used vectors are stored with const constants to avoid the depletion in move detection of new builds.
The entire scene is divided into three layers, and the rendering order is determined by setting the priority of the cameras.
- Red Camera0 is responsible for rendering the 2D background behind it, avoiding click events at this layer.
- Blue Camera responsible for 3D object rendering in the middle layer.
- The white camera is responsible for all UI and final rendering.
Basic Source Code Download - Cocos Store
Pro version (with level editor) source code - Cocos Store