Update world.py
parent
00835805f8
commit
dcbdbe4c74
139
world.py
139
world.py
|
|
@ -0,0 +1,139 @@
|
||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
from settings import *
|
||||||
|
|
||||||
|
|
||||||
|
class World:
|
||||||
|
def __init__(self):
|
||||||
|
self.width = WORLD_WIDTH
|
||||||
|
self.height = WORLD_HEIGHT
|
||||||
|
|
||||||
|
# 2D grid: world[y][x]
|
||||||
|
self.grid = [
|
||||||
|
[AIR for _ in range(self.width)]
|
||||||
|
for _ in range(self.height)
|
||||||
|
]
|
||||||
|
|
||||||
|
self.generate_world()
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# WORLD GENERATION
|
||||||
|
# ==========================================================
|
||||||
|
def generate_world(self):
|
||||||
|
for x in range(self.width):
|
||||||
|
|
||||||
|
# Simple terrain height variation
|
||||||
|
surface_height = SURFACE_LEVEL + random.randint(-3, 3)
|
||||||
|
|
||||||
|
for y in range(self.height):
|
||||||
|
|
||||||
|
if y < surface_height:
|
||||||
|
self.grid[y][x] = AIR
|
||||||
|
|
||||||
|
elif y == surface_height:
|
||||||
|
self.grid[y][x] = GRASS
|
||||||
|
|
||||||
|
elif y < surface_height + 5:
|
||||||
|
self.grid[y][x] = DIRT
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.grid[y][x] = STONE
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# DRAW
|
||||||
|
# ==========================================================
|
||||||
|
def draw(self, screen, camera):
|
||||||
|
|
||||||
|
# Determine visible tile range
|
||||||
|
start_x = max(0, camera.offset.x // TILE_SIZE)
|
||||||
|
end_x = min(self.width, (camera.offset.x + SCREEN_WIDTH) // TILE_SIZE + 2)
|
||||||
|
|
||||||
|
start_y = max(0, camera.offset.y // TILE_SIZE)
|
||||||
|
end_y = min(self.height, (camera.offset.y + SCREEN_HEIGHT) // TILE_SIZE + 2)
|
||||||
|
|
||||||
|
for y in range(int(start_y), int(end_y)):
|
||||||
|
for x in range(int(start_x), int(end_x)):
|
||||||
|
|
||||||
|
tile_id = self.grid[y][x]
|
||||||
|
|
||||||
|
if tile_id != AIR:
|
||||||
|
color = TILE_PROPERTIES[tile_id]["color"]
|
||||||
|
|
||||||
|
world_rect = pygame.Rect(
|
||||||
|
x * TILE_SIZE,
|
||||||
|
y * TILE_SIZE,
|
||||||
|
TILE_SIZE,
|
||||||
|
TILE_SIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
screen_rect = camera.apply(world_rect)
|
||||||
|
|
||||||
|
pygame.draw.rect(screen, color, screen_rect)
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# COLLISION SUPPORT
|
||||||
|
# ==========================================================
|
||||||
|
def get_nearby_tiles(self, rect):
|
||||||
|
tiles = []
|
||||||
|
|
||||||
|
# Determine tile range around player
|
||||||
|
start_x = max(0, rect.left // TILE_SIZE - 1)
|
||||||
|
end_x = min(self.width, rect.right // TILE_SIZE + 2)
|
||||||
|
|
||||||
|
start_y = max(0, rect.top // TILE_SIZE - 1)
|
||||||
|
end_y = min(self.height, rect.bottom // TILE_SIZE + 2)
|
||||||
|
|
||||||
|
for y in range(start_y, end_y):
|
||||||
|
for x in range(start_x, end_x):
|
||||||
|
|
||||||
|
tile_id = self.grid[y][x]
|
||||||
|
|
||||||
|
if tile_id != AIR:
|
||||||
|
tile_rect = pygame.Rect(
|
||||||
|
x * TILE_SIZE,
|
||||||
|
y * TILE_SIZE,
|
||||||
|
TILE_SIZE,
|
||||||
|
TILE_SIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
tiles.append({
|
||||||
|
"rect": tile_rect,
|
||||||
|
"solid": TILE_PROPERTIES[tile_id]["solid"],
|
||||||
|
"id": tile_id,
|
||||||
|
"x": x,
|
||||||
|
"y": y
|
||||||
|
})
|
||||||
|
|
||||||
|
return tiles
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# BLOCK BREAKING
|
||||||
|
# ==========================================================
|
||||||
|
def break_block(self, mouse_pos, camera):
|
||||||
|
world_x, world_y = camera.screen_to_world(mouse_pos)
|
||||||
|
|
||||||
|
tile_x = int(world_x // TILE_SIZE)
|
||||||
|
tile_y = int(world_y // TILE_SIZE)
|
||||||
|
|
||||||
|
if self.in_bounds(tile_x, tile_y):
|
||||||
|
if self.grid[tile_y][tile_x] != AIR:
|
||||||
|
self.grid[tile_y][tile_x] = AIR
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# BLOCK PLACING
|
||||||
|
# ==========================================================
|
||||||
|
def place_block(self, mouse_pos, camera, block_type=DIRT):
|
||||||
|
world_x, world_y = camera.screen_to_world(mouse_pos)
|
||||||
|
|
||||||
|
tile_x = int(world_x // TILE_SIZE)
|
||||||
|
tile_y = int(world_y // TILE_SIZE)
|
||||||
|
|
||||||
|
if self.in_bounds(tile_x, tile_y):
|
||||||
|
if self.grid[tile_y][tile_x] == AIR:
|
||||||
|
self.grid[tile_y][tile_x] = block_type
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# UTIL
|
||||||
|
# ==========================================================
|
||||||
|
def in_bounds(self, x, y):
|
||||||
|
return 0 <= x < self.width and 0 <= y < self.height
|
||||||
Loading…
Reference in New Issue