HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Builder - A 2D Minecraft clone

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
minecraftclonebuilder

Problem

I was poking around on my Raspberry Pi that I hadn't turned on or used in a while, and I stumbled upon this Python script that I wrote ~1.5 years ago, and I was intrigued.

Essentially, it's a 2D Minecraft clone with no concept of survival. It does have a slightly, complex control scheme, so here's a list of buttons that can be used, and what they do:

  • a, d - Move left/right through the world.



  • LMB - Place a tile at the desired position.



  • RMB - Destroy a tile at the desired position.



  • SHIFT/SPACE - Change the currently selected tile.



  • q - Switch to the underground "realm".



  • e - Switch to the above ground "realm".



Even though I wrote this quite a while ago, and if I had written it now, it would have looked better, I'm still curious as to what all can be improved.

```
#!usr/bin/env python
# Basic 2d building game, Builder
import pygame
import random
import shutil
import time
import math
import sys
import os

debug_game_data = int(sys.argv[1])
current_version = "0.5.0"

WIDTH = 700
HEIGHT = 700

pygame.init()
pygame.display.set_caption("Builder {}".format(current_version))
screen = pygame.display.set_mode((WIDTH, HEIGHT))
FONT = pygame.font.SysFont("monospace.ttf", 13)
clock = pygame.time.Clock()

mouse_pos = pygame.mouse.get_pos
key_pressed = pygame.key.get_pressed

mouse_x = 0
mouse_y = 1

TILE_SIZE = 25
round_tile_size = lambda x: (
1+(x-1)/TILE_SIZE)*TILE_SIZE if x%TILE_SIZE>=10 else (
x/TILE_SIZE)*TILE_SIZE

# Dictionary of game textures
TEXTURES = {
"dirt": pygame.transform.scale(pygame.image.load("./images/gameDirtBlock.png"), (TILE_SIZE, TILE_SIZE)),
"grass": pygame.transform.scale(pygame.image.load("./images/gameGrassBlock.png"), (TILE_SIZE, TILE_SIZE)),
"stone": pygame.transform.scale(pygame.image.load("./images/gameStoneBlock.png"), (TILE_SIZE, TILE_SIZE)),
"sand": pygame.transform.scale(pygame.image.load("./images/gameSandBlock.png"), (TILE_SIZE, TILE_SIZE)),
"water": pygame.transform.scale(pygame.image.load("./

Solution

A few things that could be improved upon:

TEXTURES = {
    "dirt": pygame.transform.scale(pygame.image.load("./images/gameDirtBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "grass": pygame.transform.scale(pygame.image.load("./images/gameGrassBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "stone": pygame.transform.scale(pygame.image.load("./images/gameStoneBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "sand": pygame.transform.scale(pygame.image.load("./images/gameSandBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "water": pygame.transform.scale(pygame.image.load("./images/gameWaterBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "wood": pygame.transform.scale(pygame.image.load("./images/gameWoodBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "leaf": pygame.transform.scale(pygame.image.load("./images/gameLeafBlock.png"), (TILE_SIZE, TILE_SIZE)),
}


A few things here:

  • There's no need to wrap the actual texture title with gameBlock: ./images/.png is fine.



  • All the lines are basically the same except for the texture title, you could probably loop over this if you wanted, or move the pygame.transform.scale(pygame.image.load(), (TITLE_SIZE, TILE_SIZE)) into a function.



def render_background(self):
        if player_aboveground:
            screen.fill(self.SKY_COLOR)
        if player_underground:
            screen.fill(self.UNDERGROUND_SKY_COLOR)


Shouldn't if player_underground be elif? You can't be in both places at once.

self.START_X_LEFT = self.START_X_CENTER-500
    self.END_X_LEFT = self.START_X_CENTER

    # Start and end for right side
    self.START_X_RIGHT = self.END_X_CENTER
    self.END_X_RIGHT = self.END_X_CENTER+500

    # Start and end for far left side
    self.START_X_FAR_LEFT = self.START_X_LEFT-750
    self.END_X_FAR_LEFT = self.START_X_LEFT

    # Start and end for far right side
    self.START_X_FAR_RIGHT = self.END_X_RIGHT
    self.END_X_FAR_RIGHT = self.END_X_RIGHT+750


Where's the spacing in between self.* + val?

self.inventory = {
        0: [0, pygame.transform.scale(pygame.image.load("./images/gameDirtBlock.png"), (17, 17))],
        1: [0, pygame.transform.scale(pygame.image.load("./images/gameGrassBlock.png"), (17, 17))],
        2: [0, pygame.transform.scale(pygame.image.load("./images/gameStoneBlock.png"), (17, 17))],
        3: [0, pygame.transform.scale(pygame.image.load("./images/gameSandBlock.png"), (17, 17))],
        4: [0, pygame.transform.scale(pygame.image.load("./images/gameWaterBlock.png"), (17, 17))],
        5: [0, pygame.transform.scale(pygame.image.load("./images/gameWoodBlock.png"), (17, 17))],
        6: [0, pygame.transform.scale(pygame.image.load("./images/gameLeafBlock.png"), (17, 17))],
    }


Really?

  • You should cast expelliarmus on the magic number 17!



  • ArrayPositions are bad keys. In fact, useless.



  • I'm not familiar with pygame, but couldn't you just transform the TEXTURES instead?



for chunk_x in range(self.START_X_FAR_LEFT, self.END_X_FAR_LEFT, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_far_side()

    # Generate the left side
    for chunk_x in range(self.START_X_LEFT, self.END_X_LEFT, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_side()

    # Generate the center
    for chunk_x in range(self.START_X_CENTER, self.END_X_CENTER, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_center()

    # Generate the right side
    for chunk_x in range(self.START_X_RIGHT, self.END_X_RIGHT, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_side()

    # Generate the far right side
    for chunk_x in range(self.START_X_FAR_RIGHT, self.END_X_FAR_RIGHT, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_far_side()

    # Generate the underground portion
    for chunk_x in range(self.UNDER_START_X, self.UNDER_END_X, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_underground()


DRY this a bit.

def initalize_game():
    clock.tick(75)
    background = Background()
    generator = WorldGenerator()
    generator.generate_world()


Is there any reason to assign background and generator?

Background()
    WorldGenerator().generate_world()


Why do the comments in run_events have question marks on the end?

# Player aboveground?


Also in run_events:

# Player aboveground?
    if player_aboveground:
        self.chunk_loader.render_current_loaded_chunks_aboveground()

    # Player underground?
    if player_underground:
        self.chunk_loader.render_current_loaded_chunks_underground()

    # Move player aboveground?
    if player_aboveground:
        self.player.move_player_aboveground()

    # Move player underground?
    if player_underground:
        self.player.move_player_belowground()


Why are these seperate?

```
if player_aboveground:
self.chunk_loader.render_current_loaded_chunks_aboveground()
self.pla

Code Snippets

TEXTURES = {
    "dirt": pygame.transform.scale(pygame.image.load("./images/gameDirtBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "grass": pygame.transform.scale(pygame.image.load("./images/gameGrassBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "stone": pygame.transform.scale(pygame.image.load("./images/gameStoneBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "sand": pygame.transform.scale(pygame.image.load("./images/gameSandBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "water": pygame.transform.scale(pygame.image.load("./images/gameWaterBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "wood": pygame.transform.scale(pygame.image.load("./images/gameWoodBlock.png"), (TILE_SIZE, TILE_SIZE)),
    "leaf": pygame.transform.scale(pygame.image.load("./images/gameLeafBlock.png"), (TILE_SIZE, TILE_SIZE)),
}
def render_background(self):
        if player_aboveground:
            screen.fill(self.SKY_COLOR)
        if player_underground:
            screen.fill(self.UNDERGROUND_SKY_COLOR)
self.START_X_LEFT = self.START_X_CENTER-500
    self.END_X_LEFT = self.START_X_CENTER

    # Start and end for right side
    self.START_X_RIGHT = self.END_X_CENTER
    self.END_X_RIGHT = self.END_X_CENTER+500

    # Start and end for far left side
    self.START_X_FAR_LEFT = self.START_X_LEFT-750
    self.END_X_FAR_LEFT = self.START_X_LEFT

    # Start and end for far right side
    self.START_X_FAR_RIGHT = self.END_X_RIGHT
    self.END_X_FAR_RIGHT = self.END_X_RIGHT+750
self.inventory = {
        0: [0, pygame.transform.scale(pygame.image.load("./images/gameDirtBlock.png"), (17, 17))],
        1: [0, pygame.transform.scale(pygame.image.load("./images/gameGrassBlock.png"), (17, 17))],
        2: [0, pygame.transform.scale(pygame.image.load("./images/gameStoneBlock.png"), (17, 17))],
        3: [0, pygame.transform.scale(pygame.image.load("./images/gameSandBlock.png"), (17, 17))],
        4: [0, pygame.transform.scale(pygame.image.load("./images/gameWaterBlock.png"), (17, 17))],
        5: [0, pygame.transform.scale(pygame.image.load("./images/gameWoodBlock.png"), (17, 17))],
        6: [0, pygame.transform.scale(pygame.image.load("./images/gameLeafBlock.png"), (17, 17))],
    }
for chunk_x in range(self.START_X_FAR_LEFT, self.END_X_FAR_LEFT, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_far_side()

    # Generate the left side
    for chunk_x in range(self.START_X_LEFT, self.END_X_LEFT, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_side()

    # Generate the center
    for chunk_x in range(self.START_X_CENTER, self.END_X_CENTER, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_center()

    # Generate the right side
    for chunk_x in range(self.START_X_RIGHT, self.END_X_RIGHT, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_side()

    # Generate the far right side
    for chunk_x in range(self.START_X_FAR_RIGHT, self.END_X_FAR_RIGHT, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_far_side()

    # Generate the underground portion
    for chunk_x in range(self.UNDER_START_X, self.UNDER_END_X, TILE_SIZE):
        chunk = Chunk(chunk_x)
        chunk.add_new_chunk_data_underground()

Context

StackExchange Code Review Q#101627, answer score: 5

Revisions (0)

No revisions yet.