17.04.2026

This commit is contained in:
Benjamin Hinz 2026-04-17 18:04:33 +02:00
parent a583bf9858
commit 4e8227aead
4 changed files with 151 additions and 12 deletions

4
.gitignore vendored
View file

@ -217,7 +217,9 @@ __marimo__/
# Data # Data
data/ data/
der_test.py
spickzettel.md spickzettel.md
.vscode .vscode
start.bat start.bat
Dateien erstellen.txt
map.json
testen

View file

@ -28,6 +28,7 @@ class Editor:
self.collision_area = pygame.Rect(50, 50, 300, 50) self.collision_area = pygame.Rect(50, 50, 300, 50)
self.movement = [False, False, False, False] self.movement = [False, False, False, False]
self.assets = { self.assets = {
"decor": load_images("tiles/decor"), "decor": load_images("tiles/decor"),
"grass": load_images("tiles/grass"), "grass": load_images("tiles/grass"),
@ -36,6 +37,12 @@ class Editor:
} }
self.tilemap = Tilemap(self, 16) self.tilemap = Tilemap(self, 16)
try:
self.tilemap.load('map.json')
except FileNotFoundError:
pass
self.isJumping = False self.isJumping = False
self.scroll = [0, 0] self.scroll = [0, 0]
self.tile_list = better_list(self.assets) self.tile_list = better_list(self.assets)
@ -48,34 +55,103 @@ class Editor:
self.sekunde = 60 self.sekunde = 60
self.zaehler = 0 self.zaehler = 0
self.on_grid = True
def run(self): def run(self):
while self.running: while self.running:
self.display.fill((0, 0, 0)) self.display.fill((0, 0, 0))
self.scroll[0] += (self.movement[1] - self.movement[0]) * 3
self.scroll[1] += (self.movement[3] - self.movement[2]) * 3
render_scroll = (int(self.scroll[0]), int(self.scroll[1]))
self.tilemap.render(surface=self.display, offset=render_scroll)
current_tile_img = self.assets[self.tile_list[self.tile_group]][self.tile_variant].copy() current_tile_img = self.assets[self.tile_list[self.tile_group]][self.tile_variant].copy()
current_tile_img.set_alpha(100) current_tile_img.set_alpha(100)
mpos = pygame.mouse.get_pos()
mpos = (mpos[0] / RENDER_SCALE, mpos[1] / RENDER_SCALE)
tile_pos = (int((mpos[0] + self.scroll[0]) // self.tilemap.tile_size),
int((mpos[1] + self.scroll[1]) // self.tilemap.tile_size))
# print(tile_pos[0] * self.tilemap.tile_size + self.scroll[0], tile_pos[1]*self.tilemap.tile_size + self.scroll[1])
# print(mpos)
if self.on_grid:
self.display.blit(current_tile_img, (tile_pos[0] * self.tilemap.tile_size - self.scroll[0], tile_pos[1]*self.tilemap.tile_size - self.scroll[1]))
else:
self.display.blit(current_tile_img, (mpos[0], mpos[1]))
if self.clicking:
if self.on_grid:
self.tilemap.tilemap[str(tile_pos[0]) + ';' + str(tile_pos[1])] = {
'type': self.tile_list[self.tile_group],
'variant': self.tile_variant,
'pos': tile_pos
}
if not self.on_grid:
self.tilemap.offgrid_tiles.append({"type": self.tile_list[self.tile_group], "variant": self.tile_variant, "pos": (mpos[0]+self.scroll[0], mpos[1]+self.scroll[1])})
if self.right_clicking:
tile_loc = str(tile_pos[0]) + ';' + str(tile_pos[1])
if tile_loc in self.tilemap.tilemap:
del self.tilemap.tilemap[tile_loc]
for offi_tile in self.tilemap.offgrid_tiles.copy():
offi_tile_img = self.assets[offi_tile['type']][offi_tile['variant']]
offi_tile_r = pygame.Rect(offi_tile["pos"][0]-self.scroll[0], offi_tile["pos"][1]-self.scroll[1], offi_tile_img.get_width(), offi_tile_img.get_height())
if offi_tile_r.collidepoint(mpos):
self.tilemap.offgrid_tiles.remove(offi_tile)
self.display.blit(current_tile_img, (5, 5)) self.display.blit(current_tile_img, (5, 5))
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
self.running = False self.running = False
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1: self.clicking = False
if event.button == 3: self.right_clicking = False
if event.type == pygame.KEYDOWN: if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE: if event.key == pygame.K_ESCAPE:
self.running = False self.running = False
if event.key == pygame.K_a: if event.key == pygame.K_a:
self.movement[0] = True self.movement[0] = True
if event.key == pygame.K_d: if event.key == pygame.K_d:
self.movement[1] = True self.movement[1] = True
if event.key == pygame.K_w: if event.key == pygame.K_w:
self.movement[2] = True self.movement[2] = True
if event.key == pygame.K_s: if event.key == pygame.K_s:
self.movement[3] = True self.movement[3] = True
if event.key == pygame.K_LSHIFT: if event.key == pygame.K_LSHIFT:
self.shifting = True self.shifting = True
if event.key == pygame.K_g:
self.on_grid = not self.on_grid
if event.key == pygame.K_o:
self.tilemap.save('map.json')
print("Map gespeichert")
if event.key == pygame.K_t:
self.tilemap.autotile()
if event.type == pygame.KEYUP: if event.type == pygame.KEYUP:
@ -137,7 +213,7 @@ class Editor:
self.zaehler += 1 self.zaehler += 1
if self.zaehler >= self.sekunde: if self.zaehler >= self.sekunde:
self.zaehler = 0 self.zaehler = 0
print(f"{self.tile_group} + {self.tile_variant}") # print(f"{self.tile_group} + {self.tile_variant}")
self.screen.blit(pygame.transform.scale(self.display, self.screen.get_size()), (0,0)) self.screen.blit(pygame.transform.scale(self.display, self.screen.get_size()), (0,0))
pygame.display.update() pygame.display.update()
self.clock.tick(60) self.clock.tick(60)

11
game.py
View file

@ -42,9 +42,15 @@ class Game:
self.player = Player(self, (50, 50), (8, 15)) self.player = Player(self, (50, 50), (8, 15))
self.tilemap = Tilemap(self, 16) self.tilemap = Tilemap(self, 16)
self.tilemap.load("map.json")
self.clouds = Clouds(self.assets['clouds'], count=16) self.clouds = Clouds(self.assets['clouds'], count=16)
self.isJumping = False self.isJumping = False
self.scroll = [0, 0] self.scroll = [0, 0]
self.test :dict = {"dsa"}
def testolino(self):
print(self.test)
print(type(self.test))
def run(self): def run(self):
@ -97,4 +103,9 @@ class Game:
game = Game() game = Game()
if __name__ == "__main__":
# game.testolino()
pass
game.run() game.run()

View file

@ -1,6 +1,21 @@
import pygame as pg import pygame as pg
import json
NEIGHBOR_OFFSETS = [(0, 0), (-1, 0), (-1, -1), (-1, 1), (0, 1), (0, -1), (1, 1), (1, 0), (1, -1)] NEIGHBOR_OFFSETS = [(0, 0), (-1, 0), (-1, -1), (-1, 1), (0, 1), (0, -1), (1, 1), (1, 0), (1, -1)]
PHYSICS_TILES = {"grass", "stone"} PHYSICS_TILES = {"grass", "stone"}
AUTOTILE_TYPES = {'grass', 'stone'}
AUTOTILE_MAP = {
tuple(sorted([(1, 0), (0, 1)])): 0,
tuple(sorted([(1, 0), (0, 1), (-1, 0)])): 1,
tuple(sorted([(-1, 0), (0, 1)])): 2,
tuple(sorted([(-1, 0), (0, -1), (0, 1)])): 3,
tuple(sorted([(-1, 0), (0, -1)])): 4,
tuple(sorted([(-1, 0), (0, -1), (1, 0)])): 5,
tuple(sorted([(1, 0), (0, -1)])): 6,
tuple(sorted([(1, 0), (0, -1), (0, 1)])): 7,
tuple(sorted([(1, 0), (-1, 0), (0, 1), (0, -1)])): 8,
}
class Tilemap: class Tilemap:
def __init__(self, game, tile_size=16): def __init__(self, game, tile_size=16):
self.game = game self.game = game
@ -10,6 +25,7 @@ class Tilemap:
for i in range(10): for i in range(10):
self.tilemap[str(3 + i) + ';10'] = {'type': 'grass', 'variant': 1, 'pos': (3 + i, 10)} self.tilemap[str(3 + i) + ';10'] = {'type': 'grass', 'variant': 1, 'pos': (3 + i, 10)}
self.tilemap['10;' + str(5 + i)] = {'type': 'stone', 'variant': 1, 'pos': (10, i + 5)} self.tilemap['10;' + str(5 + i)] = {'type': 'stone', 'variant': 1, 'pos': (10, i + 5)}
def render(self, surface:pg.Surface, offset:tuple=(0,0)): def render(self, surface:pg.Surface, offset:tuple=(0,0)):
for tile in self.offgrid_tiles: for tile in self.offgrid_tiles:
surface.blit(self.game.assets[tile['type']][tile['variant']], (tile['pos'][0] - offset[0], tile['pos'][1] - offset[1])) surface.blit(self.game.assets[tile['type']][tile['variant']], (tile['pos'][0] - offset[0], tile['pos'][1] - offset[1]))
@ -29,9 +45,10 @@ class Tilemap:
check_location = str(tile_location[0] + offset[0]) + ';' + str(tile_location[1] + offset[1]) check_location = str(tile_location[0] + offset[0]) + ';' + str(tile_location[1] + offset[1])
if check_location in self.tilemap: if check_location in self.tilemap:
tiles.append(self.tilemap[check_location]) tiles.append(self.tilemap[check_location])
return tiles return tiles
def physics_rects_around(self, pos): def physics_rects_around(self, pos) -> list:
# Erzeuge eine leere Liste für die Rechtecke # Erzeuge eine leere Liste für die Rechtecke
rects = [] rects = []
# Durchlaufe alle Tiles aus der Umgebung (tiles_around) # Durchlaufe alle Tiles aus der Umgebung (tiles_around)
@ -55,11 +72,44 @@ class Tilemap:
# Gib die Liste der Rechtecke zurück # Gib die Liste der Rechtecke zurück
return rects return rects
# def test(self):
# pass def autotile(self):
# print("Hallo")
# # if __name__ == "__main__": for loc in self.tilemap:
# # from ..game import Game
# # tile = Tilemap(Game()) tile = self.tilemap[loc]
neighbors = set()
for shift in [(1, 0), (-1, 0), (0, -1), (0, 1)]:
check_loc = str(tile['pos'][0] + shift[0]) + ';' + str(tile['pos'][1] + shift[1])
if check_loc in self.tilemap:
if self.tilemap[check_loc]['type'] == tile['type']:
neighbors.add(shift)
neighbors = tuple(sorted(neighbors))
if (tile['type'] in AUTOTILE_TYPES) and (neighbors in AUTOTILE_MAP):
tile['variant'] = AUTOTILE_MAP[neighbors]
def save(self, path):
with open(path, "w") as f:
json.dump({'tilemap': self.tilemap, 'tile_size': self.tile_size, 'offgrid': self.offgrid_tiles}, f)
def load(self, path):
with open(path, "r") as f:
map_data = json.load(f)
self.tilemap = map_data['tilemap']
self.tile_size = map_data['tile_size']
self.offgrid_tiles = map_data['offgrid']