Загрузка данных
import pygame
import sys
import random
import math
pygame.init()
# =========================
# BASIC SETTINGS
# =========================
WIDTH, HEIGHT = 1280, 720
TILE = 32
FPS = 60
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Terrablock")
clock = pygame.time.Clock()
FONT = pygame.font.SysFont("Arial", 20)
BIG = pygame.font.SysFont("Arial", 44)
SMALL = pygame.font.SysFont("Arial", 16)
# =========================
# COLORS
# =========================
C = {
"menu": (20, 20, 30),
"panel": (35, 35, 50),
"white": (255, 255, 255),
"black": (0, 0, 0),
"red": (220, 70, 70),
"green": (80, 220, 120),
"blue": (70, 120, 230),
"yellow": (240, 220, 80),
"grass": (80, 200, 120),
"dirt": (139, 92, 52),
"stone": (130, 130, 130),
"wood": (120, 75, 35),
"leaves": (40, 160, 70),
"sand": (220, 210, 130),
"netherrack": (140, 40, 40),
"lava": (255, 90, 20),
"endstone": (210, 210, 160),
"portal": (120, 0, 255),
"city": (180, 180, 220),
"bedrock": (30, 30, 30),
"village": (200, 170, 120),
"spawner": (100, 0, 120),
"trial": (70, 120, 180),
"dragon_egg": (50, 0, 60),
"player": (50, 100, 220),
"hair": (60, 40, 20),
"skin": (240, 200, 170),
"shirt": (50, 120, 220),
"pants": (70, 70, 150),
}
BLOCK_COLORS = {
"grass": C["grass"], "dirt": C["dirt"], "stone": C["stone"], "wood": C["wood"],
"leaves": C["leaves"], "sand": C["sand"], "netherrack": C["netherrack"],
"lava": C["lava"], "endstone": C["endstone"], "portal": C["portal"],
"city": C["city"], "bedrock": C["bedrock"], "village": C["village"],
"spawner": C["spawner"], "trial": C["trial"], "dragon_egg": C["dragon_egg"]
}
# =========================
# GAME STATE
# =========================
class State:
def __init__(self):
self.mode = "menu" # menu, play, skin, command, dead
self.difficulty = "normal"
self.menu_index = 0
self.command_text = ""
self.message = ""
self.message_timer = 0
state = State()
# =========================
# INVENTORY
# =========================
class Inventory:
def __init__(self):
self.hotbar = [
"wood_pickaxe", "wood_axe", "wood_shovel", "wood_hoe",
"wood_spear", "wood_sword", "stone_pickaxe", "block_grass", "block_stone"
]
self.selected = 0
self.items = {
"block_grass": 64,
"block_dirt": 64,
"block_stone": 64,
"wood": 50,
"iron_ingot": 20,
"diamond": 10,
"netherite_ingot": 5,
"dragon_egg": 1,
"spawner_item": 2,
"trial_key": 2,
"mace": 1,
"spear": 1,
"leather_helmet": 1, "leather_chest": 1, "leather_legs": 1, "leather_boots": 1,
"iron_helmet": 1, "iron_chest": 1, "iron_legs": 1, "iron_boots": 1,
"diamond_helmet": 1, "diamond_chest": 1, "diamond_legs": 1, "diamond_boots": 1,
"netherite_helmet": 1, "netherite_chest": 1, "netherite_legs": 1, "netherite_boots": 1,
}
def add(self, item, n=1):
self.items[item] = self.items.get(item, 0) + n
def remove(self, item, n=1):
if self.items.get(item, 0) >= n:
self.items[item] -= n
if self.items[item] <= 0:
self.items.pop(item, None)
return True
return False
# =========================
# PLAYER
# =========================
ARMOR_DEF = {"leather": 1, "iron": 3, "diamond": 4, "netherite": 5}
SWORD_POWER = {"wood": 2, "stone": 3, "iron": 4, "diamond": 5, "netherite": 7}
TOOL_POWER = {"wood": 1, "stone": 2, "iron": 3, "diamond": 4, "netherite": 5}
class Player:
def __init__(self, x, y):
self.rect = pygame.Rect(x * TILE, y * TILE, 24, 30)
self.vel_y = 0
self.speed = 4
self.jump_power = -11
self.on_ground = False
self.max_hp = 20
self.hp = 20
self.invuln = 0
self.dead = False
self.hunger = 20
self.armor = {"helmet": None, "chest": None, "legs": None, "boots": None}
self.skin = {"hair": C["hair"], "skin": C["skin"], "shirt": C["shirt"], "pants": C["pants"]}
def armor_points(self):
pts = 0
for item in self.armor.values():
if item:
tier = item.split("_")[0]
pts += ARMOR_DEF.get(tier, 0)
return pts
def equip_armor(self, item):
if item.endswith("_helmet"):
self.armor["helmet"] = item
elif item.endswith("_chest"):
self.armor["chest"] = item
elif item.endswith("_legs"):
self.armor["legs"] = item
elif item.endswith("_boots"):
self.armor["boots"] = item
def take_damage(self, dmg):
if self.invuln > 0:
return
reduced = max(1, dmg - self.armor_points() // 2)
self.hp -= reduced
self.invuln = 45
if self.hp <= 0:
self.dead = True
# =========================
# ENTITIES
# =========================
class Mob:
def __init__(self, x, y, kind="zombie"):
self.kind = kind
self.rect = pygame.Rect(x * TILE, y * TILE, 24, 28)
self.vel_y = 0
self.hp = 10 if kind == "zombie" else 18
self.speed = 1 if kind == "zombie" else 2
def update(self, world, player):
dx = 0
if player.rect.centerx < self.rect.centerx:
dx = -self.speed
elif player.rect.centerx > self.rect.centerx:
dx = self.speed
self.rect.x += dx
for (bx, by), block in world.blocks.items():
br = pygame.Rect(bx * TILE, by * TILE, TILE, TILE)
if self.rect.colliderect(br):
if dx > 0:
self.rect.right = br.left
elif dx < 0:
self.rect.left = br.right
self.vel_y += 0.5
self.rect.y += int(self.vel_y)
for (bx, by), block in world.blocks.items():
br = pygame.Rect(bx * TILE, by * TILE, TILE, TILE)
if self.rect.colliderect(br):
if self.vel_y > 0:
self.rect.bottom = br.top
self.vel_y = 0
if self.rect.colliderect(player.rect):
player.take_damage(1 if self.kind == "zombie" else 2)
class World:
def __init__(