Part of pictures, articles, images on this page are copyrighted by Mojang AB.
This is a project to reproduce the world-famous sandbox game "Minecraft" in the programming language "Python".
Next article: [# 2] Make Minecraft with Python. ~ Model drawing and player implementation ~
"Minecraft" was the first time I came into contact with programming.
It was over 4 years ago. I was interested in so-called remodeled content called "MOD" in Minecraft, and entered the world of programming saying "I want to make it myself!". With a total play time of over tens of thousands of hours, it is one of many memorable games.
Since I was in the lower grades of elementary school, I have been doing some creative activities, such as creating a website. When you actually program a "thing" using a programming language and it actually works, the impression is tremendous.
Also, my way of thinking about "programming", how to assemble it, and the knowledge to realize it. It was a perfect match for all.
With that in mind, now that four years have passed, let's actually reproduce "Minecraft" itself instead of ** "MOD"! ** ** I stood up.
However, reproducing a game of that scale is not easy.
Nowadays, they are called ** game engines ** such as "Unity" and "Unreal Engine". It's an era where you can easily create high-quality games without any coding.
Even coding is visualized with what is called a ** blueprint ** and assembled with a GUI. It is possible to say that. This is amazing.
However, this project does not use such a game engine. ** Make it "from scratch" in the true sense. ** **
In actual production, you must first know the enemy.
If the so-called "drawing system" library called the computer graphics library is famous There are "DirectX" and "OpenGL".
This is the main subject. How does Minecraft draw in Java? ** Minecraft uses one of the game libraries in Java called "LWJGL (Lightweight Java Game Library)". ** ** It's like OpenGL's Wrapper.
Is there such a library in Python? It doesn't have to be the worst. ** If you don't have it, you can make it. If you run out, just add it. ** **
Integrated development environment ["Eclipse"](https://ja.wikipedia.org/wiki/Eclipse_(%E7%B5%B1%E5%90%88%E9%96%8B%E7%99%BA%E7% Let's touch LWJGL a little using 92% B0% E5% A2% 83)).
Download from Official Site.
Nostalgic. This screen.
For the time being, my eyes get tired, so I chose a dark theme.
Window
▶Preferences
▶Appearance
Make a project appropriately.
Create a class appropriately.
main.java
public class main
{
//constructor
public main() {}
public static void main(String[] args)
{
System.out.println("Hello LWJGL!");
}
}
Operation check is completed for the time being.
To use LWJGL, you need "JDK (Java Development Kit)".
Reference article: How to install JDK on Windows
You can pass it with javac -version
.
Install Maven
to build LWJGL environment.
Reference article: How to install Maven on Windows
OK if you pass with mvn -v
.
This time I installed Maven 3
.
next,
mvn archetype:generate -DgroupId=test -DartifactId=test
Create a project appropriately with
This time, I created it in the working space of ʻEclipse`.
Reference article: Memo of Maven3
Choose org.apache.maven.archetypes:maven-archetype-quickstart version:
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
7: 1.3
8: 1.4
Choose a number: 8: 8
[INFO] Using property: groupId = test
[INFO] Using property: artifactId = test
Define value for property 'version' 1.0-SNAPSHOT: : 1.0-SNAPSHOT
[INFO] Using property: package = test
Confirm properties configuration:
groupId: test
artifactId: test
version: 1.0-SNAPSHOT
package: test
Y: : Y
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 06:21 min
[INFO] Finished at: 2020-01-21T08:58:05+09:00
[INFO] ------------------------------------------------------------------------
Reference: Try Hello world with LWJGL (Environment construction)
next,
Link LWJGL to pom.xml
in the created project
mvn nativedependencies:copy
Download the dynamic link library at
mvn clean eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true
Allows Eclipse to load the project. Open Eclipse and import from ʻImport existing projects`.
The library is being built.
The source code is as follows.
Main.java
package test;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
public class Main
{
public static final int screen_width = 800;
public static final int screen_height = 500;
public static void Initialize()
{
try
{
Display.setDisplayMode(new DisplayMode(screen_width, screen_height));
Display.setTitle("Hello LWJGL!");
Display.create();
}
catch(LWJGLException e)
{
e.printStackTrace();
return;
}
try
{
glOrtho(0, screen_width, 0, screen_height, 0, depth);
glMatrixMode(GL_MODELVIEW);
while (!Display.isCloseRequested())
{
glClear(GL_COLOR_BUFFER_BIT);
Render();
Display.update();
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
Display.destroy();
}
}
public static void Render()
{
glBegin(GL_QUADS);
glEnd();
}
public static void main(String[] args)
{
Initialize();
}
}
Nothing was drawn for the time being, but it went well.
Draw a red line from the upper right to the lower right of the screen.
Main.java
public static void Render()
{
glBegin(GL_LINES);
glColor3f(1.0f, 0f, 0f);
glVertex2f(0, 0);
glVertex2f(screen_width, screen_height);
glEnd();
}
You can see that the line is drawn.
By now, you know that Minecraft uses OpenGL. It seems that OpenGL can be used in Python as well.
Use an IDE called "PyCharm" (https://www.jetbrains.com/ja-jp/pycharm/).
File
▶ Setting
▶ Project: <project name>
▶ Project Interpreter
Add the required libraries.
The image loading Pillow
on the reference site seems to be out of Python 3.8 support, so I could not install it.
Create and run main.py
.
The source code is as follows.
This Python squishy notation seems to take some time to get used to. </ font>
main.py
from OpenGL.GL import *
import glfw
def main():
if not glfw.init():
return
window = glfw.create_window(640, 480, 'Hello World', None, None)
if not window:
glfw.terminate()
print('Failed to create window')
return
glfw.make_context_current(window)
print('Vendor :', glGetString(GL_VENDOR))
print('GPU :', glGetString(GL_RENDERER))
print('OpenGL version :', glGetString(GL_VERSION))
glfw.destroy_window(window)
glfw.terminate()
if __name__ == "__main__":
main()
Output result:
Vendor : b'NVIDIA Corporation'
GPU : b'GeForce GTX 1080/PCIe/SSE2'
OpenGL version : b'4.6.0 NVIDIA 441.08'
Process finished with exit code 0
It's going well.
The source code is as follows.
The argument for glClearColor
is RGBA
.
Specify each with float
.
(r / 255.f, g / 255.f, b / 255.f, a / 255.f)
main.py
glfw.make_context_current(window)
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 0)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
while not glfw.window_should_close(window):
glClearColor(0, 1, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glfw.swap_buffers(window)
glfw.poll_events()
▼ It is drawn like this. Python is amazing. Is it so easy to do? If you were doing it with C # .NET WinForm, you would have seen hell by this time.
If you have only one front buffer, it will flicker every time you update it, and problems will occur.
Therefore, we prepare what is called a back buffer and update it to the back buffer.
By sending the back buffer to the front buffer with SwapBuffer ()
, it will be displayed on the screen.
So far, I actually touched it while considering how it is drawn with OpenGL.
Here is the main issue. When programming a game, programming it in a straightforward manner will hinder the maintainability and maintainability of the program. Therefore, you can make a rough outline, so actually create a blueprint for the program.
In Minecraft, one of the means of managing World is called ** "chunk" **.
This divides the vast world into chunks of 16 (x) × 16 (z) × 256 (y)
and reads / draws only the required range to minimize the load.
Normally, in the world of 3D games, the concept of 3D vectors recognizes that Z
is defined as height, but in Minecraft, Y
is height.
I don't know why. Mystery is. ..
▼ Z
in 3D of the image below is defined as Y
in Minecraft.
Image Source: 8th Basic Mathematics I
Next, about blocks. In Minecraft, there are two types of blocks internally.
--A normal block that has no function, such as a "soil" block, is Block
.
-TileEntity
is a special block with GUI and functions such as "Kamado" block.
It is defined as.
The entity of the block with the function such as "Kamado" is Block
, and it has the object of TileEntity
.
This is also one of the world management of load reduction and resource saving.
Block
Block
inherits the interface.
The interface also contains an instance of World
, which sends and receives events such as installed / destroyed ... etc. from the block to World
.
For example, it looks like this.
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player)
TileEntity
Since the entity of TileEntity
is Block
, it is necessary to link Block
and TileEntity
.
Therefore, Minecraft creates an object of TileEntity
from the interface function of a specific block like this.
MyTileEntityClass
inherits the interface TileEntity
.
public TileEntity createNewTileEntity(World world)
{
return new MyTileEntityClass();
}
Based on the information so far, I will lightly assemble the blueprint. Since the scale is too large, we do not think about any details for the time being, and design based on what we know at present and what we want to implement.
▼ It looks like this. Events such as exchanging information with the world are defined in the interface.
Since I have not actually seen the source code of Minecraft, I was able to make a rough design based on the experience and knowledge cultivated in MOD development so far, but I have to think about the details and implement it myself. .. It's going to be a tough battle.
Especially, the point of concern is drawing.
How do you actually render the drawing from World
? When.
Especially since it is a 3D space, it seems to be complicated unlike a 2D space.
Loading textures ..etc There are a lot of problems.
For the time being, is it the production of the menu screen?
Due to the large scale, I decided to divide the project into parts. Is the project name ... ** "PyCraft" ** okay? ** We are looking for someone to create a logo like that. Thank you. ** **
Next time, I will aim to create a menu screen and solve rendering problems.
Thank you for watching until the end.
Recommended Posts