Hi everyone! So, in this tutorial, you'll learn how to make minecraft in python! So, go to the original, and download all the files except for the code file. If you do, all my hard work is a waste and you don't learn anything! So please, don't download the code file! Go to command prompt or windows powershell and type
pip install ursina. This won't work in Replit so open Visual Studio Code. If you don't have it, download it here. So, open the folder in Visual Studio Code (I hope you downloaded the files into a folder called assets) and create a new python file called
Minecraft.py. Let's start with the imports.
from ursina import * from ursina.prefabs.first_person_controller import FirstPersonController
Leave a line and type:
app = Ursina() grass_texture = load_texture('assets/grass_block.png') stone_texture = load_texture('assets/stone_block.png') brick_texture = load_texture('assets/brick_block.png') dirt_texture = load_texture('assets/dirt_block.png') sky_texture = load_texture('assets/skybox.png') arm_texture = load_texture('assets/arm_texture.png') punch_sound = Audio('assets/punch_sound',loop = False, autoplay = False) block_pick = 1
block_pick variable shows which block the player is using. 1 is ground, 2 is stone, etc. Everything else loads the sprite sheet textures into the game. The
punch_sound is the punching audio. So, leave a blank line and in the next two lines, type this:
window.fps_counter.enabled = True window.exit_button.visible = True
You can also set
window.fps_counter.enabled = True to
window.fps_counter.enabled = False , but keeping it as
window.fps_counter.enabled = True makes it easier to understand how FPS works. Leave a line and in the next line, add this definition:
def update(): global block_pick if held_keys['left mouse'] or held_keys['right mouse']: hand.active() else: hand.passive() if held_keys['1']: block_pick = 1 if held_keys['2']: block_pick = 2 if held_keys['3']: block_pick = 3 if held_keys['4']: block_pick = 4
This sets the block the player is using based on the numbers 1, 2, 3, and 4. Now, a class with definitions:
class Voxel(Button): def __init__(self, position = (0,0,0), texture = grass_texture): super().__init__( parent = scene, position = position, model = 'assets/block', origin_y = 0.5, texture = texture, color = color.color(0,0,random.uniform(0.9,1)), scale = 0.5) def input(self,key): if self.hovered: if key == 'left mouse down': punch_sound.play() if block_pick == 1: voxel = Voxel(position = self.position + mouse.normal, texture = grass_texture) if block_pick == 2: voxel = Voxel(position = self.position + mouse.normal, texture = stone_texture) if block_pick == 3: voxel = Voxel(position = self.position + mouse.normal, texture = brick_texture) if block_pick == 4: voxel = Voxel(position = self.position + mouse.normal, texture = dirt_texture) if key == 'right mouse down': punch_sound.play() destroy(self)
This spawns and deletes the blocks based on which key is pressed, and which block type it is. Now leave a line for the sky class:
class Sky(Entity): def __init__(self): super().__init__( parent = scene, model = 'sphere', texture = sky_texture, scale = 150, double_sided = True)
So basically, this is the sphere in which the player is concealed in. Later, when we add the ground and you fall off, you'll see what I mean. So, now, leave a line and add the class for the player's hand:
class Hand(Entity): def __init__(self): super().__init__( parent = camera.ui, model = 'assets/arm', texture = arm_texture, scale = 0.2, rotation = Vec3(150,-10,0), position = Vec2(0.4,-0.6)) def active(self): self.position = Vec2(0.3,-0.5) def passive(self): self.position = Vec2(0.4,-0.6)
This cuts the arm's sprite sheet(well, sort of) and pastes it onto the arm 3D object and checks whether it's active or not. Almost done! Now, let's add the ground.
for z in range(20): for x in range(20): voxel = Voxel(position = (x,0,z))
This spawns a terrain with the length of 20 and breadth of 20 blocks. You can make it bigger, but it then it becomes a lot slower. And, to finish it off:
player = FirstPersonController() sky = Sky() hand = Hand() app.run()
BANG! There you go, a fully functioning Minecraft game!
How FPS works
So, remember when I told you about FPS earlier? Now, let me explain that. Here, Visual Studio Code is actually creating and deleting many windows at once! If you set that line to
window.fps_counter.enabled = True, look at the counter in the top right corner. You'll see that the numbers keep changing. That's how many frames Visual Studio Code creates and deletes per second. So, depending on that, the game is slower or faster.
Notes and credits
Thanks for reading this tutorial everyone! I hope you go away with better understanding of python and not just faster typing skills 😁. Thanks to @amasad for the tutorial on how to use Markdown. Thanks and bye!