Tutorial: Hex-Welten#
In diesem Tutorial baust du Schritt für Schritt eine Welt aus Sechsecken. Sechseckige Welten werden für Brettspiele wie Catan verwendet: Landhexfelder, Siedlungen auf Ecken und Straßen auf Kanten.
Wenn du noch nie mit Welten gearbeitet hast, beginne mit dem Kapitel Die erste Welt im interaktiven Kurs.
Schritt 1: Eine Hex-Welt erstellen#
Eine HexWorld wird mit (Spalten, Zeilen) und einer tile_size erstellt:
import miniworlds
world = miniworlds.HexWorld(7, 7, tile_size=40)
world.background.grid = True
world.run()
Hexfelder werden wie Kacheln in einer TiledWorld über (Spalte, Zeile)-Koordinaten angesprochen. Ungerade Zeilen sind um ein halbes Hexfeld nach rechts verschoben.
Schritt 2: Actors auf Hexfeldern platzieren#
Ein Actor, der auf einer Hexfeld-Position platziert wird, wird als Sechseck gezeichnet:
import miniworlds
world = miniworlds.HexWorld(7, 7, tile_size=40)
world.background.grid = True
forest = miniworlds.Actor((2, 3))
forest.fill_color = (0, 120, 0)
desert = miniworlds.Actor((4, 2))
desert.fill_color = (230, 210, 160)
world.run()
Schritt 3: Nachbarn abfragen#
world.get_tile(position) gibt ein einzelnes Hexfeld zurück. tile.get_neighbour_tiles() gibt die bis zu sechs benachbarten Hexfelder zurück.
Das Beispiel färbt das zentrale Hexfeld und alle seine Nachbarn:
import miniworlds
world = miniworlds.HexWorld(7, 7, tile_size=40)
world.background.grid = True
center = world.get_tile((3, 3))
center_actor = miniworlds.Actor(center.position)
center_actor.fill_color = (200, 30, 30)
for tile in center.get_neighbour_tiles():
actor = miniworlds.Actor(tile.position)
actor.fill_color = (0, 120, 0)
world.run()
world.get_tiles_in_radius(position, radius) returns all hexes within
a given hex distance, ordered from the center outwards.
world.get_tiles_in_ring(position, radius) returns only the hexes at
exactly the given distance, in ring traversal order.
Step 4: Move actors from hex to hex#
Actors move from hex to hex with the six hex directions "no", "o",
"so", "sw", "w", and "nw":
import miniworlds
world = miniworlds.HexWorld(7, 7, tile_size=40)
world.background.grid = True
robot = miniworlds.Actor((3, 3))
robot.fill_color = (200, 30, 30)
@robot.register
def act(self):
if world.frame % 20 == 0:
self.move_in_direction("no")
world.run()
Every move_in_direction call moves the actor exactly one hex,
independent of the row parity. The directions can also be given as
degrees: "no" is 30, "o" is 90, "so" is 150, "sw" is 210,
"w" is 270, and "nw" is 330.
Step 5: React to clicks#
With @world.register you can react to mouse clicks.
world.get_tile_from_pixel(mouse_pos) returns the hex under the mouse,
or None if the click is outside the world:
import miniworlds
world = miniworlds.HexWorld(7, 7, tile_size=40)
world.background.grid = True
@world.register
def on_mouse_left(self, mouse_pos):
tile = world.get_tile_from_pixel(mouse_pos)
if tile is None:
return
actor = miniworlds.Actor(tile.position)
actor.fill_color = (0, 120, 0)
world.run()
Step 6: Settlements and roads#
Corners and edges are positions, too.
world.get_corner_from_pixel(mouse_pos) returns the nearest corner,
world.get_edge_from_pixel(mouse_pos) the nearest edge.
Both return None if the pixel is outside the world, for example when
a toolbar or console is attached to the world.
Ein Linksklick platziert eine Siedlung (kleiner Kreis) auf einer Ecke, ein Rechtsklick eine Straße (kleines Rechteck) auf einer Kante:
import miniworlds
world = miniworlds.HexWorld(7, 7, tile_size=40)
world.background.grid = True
@world.register
def on_mouse_left(self, mouse_pos):
corner = world.get_corner_from_pixel(mouse_pos)
settlement = miniworlds.Actor(corner.position)
settlement.fill_color = (200, 30, 30)
settlement.size = (0.3, 0.3)
@world.register
def on_mouse_right(self, mouse_pos):
edge = world.get_edge_from_pixel(mouse_pos)
road = miniworlds.Actor(edge.position)
road.fill_color = (90, 60, 30)
road.size = (0.6, 0.15)
world.run()
Step 7: A mini-Catan board#
Ein Catan-Brett hat 19 Landhexfelder, angeordnet in Zeilen aus 3, 4, 5, 4 und 3 Hexfeldern:
import miniworlds
world = miniworlds.HexWorld(7, 7, tile_size=40)
world.background.grid = True
land_positions = [
(2, 1), (3, 1), (4, 1),
(2, 2), (3, 2), (4, 2), (5, 2),
(1, 3), (2, 3), (3, 3), (4, 3), (5, 3),
(1, 4), (2, 4), (3, 4), (4, 4),
(2, 5), (3, 5), (4, 5),
]
terrain_colors = [
(0, 120, 0), # forest
(220, 180, 60), # field
(120, 200, 60), # meadow
(150, 150, 150), # mountain
(200, 90, 30), # hill
(230, 210, 160), # desert
]
for number, position in enumerate(land_positions):
actor = miniworlds.Actor(position)
actor.fill_color = terrain_colors[number % len(terrain_colors)]
actor.border = 1
world.run()
Von hier aus kannst du im Pattern Hex-Welten und ein Mini-Catan-Brett weitermachen und eigene Spielregeln ergänzen: Würfel, Rohstoffe und Handel sind nicht Teil des Frameworks — sie gehören in deinen Spielcode.
Die vollständige Schnittstelle ist in der HexWorld-API-Referenz dokumentiert.