Skip to main content
added 34 characters in body
Source Link
class Vector(pygame.math.Vector2):
    def __hash__(self):
        return idint(self.x * 10 + self.y)

def handle_chunk_loader(self):
    chunks_needed = {Vector(i) for i in self.chunks_to_load()}
    loaded_chunks = {Vector(i) for i in self.loaded_chunks}
    self.load_chunks(chunks_needed - loaded_chunks)
    self.unload_chunks(loaded_chunks - chunks_needed)
import pygame
from bisect import bisect
from itertools import product

BLOCK_SIZE = 64
BLOCK_TEXTURE_NAMES = [
    "textures/void.png",
    "textures/air.png",
    "textures/grass_block.png",
    "textures/dirt.png",
    "textures/stone.png",
    "textures/sandstone.png",
    "textures/sand.png",
    "textures/bedrock.png",
    "textures/oak_log.png",
    "textures/oak_leaves.png",
    "textures/cobblestone.png",
]


def block_texture(texture):
    return pygame.transform.scale(
        pygame.image.load(texture), (BLOCK_SIZE, BLOCK_SIZE)
    ).convert_alpha()


def convert(pos, convert_value_x, convert_value_y):
    """Converts coordinate systems."""
    nx, rx = divmod(pos.x, convert_value_x)
    ny, ry = divmod(pos.y, convert_value_y)
    return ((nx, ny), (rx, ry))


class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (1, 3, 4, 0)

    def __init__(self, pos, size):
        self.size = size
        self.actual_size = size * BLOCK_SIZE
        self.block_textures = [
            block_texture(texture) for texture in BLOCK_TEXTURE_NAMES
        ]
        self.backround_texture = block_texture("textures/backround.png")
        self.pos = pos
        self.actual_pos = pos * BLOCK_SIZE
        self.surface = pygame.Surface((self.actual_size, self.actual_size))
        self.x_range = range(self.size)
        self.y_range = range(self.size)
        self.blocks = {}

    def update(self, block_pos, new_block=None):
        vector = pygame.Vector2(block_pos) * BLOCK_SIZE
        self.surface.blit(self.backround_texture, vector)
        self.blocks[block_pos] = block = new_block or self.blocks[block_pos]
        self.surface.blit(block, vector)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos)
                block = self.block_sizes[i]
            self.update((x, y), block)

    def set_blocks(self, blocks):
        self.blocks = blocks
        for x, y in product(self.x_range, self.y_range):
            self.update((x, y))

    def __str__(self):
        return str([self.blocks[(x, y)] for x in self.x_range for y in self.y_range])


class Vector(pygame.math.Vector2):
    def __hash__(self):
        return idint(self.x * 10 + self.y)

class World:
    def __init__(self, loader_pos, loader_distance, chunk_size):
        self.chunk_size = chunk_size
        self.actual_chunk_size = chunk_size * BLOCK_SIZE
        self.loaded_chunks = {}
        self.loader_pos = loader_pos
        self.set_loader_chunk_pos(loader_pos)
        self.loader_distance = loader_distance
        self.rendered = pygame.Surface((1, 1)).convert_alpha()
        self.innactive_block_data = {}

    def handle_chunk_loader(self):
        chunks_needed = {Vector(i) for i in self.chunks_to_load()}
        loaded_chunks = {Vector(i) for i in self.loaded_chunks}
        self.load_chunks(chunks_needed - loaded_chunks)
        self.unload_chunks(loaded_chunks - chunks_needed)

    def get_data(self, chunk_pos):
        return self.innactive_block_data.get(chunk_pos, False)

    def load_chunks(self, chunks_pos):
        for pos in chunks_pos:
            chunk_pos = (pos.x, pos.y)
            self.loaded_chunks[chunk_pos] = Chunk(pos, self.chunk_size)
            (
                self.loaded_chunks[chunk_pos].set_blocks(block_data)
                if (block_data := self.get_data(chunk_pos))
                else self.loaded_chunks[chunk_pos].generate()
            )

    def unload_chunks(self, chunks_pos):
        for chunk_pos in chunks_pos:
            chunk = self.loaded_chunks.pop(chunk_pos)
            if self.get_data(chunk_pos) != chunk.blocks:
                self.innactive_block_data[chunk_pos] = chunk.blocks

    def get_block(self, pos):
        chunk_pos, block_pos = convert(pos, self.chunk_size, self.chunk_size)
        try:
            return self.loaded_chunks[chunk_pos].blocks[block_pos]
        except IndexError:
            return False

    def get_range(self, axis):
        n = int(getattr(self.loader_chunk_pos, axis))
        return range(
            n - self.loader_distance,
            n + self.loader_distance + 1,
        )

    def chunks_to_load(self):
        return [
            pygame.Vector2(chunk_pos_x * self.chunk_size, chunk_pos_y * self.chunk_size)
            for chunk_pos_x, chunk_pos_y in product(
                self.get_range("x"), self.get_range("y")
            )
        ]

    def set_loader_chunk_pos(self, pos):
        self.loader_chunk_pos = pygame.Vector2(
            convert(pos, self.actual_chunk_size, self.actual_chunk_size)[0]
        )

    def change_pos(self, pos):
        self.loader_pos += pos
        self.set_loader_chunk_pos(self.loader_pos)

    def set_pos(self, pos):
        self.loader_pos = pos
        self.set_loader_chunk_pos(pos)

    def render(self, screen, use_pos, other_offset=0):
        for ch in self.loaded_chunks.values():
            screen.blit(
                ch.surface,
                (ch.actual_pos - self.loader_pos * int(use_pos)) + other_offset,
            )
class Vector(pygame.math.Vector2):
    def __hash__(self):
        return id(self)

def handle_chunk_loader(self):
    chunks_needed = {Vector(i) for i in self.chunks_to_load()}
    loaded_chunks = {Vector(i) for i in self.loaded_chunks}
    self.load_chunks(chunks_needed - loaded_chunks)
    self.unload_chunks(loaded_chunks - chunks_needed)
import pygame
from bisect import bisect
from itertools import product

BLOCK_SIZE = 64
BLOCK_TEXTURE_NAMES = [
    "textures/void.png",
    "textures/air.png",
    "textures/grass_block.png",
    "textures/dirt.png",
    "textures/stone.png",
    "textures/sandstone.png",
    "textures/sand.png",
    "textures/bedrock.png",
    "textures/oak_log.png",
    "textures/oak_leaves.png",
    "textures/cobblestone.png",
]


def block_texture(texture):
    return pygame.transform.scale(
        pygame.image.load(texture), (BLOCK_SIZE, BLOCK_SIZE)
    ).convert_alpha()


def convert(pos, convert_value_x, convert_value_y):
    """Converts coordinate systems."""
    nx, rx = divmod(pos.x, convert_value_x)
    ny, ry = divmod(pos.y, convert_value_y)
    return ((nx, ny), (rx, ry))


class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (1, 3, 4, 0)

    def __init__(self, pos, size):
        self.size = size
        self.actual_size = size * BLOCK_SIZE
        self.block_textures = [
            block_texture(texture) for texture in BLOCK_TEXTURE_NAMES
        ]
        self.backround_texture = block_texture("textures/backround.png")
        self.pos = pos
        self.actual_pos = pos * BLOCK_SIZE
        self.surface = pygame.Surface((self.actual_size, self.actual_size))
        self.x_range = range(self.size)
        self.y_range = range(self.size)
        self.blocks = {}

    def update(self, block_pos, new_block=None):
        vector = pygame.Vector2(block_pos) * BLOCK_SIZE
        self.surface.blit(self.backround_texture, vector)
        self.blocks[block_pos] = block = new_block or self.blocks[block_pos]
        self.surface.blit(block, vector)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos)
                block = self.block_sizes[i]
            self.update((x, y), block)

    def set_blocks(self, blocks):
        self.blocks = blocks
        for x, y in product(self.x_range, self.y_range):
            self.update((x, y))

    def __str__(self):
        return str([self.blocks[(x, y)] for x in self.x_range for y in self.y_range])


class Vector(pygame.math.Vector2):
    def __hash__(self):
        return id(self)

class World:
    def __init__(self, loader_pos, loader_distance, chunk_size):
        self.chunk_size = chunk_size
        self.actual_chunk_size = chunk_size * BLOCK_SIZE
        self.loaded_chunks = {}
        self.loader_pos = loader_pos
        self.set_loader_chunk_pos(loader_pos)
        self.loader_distance = loader_distance
        self.rendered = pygame.Surface((1, 1)).convert_alpha()
        self.innactive_block_data = {}

    def handle_chunk_loader(self):
        chunks_needed = {Vector(i) for i in self.chunks_to_load()}
        loaded_chunks = {Vector(i) for i in self.loaded_chunks}
        self.load_chunks(chunks_needed - loaded_chunks)
        self.unload_chunks(loaded_chunks - chunks_needed)

    def get_data(self, chunk_pos):
        return self.innactive_block_data.get(chunk_pos, False)

    def load_chunks(self, chunks_pos):
        for pos in chunks_pos:
            chunk_pos = (pos.x, pos.y)
            self.loaded_chunks[chunk_pos] = Chunk(pos, self.chunk_size)
            (
                self.loaded_chunks[chunk_pos].set_blocks(block_data)
                if (block_data := self.get_data(chunk_pos))
                else self.loaded_chunks[chunk_pos].generate()
            )

    def unload_chunks(self, chunks_pos):
        for chunk_pos in chunks_pos:
            chunk = self.loaded_chunks.pop(chunk_pos)
            if self.get_data(chunk_pos) != chunk.blocks:
                self.innactive_block_data[chunk_pos] = chunk.blocks

    def get_block(self, pos):
        chunk_pos, block_pos = convert(pos, self.chunk_size, self.chunk_size)
        try:
            return self.loaded_chunks[chunk_pos].blocks[block_pos]
        except IndexError:
            return False

    def get_range(self, axis):
        n = int(getattr(self.loader_chunk_pos, axis))
        return range(
            n - self.loader_distance,
            n + self.loader_distance + 1,
        )

    def chunks_to_load(self):
        return [
            pygame.Vector2(chunk_pos_x * self.chunk_size, chunk_pos_y * self.chunk_size)
            for chunk_pos_x, chunk_pos_y in product(
                self.get_range("x"), self.get_range("y")
            )
        ]

    def set_loader_chunk_pos(self, pos):
        self.loader_chunk_pos = pygame.Vector2(
            convert(pos, self.actual_chunk_size, self.actual_chunk_size)[0]
        )

    def change_pos(self, pos):
        self.loader_pos += pos
        self.set_loader_chunk_pos(self.loader_pos)

    def set_pos(self, pos):
        self.loader_pos = pos
        self.set_loader_chunk_pos(pos)

    def render(self, screen, use_pos, other_offset=0):
        for ch in self.loaded_chunks.values():
            screen.blit(
                ch.surface,
                (ch.actual_pos - self.loader_pos * int(use_pos)) + other_offset,
            )
class Vector(pygame.math.Vector2):
    def __hash__(self):
        return int(self.x * 10 + self.y)

def handle_chunk_loader(self):
    chunks_needed = {Vector(i) for i in self.chunks_to_load()}
    loaded_chunks = {Vector(i) for i in self.loaded_chunks}
    self.load_chunks(chunks_needed - loaded_chunks)
    self.unload_chunks(loaded_chunks - chunks_needed)
import pygame
from bisect import bisect
from itertools import product

BLOCK_SIZE = 64
BLOCK_TEXTURE_NAMES = [
    "textures/void.png",
    "textures/air.png",
    "textures/grass_block.png",
    "textures/dirt.png",
    "textures/stone.png",
    "textures/sandstone.png",
    "textures/sand.png",
    "textures/bedrock.png",
    "textures/oak_log.png",
    "textures/oak_leaves.png",
    "textures/cobblestone.png",
]


def block_texture(texture):
    return pygame.transform.scale(
        pygame.image.load(texture), (BLOCK_SIZE, BLOCK_SIZE)
    ).convert_alpha()


def convert(pos, convert_value_x, convert_value_y):
    """Converts coordinate systems."""
    nx, rx = divmod(pos.x, convert_value_x)
    ny, ry = divmod(pos.y, convert_value_y)
    return ((nx, ny), (rx, ry))


class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (1, 3, 4, 0)

    def __init__(self, pos, size):
        self.size = size
        self.actual_size = size * BLOCK_SIZE
        self.block_textures = [
            block_texture(texture) for texture in BLOCK_TEXTURE_NAMES
        ]
        self.backround_texture = block_texture("textures/backround.png")
        self.pos = pos
        self.actual_pos = pos * BLOCK_SIZE
        self.surface = pygame.Surface((self.actual_size, self.actual_size))
        self.x_range = range(self.size)
        self.y_range = range(self.size)
        self.blocks = {}

    def update(self, block_pos, new_block=None):
        vector = pygame.Vector2(block_pos) * BLOCK_SIZE
        self.surface.blit(self.backround_texture, vector)
        self.blocks[block_pos] = block = new_block or self.blocks[block_pos]
        self.surface.blit(block, vector)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos)
                block = self.block_sizes[i]
            self.update((x, y), block)

    def set_blocks(self, blocks):
        self.blocks = blocks
        for x, y in product(self.x_range, self.y_range):
            self.update((x, y))

    def __str__(self):
        return str([self.blocks[(x, y)] for x in self.x_range for y in self.y_range])


class Vector(pygame.math.Vector2):
    def __hash__(self):
        return int(self.x * 10 + self.y)

class World:
    def __init__(self, loader_pos, loader_distance, chunk_size):
        self.chunk_size = chunk_size
        self.actual_chunk_size = chunk_size * BLOCK_SIZE
        self.loaded_chunks = {}
        self.loader_pos = loader_pos
        self.set_loader_chunk_pos(loader_pos)
        self.loader_distance = loader_distance
        self.rendered = pygame.Surface((1, 1)).convert_alpha()
        self.innactive_block_data = {}

    def handle_chunk_loader(self):
        chunks_needed = {Vector(i) for i in self.chunks_to_load()}
        loaded_chunks = {Vector(i) for i in self.loaded_chunks}
        self.load_chunks(chunks_needed - loaded_chunks)
        self.unload_chunks(loaded_chunks - chunks_needed)

    def get_data(self, chunk_pos):
        return self.innactive_block_data.get(chunk_pos, False)

    def load_chunks(self, chunks_pos):
        for pos in chunks_pos:
            chunk_pos = (pos.x, pos.y)
            self.loaded_chunks[chunk_pos] = Chunk(pos, self.chunk_size)
            (
                self.loaded_chunks[chunk_pos].set_blocks(block_data)
                if (block_data := self.get_data(chunk_pos))
                else self.loaded_chunks[chunk_pos].generate()
            )

    def unload_chunks(self, chunks_pos):
        for chunk_pos in chunks_pos:
            chunk = self.loaded_chunks.pop(chunk_pos)
            if self.get_data(chunk_pos) != chunk.blocks:
                self.innactive_block_data[chunk_pos] = chunk.blocks

    def get_block(self, pos):
        chunk_pos, block_pos = convert(pos, self.chunk_size, self.chunk_size)
        try:
            return self.loaded_chunks[chunk_pos].blocks[block_pos]
        except IndexError:
            return False

    def get_range(self, axis):
        n = int(getattr(self.loader_chunk_pos, axis))
        return range(
            n - self.loader_distance,
            n + self.loader_distance + 1,
        )

    def chunks_to_load(self):
        return [
            pygame.Vector2(chunk_pos_x * self.chunk_size, chunk_pos_y * self.chunk_size)
            for chunk_pos_x, chunk_pos_y in product(
                self.get_range("x"), self.get_range("y")
            )
        ]

    def set_loader_chunk_pos(self, pos):
        self.loader_chunk_pos = pygame.Vector2(
            convert(pos, self.actual_chunk_size, self.actual_chunk_size)[0]
        )

    def change_pos(self, pos):
        self.loader_pos += pos
        self.set_loader_chunk_pos(self.loader_pos)

    def set_pos(self, pos):
        self.loader_pos = pos
        self.set_loader_chunk_pos(pos)

    def render(self, screen, use_pos, other_offset=0):
        for ch in self.loaded_chunks.values():
            screen.blit(
                ch.surface,
                (ch.actual_pos - self.loader_pos * int(use_pos)) + other_offset,
            )
added 242 characters in body
Source Link

Your code is of very poor quality, though it is understandable considering you very likely copied from ChatGPT. If you didn't copy from ChatGPT, then the quality of your code is about the same level as what ChatGPT would generate. You have a long way to go. But I don't mean to discourage you, you just have a lot to learn and huge potential to improve.

Your code is of very poor quality, though it is understandable considering you very likely copied from ChatGPT.

Your code is of very poor quality, though it is understandable considering you very likely copied from ChatGPT. If you didn't copy from ChatGPT, then the quality of your code is about the same level as what ChatGPT would generate. You have a long way to go. But I don't mean to discourage you, you just have a lot to learn and huge potential to improve.

deleted 72 characters in body
Source Link
class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (1, 3, 4, 0)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos) - 1
                block = self.block_sizes[i]
            block = max(block, 0)
            self.update((x, y), block)
import pygame
from bisect import bisect
from itertools import product

BLOCK_SIZE = 64
BLOCK_TEXTURE_NAMES = [
    "textures/void.png",
    "textures/air.png",
    "textures/grass_block.png",
    "textures/dirt.png",
    "textures/stone.png",
    "textures/sandstone.png",
    "textures/sand.png",
    "textures/bedrock.png",
    "textures/oak_log.png",
    "textures/oak_leaves.png",
    "textures/cobblestone.png",
]


def block_texture(texture):
    return pygame.transform.scale(
        pygame.image.load(texture), (BLOCK_SIZE, BLOCK_SIZE)
    ).convert_alpha()


def convert(pos, convert_value_x, convert_value_y):
    """Converts coordinate systems."""
    nx, rx = divmod(pos.x, convert_value_x)
    ny, ry = divmod(pos.y, convert_value_y)
    return ((nx, ny), (rx, ry))


class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (1, 3, 4, 0)

    def __init__(self, pos, size):
        self.size = size
        self.actual_size = size * BLOCK_SIZE
        self.block_textures = [
            block_texture(texture) for texture in BLOCK_TEXTURE_NAMES
        ]
        self.backround_texture = block_texture("textures/backround.png")
        self.pos = pos
        self.actual_pos = pos * BLOCK_SIZE
        self.surface = pygame.Surface((self.actual_size, self.actual_size))
        self.x_range = range(self.size)
        self.y_range = range(self.size)
        self.blocks = {}

    def update(self, block_pos, new_block=None):
        vector = pygame.Vector2(block_pos) * BLOCK_SIZE
        self.surface.blit(self.backround_texture, vector)
        self.blocks[block_pos] = block = new_block or self.blocks[block_pos]
        self.surface.blit(block, vector)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos) - 1
                block = self.block_sizes[i]
            block = max(block, 0)
            self.update((x, y), block)

    def set_blocks(self, blocks):
        self.blocks = blocks
        for x, y in product(self.x_range, self.y_range):
            self.update((x, y))

    def __str__(self):
        return str([self.blocks[(x, y)] for x in self.x_range for y in self.y_range])


class Vector(pygame.math.Vector2):
    def __hash__(self):
        return id(self)

class World:
    def __init__(self, loader_pos, loader_distance, chunk_size):
        self.chunk_size = chunk_size
        self.actual_chunk_size = chunk_size * BLOCK_SIZE
        self.loaded_chunks = {}
        self.loader_pos = loader_pos
        self.set_loader_chunk_pos(loader_pos)
        self.loader_distance = loader_distance
        self.rendered = pygame.Surface((1, 1)).convert_alpha()
        self.innactive_block_data = {}

    def handle_chunk_loader(self):
        chunks_needed = {Vector(i) for i in self.chunks_to_load()}
        loaded_chunks = {Vector(i) for i in self.loaded_chunks}
        self.load_chunks(chunks_needed - loaded_chunks)
        self.unload_chunks(loaded_chunks - chunks_needed)

    def get_data(self, chunk_pos):
        return self.innactive_block_data.get(chunk_pos, False)

    def load_chunks(self, chunks_pos):
        for pos in chunks_pos:
            chunk_pos = (pos.x, pos.y)
            self.loaded_chunks[chunk_pos] = Chunk(pos, self.chunk_size)
            (
                self.loaded_chunks[chunk_pos].set_blocks(block_data)
                if (block_data := self.get_data(chunk_pos))
                else self.loaded_chunks[chunk_pos].generate()
            )

    def unload_chunks(self, chunks_pos):
        for chunk_pos in chunks_pos:
            chunk = self.loaded_chunks.pop(chunk_pos)
            if self.get_data(chunk_pos) != chunk.blocks:
                self.innactive_block_data[chunk_pos] = chunk.blocks

    def get_block(self, pos):
        chunk_pos, block_pos = convert(pos, self.chunk_size, self.chunk_size)
        try:
            return self.loaded_chunks[chunk_pos].blocks[block_pos]
        except IndexError:
            return False

    def get_range(self, axis):
        n = int(getattr(self.loader_chunk_pos, axis))
        return range(
            n - self.loader_distance,
            n + self.loader_distance + 1,
        )

    def chunks_to_load(self):
        return [
            pygame.Vector2(chunk_pos_x * self.chunk_size, chunk_pos_y * self.chunk_size)
            for chunk_pos_x, chunk_pos_y in product(
                self.get_range("x"), self.get_range("y")
            )
        ]

    def set_loader_chunk_pos(self, pos):
        self.loader_chunk_pos = pygame.Vector2(
            convert(pos, self.actual_chunk_size, self.actual_chunk_size)[0]
        )

    def change_pos(self, pos):
        self.loader_pos += pos
        self.set_loader_chunk_pos(self.loader_pos)

    def set_pos(self, pos):
        self.loader_pos = pos
        self.set_loader_chunk_pos(pos)

    def render(self, screen, use_pos, other_offset=0):
        for ch in self.loaded_chunks.values():
            screen.blit(
                ch.surface,
                (ch.actual_pos - self.loader_pos * int(use_pos)) + other_offset,
            )
class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (3, 4, 0)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos) - 1
                block = self.block_sizes[i]
            block = max(block, 0)
            self.update((x, y), block)
import pygame
from bisect import bisect
from itertools import product

BLOCK_SIZE = 64
BLOCK_TEXTURE_NAMES = [
    "textures/void.png",
    "textures/air.png",
    "textures/grass_block.png",
    "textures/dirt.png",
    "textures/stone.png",
    "textures/sandstone.png",
    "textures/sand.png",
    "textures/bedrock.png",
    "textures/oak_log.png",
    "textures/oak_leaves.png",
    "textures/cobblestone.png",
]


def block_texture(texture):
    return pygame.transform.scale(
        pygame.image.load(texture), (BLOCK_SIZE, BLOCK_SIZE)
    ).convert_alpha()


def convert(pos, convert_value_x, convert_value_y):
    """Converts coordinate systems."""
    nx, rx = divmod(pos.x, convert_value_x)
    ny, ry = divmod(pos.y, convert_value_y)
    return ((nx, ny), (rx, ry))


class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (3, 4, 0)

    def __init__(self, pos, size):
        self.size = size
        self.actual_size = size * BLOCK_SIZE
        self.block_textures = [
            block_texture(texture) for texture in BLOCK_TEXTURE_NAMES
        ]
        self.backround_texture = block_texture("textures/backround.png")
        self.pos = pos
        self.actual_pos = pos * BLOCK_SIZE
        self.surface = pygame.Surface((self.actual_size, self.actual_size))
        self.x_range = range(self.size)
        self.y_range = range(self.size)
        self.blocks = {}

    def update(self, block_pos, new_block=None):
        vector = pygame.Vector2(block_pos) * BLOCK_SIZE
        self.surface.blit(self.backround_texture, vector)
        self.blocks[block_pos] = block = new_block or self.blocks[block_pos]
        self.surface.blit(block, vector)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos) - 1
                block = self.block_sizes[i]
            block = max(block, 0)
            self.update((x, y), block)

    def set_blocks(self, blocks):
        self.blocks = blocks
        for x, y in product(self.x_range, self.y_range):
            self.update((x, y))

    def __str__(self):
        return str([self.blocks[(x, y)] for x in self.x_range for y in self.y_range])


class Vector(pygame.math.Vector2):
    def __hash__(self):
        return id(self)

class World:
    def __init__(self, loader_pos, loader_distance, chunk_size):
        self.chunk_size = chunk_size
        self.actual_chunk_size = chunk_size * BLOCK_SIZE
        self.loaded_chunks = {}
        self.loader_pos = loader_pos
        self.set_loader_chunk_pos(loader_pos)
        self.loader_distance = loader_distance
        self.rendered = pygame.Surface((1, 1)).convert_alpha()
        self.innactive_block_data = {}

    def handle_chunk_loader(self):
        chunks_needed = {Vector(i) for i in self.chunks_to_load()}
        loaded_chunks = {Vector(i) for i in self.loaded_chunks}
        self.load_chunks(chunks_needed - loaded_chunks)
        self.unload_chunks(loaded_chunks - chunks_needed)

    def get_data(self, chunk_pos):
        return self.innactive_block_data.get(chunk_pos, False)

    def load_chunks(self, chunks_pos):
        for pos in chunks_pos:
            chunk_pos = (pos.x, pos.y)
            self.loaded_chunks[chunk_pos] = Chunk(pos, self.chunk_size)
            (
                self.loaded_chunks[chunk_pos].set_blocks(block_data)
                if (block_data := self.get_data(chunk_pos))
                else self.loaded_chunks[chunk_pos].generate()
            )

    def unload_chunks(self, chunks_pos):
        for chunk_pos in chunks_pos:
            chunk = self.loaded_chunks.pop(chunk_pos)
            if self.get_data(chunk_pos) != chunk.blocks:
                self.innactive_block_data[chunk_pos] = chunk.blocks

    def get_block(self, pos):
        chunk_pos, block_pos = convert(pos, self.chunk_size, self.chunk_size)
        try:
            return self.loaded_chunks[chunk_pos].blocks[block_pos]
        except IndexError:
            return False

    def get_range(self, axis):
        n = int(getattr(self.loader_chunk_pos, axis))
        return range(
            n - self.loader_distance,
            n + self.loader_distance + 1,
        )

    def chunks_to_load(self):
        return [
            pygame.Vector2(chunk_pos_x * self.chunk_size, chunk_pos_y * self.chunk_size)
            for chunk_pos_x, chunk_pos_y in product(
                self.get_range("x"), self.get_range("y")
            )
        ]

    def set_loader_chunk_pos(self, pos):
        self.loader_chunk_pos = pygame.Vector2(
            convert(pos, self.actual_chunk_size, self.actual_chunk_size)[0]
        )

    def change_pos(self, pos):
        self.loader_pos += pos
        self.set_loader_chunk_pos(self.loader_pos)

    def set_pos(self, pos):
        self.loader_pos = pos
        self.set_loader_chunk_pos(pos)

    def render(self, screen, use_pos, other_offset=0):
        for ch in self.loaded_chunks.values():
            screen.blit(
                ch.surface,
                (ch.actual_pos - self.loader_pos * int(use_pos)) + other_offset,
            )
class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (1, 3, 4, 0)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos)
                block = self.block_sizes[i]
            self.update((x, y), block)
import pygame
from bisect import bisect
from itertools import product

BLOCK_SIZE = 64
BLOCK_TEXTURE_NAMES = [
    "textures/void.png",
    "textures/air.png",
    "textures/grass_block.png",
    "textures/dirt.png",
    "textures/stone.png",
    "textures/sandstone.png",
    "textures/sand.png",
    "textures/bedrock.png",
    "textures/oak_log.png",
    "textures/oak_leaves.png",
    "textures/cobblestone.png",
]


def block_texture(texture):
    return pygame.transform.scale(
        pygame.image.load(texture), (BLOCK_SIZE, BLOCK_SIZE)
    ).convert_alpha()


def convert(pos, convert_value_x, convert_value_y):
    """Converts coordinate systems."""
    nx, rx = divmod(pos.x, convert_value_x)
    ny, ry = divmod(pos.y, convert_value_y)
    return ((nx, ny), (rx, ry))


class Chunk:
    surface = 0
    bedrock = 16
    ground = 3
    starts = (surface, ground, bedrock)
    levels = dict(zip(starts, (2, 3, 7)))
    block_sizes = (1, 3, 4, 0)

    def __init__(self, pos, size):
        self.size = size
        self.actual_size = size * BLOCK_SIZE
        self.block_textures = [
            block_texture(texture) for texture in BLOCK_TEXTURE_NAMES
        ]
        self.backround_texture = block_texture("textures/backround.png")
        self.pos = pos
        self.actual_pos = pos * BLOCK_SIZE
        self.surface = pygame.Surface((self.actual_size, self.actual_size))
        self.x_range = range(self.size)
        self.y_range = range(self.size)
        self.blocks = {}

    def update(self, block_pos, new_block=None):
        vector = pygame.Vector2(block_pos) * BLOCK_SIZE
        self.surface.blit(self.backround_texture, vector)
        self.blocks[block_pos] = block = new_block or self.blocks[block_pos]
        self.surface.blit(block, vector)

    def generate(self):
        for x, y in product(self.x_range, self.y_range):
            y_pos = int(self.pos.y) + y
            if y_pos in self.levels:
                block = self.levels[y_pos]
            else:
                i = bisect(self.starts, y_pos)
                block = self.block_sizes[i]
            self.update((x, y), block)

    def set_blocks(self, blocks):
        self.blocks = blocks
        for x, y in product(self.x_range, self.y_range):
            self.update((x, y))

    def __str__(self):
        return str([self.blocks[(x, y)] for x in self.x_range for y in self.y_range])


class Vector(pygame.math.Vector2):
    def __hash__(self):
        return id(self)

class World:
    def __init__(self, loader_pos, loader_distance, chunk_size):
        self.chunk_size = chunk_size
        self.actual_chunk_size = chunk_size * BLOCK_SIZE
        self.loaded_chunks = {}
        self.loader_pos = loader_pos
        self.set_loader_chunk_pos(loader_pos)
        self.loader_distance = loader_distance
        self.rendered = pygame.Surface((1, 1)).convert_alpha()
        self.innactive_block_data = {}

    def handle_chunk_loader(self):
        chunks_needed = {Vector(i) for i in self.chunks_to_load()}
        loaded_chunks = {Vector(i) for i in self.loaded_chunks}
        self.load_chunks(chunks_needed - loaded_chunks)
        self.unload_chunks(loaded_chunks - chunks_needed)

    def get_data(self, chunk_pos):
        return self.innactive_block_data.get(chunk_pos, False)

    def load_chunks(self, chunks_pos):
        for pos in chunks_pos:
            chunk_pos = (pos.x, pos.y)
            self.loaded_chunks[chunk_pos] = Chunk(pos, self.chunk_size)
            (
                self.loaded_chunks[chunk_pos].set_blocks(block_data)
                if (block_data := self.get_data(chunk_pos))
                else self.loaded_chunks[chunk_pos].generate()
            )

    def unload_chunks(self, chunks_pos):
        for chunk_pos in chunks_pos:
            chunk = self.loaded_chunks.pop(chunk_pos)
            if self.get_data(chunk_pos) != chunk.blocks:
                self.innactive_block_data[chunk_pos] = chunk.blocks

    def get_block(self, pos):
        chunk_pos, block_pos = convert(pos, self.chunk_size, self.chunk_size)
        try:
            return self.loaded_chunks[chunk_pos].blocks[block_pos]
        except IndexError:
            return False

    def get_range(self, axis):
        n = int(getattr(self.loader_chunk_pos, axis))
        return range(
            n - self.loader_distance,
            n + self.loader_distance + 1,
        )

    def chunks_to_load(self):
        return [
            pygame.Vector2(chunk_pos_x * self.chunk_size, chunk_pos_y * self.chunk_size)
            for chunk_pos_x, chunk_pos_y in product(
                self.get_range("x"), self.get_range("y")
            )
        ]

    def set_loader_chunk_pos(self, pos):
        self.loader_chunk_pos = pygame.Vector2(
            convert(pos, self.actual_chunk_size, self.actual_chunk_size)[0]
        )

    def change_pos(self, pos):
        self.loader_pos += pos
        self.set_loader_chunk_pos(self.loader_pos)

    def set_pos(self, pos):
        self.loader_pos = pos
        self.set_loader_chunk_pos(pos)

    def render(self, screen, use_pos, other_offset=0):
        for ch in self.loaded_chunks.values():
            screen.blit(
                ch.surface,
                (ch.actual_pos - self.loader_pos * int(use_pos)) + other_offset,
            )
Bounty Ended with 50 reputation awarded by coder
added 2 characters in body
Source Link
Loading
added 837 characters in body
Source Link
Loading
added 15 characters in body
Source Link
Loading
Source Link
Loading