Build a "Minecraft" with Cocos Creator! On-line WeChat

In recent years, sandbox construction games represented by Minecraft have become popular all over the world. In this sandbox world with a high degree of freedom, players can create their own world as they wish, and realize unconstrained creativity and ideas.

Hello everyone, I am Dong Mi! My game has been launched on WeChat. Thank you Brother Xiaoheng for the invitation. Here I will share my technology with you.

660d6ef360a4a03e45c5d7660a01ee43.jpeg

Last year, a version of "Minecraft" was reproduced in Cocos Creator 3.6.2. The main functions implemented at the beginning include: generating terrain; creating and destroying blocks; character movement, collision, gravity and simple animation; terrain extension; shortcut item bar wait. At present, the main gameplay functions of the game have been completed, and the WeChat mini-game Pixel Space 3D has been launched.

b37cba1bb0a42a9dd3352b923a821661.gif

025a1bc62933d4b13e6f21ecaf58fdba.gif

achieve effect

generate terrain

basic concept

  • Block: The smallest terrain unit with a size of 1X1X1.

  • Face: The elements that make up a block. A block can have up to 6 faces, and at least one can not have one.

  • Block: The size is 16X16X100. Consists of blocks. Arranged in each quadrant in turn.

random terrain

The terrain is randomly generated using a 2D Perlin noise function. Enter the x and z coordinates, get the y coordinate as the ground height, and create fill blocks from the set minimum height to the ground height. At present, simply set less than 0 as water, equal to 0 as sand, and the rest as dirt and grass. The bottom layer is paved with stones, and the middle is filled with soil.

53ea2ac334837182d5a1ecd57882797c.jpeg

random cave

Cave randomization uses 3D Perlin noise. Input the x, y, z coordinates, if it exceeds the set threshold, and it is below the ground surface and above the bottom layer, it will be judged as an air block. If it is an air block, there is no need to fill it with dirt blocks. This way we have basic caves (caves without mines...).

ba8e1b052c74909b08b0618af4375104.jpeg

b3839d07ffc9c84566fed37e8d30b12d.jpeg

random weeds and trees

Pure random for random weeds and trees. After the 2-dimensional Perlin noise is processed for each coordinate, the random judgment of weeds and trees is performed. Or set a threshold, if it exceeds, it will be judged as random weeds or trees (a tree is a fixed shape composed of many blocks).

b55854145f736ef2c232a3a8090d003d.png

Terrain mesh generation

The above contents are generated virtual objects. For the block rendered in the scene, I tried two methods to achieve it.

1. The system default block +instancing.

Use the setInstancedAttribute function to distinguish different blocks. The implementation effect of this method is actually quite good, but the disadvantage is that there are many examples and surfaces.

2. Dynamic grid is also the current practice.

This should be a new feature of v3.6, just try it out.

Create a dynamic mesh for each block. Since the update has not been processed yet, every time a block is added or deleted, the grid data of the entire block is rebuilt, so every time the nearby blocks are refreshed, there will be a little lag.

Face optimization is possible with Dynamic Mesh, creating only faces with no adjacency. However, surface optimization also requires traversing all blocks, which has not yet reached the optimal performance, and will continue to optimize in the future.


In addition, the UV value of each face of each block is also configured here to display different textures.

*A performance optimization: There are many squares, each square is a class, and the vec3 class is not used in the class, but numbers are used to represent the coordinates, which will take up much less memory.

Block creation and destruction

If the default block is used, creation and destruction are very simple and rude. But after switching to the dynamic grid, data reconstruction is required for each addition and deletion, and the data of the entire dynamic grid is reconstructed based on virtual data.

selection of squares

Here, the octree is simply used to manage nearby blocks, and the ray AABB intersection detection is used to determine which block the mouse is focusing on.

Then you need to know which face to focus on. In the beginning, 6 AABBs were used to judge. Later, it was found that the built-in detection function had already calculated the distance to the candidate surface. After copying it, the one with the smallest distance was the current one.

e316a999fce9e9956a03f5aad86d83c6.png

check box

Tried 4 methods before and after checking the box.

1. Geometry rendering using the camera.

bebdd807af475f4b460c0c97e908793c.png

The disadvantage of this method is that it cannot be completely occluded, and the occluded edges will be displayed semi-transparently.

2. Use shaders.

a000f18a3825e2e9c8ff8f83f13e4392.jpeg

Determine whether the UV is in the edge range, and if so, display the border color. The disadvantage of this method is that the border is relatively thick when viewed from a close distance, and thinner when viewed from a distance, and the effect is not very beautiful.

3. Use cube's Primitive line stroke.

bb7d586bf19788b3a2daee09023a9add.png

Because the default cube vertex order is lower left, lower right, upper left, upper right, so if you use line_list or loop, you cannot form a complete box.

4. Static grid is also the current practice.

With this scheme, you can set the order of vertices according to your own ideas, and change it to lower left, lower right, upper right, and upper left. Because I think that in "Minecraft", it is better to frame one block at a time, rather than only frame the focused surface, so in the end I chose to create a border with only 4 vertices. Using the line rendering mode can also meet the display requirements for the thickness of the border.

block texture

2f7d3167821328b6f580345be87e83d7.png

Originally, I wanted to find the texture map of "Minecraft" directly, but I never saw a very suitable one. So I was so cruel, I just started with PS. Similar textures can be easily generated using PS pixelation. Put all the textures in a 512 picture, which can be used together.

destroying particles

When the block is broken, play a particle animation in its position.

Here we use mesh particles, the cube that comes with the engine. Set to the gravity mode, use the curve to control the gravity to be small and then large, so that the generated particles stay for a while before falling.

Then customize the particle material, and set the offset of the material based on the properties of the currently destroyed block. The texture uses the same texture as the other blocks.

1e6fa407ad39949d68edf05bb9b453bc.png

character movement, collision,

Gravity and Simple Animations

This part took the longest time, and the effect still has a lot of room for optimization.

character movement

Press the direction key to record the direction of movement, and release it to reset the direction. Move based on the direction of movement in update.

The translate method of node, the second parameter passes 0 to the local coordinate system, and passes 1 to the world coordinate system. I am using the world coordinate system and need to rotate the displacement vector along the y axis.

character collision

Use octree to detect nearby blocks, and then use circle and polygon intersection to detect collision. If it collides, move along the opposite direction of the moving vector to create a blocking effect.

character gravity

Use the physical formula vt+0.5vtt to perform the vertical displacement of the character. Then use the collision principle to detect whether there is a collision. If there is a collision, set the acceleration of gravity to 0 and the speed to 0 until there is no collision, and the acceleration is restored.

Because the horizontal collision is corrected first, after the gravity displacement is performed, if there is a collision, it must be embedded in the soil and can be corrected.

When jumping, set the speed to a positive value to achieve jumping.

The current effect only satisfies the basic displacement, collision and gravity, but in terms of the feeling of continuous jumping and the intensity of collision, etc., follow-up optimization is still needed.

simple animation

When the character is not moving, there will be breathing, and the hands will move up and down; when running, there will be camera shaking; when deleting blocks and adding blocks, there will be hand movements. The implementation of these animations is relatively simple.

terrain extension

Because Perlin noise is used, as long as you have the coordinates of the block, you can randomly generate natural and continuous terrain.

This part is where the performance is most tight. As long as other blocks are judged, it will search for 25 nearby blocks, then create a new block and replace the grid of the old block with the new block.

And when it comes to a new block, a new octree needs to be created, which is very stuck. The original plan was to build an octree for the 25 nearby blocks based on the central block, so every time a new block is reached, there will be a lot of waste of repeated construction. Now limit the construction of the octree to each block. Before querying, first filter the block, and then query the octree of the block, which greatly improves the performance.

Quick Items Bar

This is the part that belongs to the UI and is not difficult.

Listen for keyboard events and then toggle the state of the cell. When needed, call the interface of pushing items and using items to update the state. In addition, there is linkage with the state of the hand. When switching cells, if there are items in the cell, the hand needs to be replaced with the item model.

The difficulty lies in drawing the item ICON, currently only 3 squares have ICON.

epilogue

The core solutions used in this project include: octree query for scene management, ray detection for collision and interaction, Berlin function for random terrain, dynamic grid for terrain display, etc. In the future, I will optimize the performance of the scene and add a series of content such as resources, NPCs, archives, and redstones.

I will update the progress of the project in the forum, welcome everyone to exchange and discuss:

https://forum.cocos.org/t/topic/143799

I'm planning to share the project to the Cocos Store, so stay tuned!

If you are interested in Cocos game development, technology, and monetization, please add Xiaoheng WeChat: z6346289.

Wonderful past

Guess you like

Origin blog.csdn.net/6346289/article/details/130299373