155 lines
4.8 KiB
GDScript
155 lines
4.8 KiB
GDScript
class_name Maze
|
|
extends Reference
|
|
|
|
# Represents an area of cell
|
|
var width: int = 0
|
|
var height: int = 0
|
|
var cells = []
|
|
var events = []
|
|
var entrance = Vector2()
|
|
var exit = Vector2()
|
|
var nb_chests: int = 0
|
|
# For submazes, as they modify their parent maze
|
|
var parent: Maze = null # Submaze parent maze
|
|
var offset_x = 0
|
|
var offset_y = 0
|
|
|
|
# Initialize a maze
|
|
func _init(w: int, h: int):
|
|
assert(w > 0)
|
|
assert(h > 0)
|
|
width = w
|
|
height = h
|
|
cells.clear()
|
|
cells.resize(w * h)
|
|
for i in range(w * h):
|
|
cells[i] = Cell.new()
|
|
|
|
# Initialize a submaze from a parent maze.
|
|
func init_from(w: int, h: int, that: Maze, x: int, y: int):
|
|
assert(w > 0)
|
|
assert(h > 0)
|
|
width = w
|
|
height = h
|
|
parent = that
|
|
offset_x = x
|
|
offset_y = y
|
|
|
|
# Get the index for the cell at position (x,y)
|
|
func index(x: int, y: int):
|
|
return x + y * width
|
|
|
|
# Get the cell at the position (x,y)
|
|
func at(x: int, y: int):
|
|
if parent == null:
|
|
return cells[index(x, y)]
|
|
else:
|
|
parent.at(x + offset_x, y + offset_y)
|
|
|
|
# Check if a position is inside the area
|
|
func is_inside(x: int, y: int):
|
|
return (x >= 0) and (x < width) and (y >= 0) and (y < height)
|
|
|
|
# Get a submaze of this maze.
|
|
# The submaze if a view of this maze, so a modification of the submaze cells modify this maze.
|
|
func submaze(x: int, y: int, w: int, h: int):
|
|
assert(x > 0)
|
|
assert(y > 0)
|
|
assert((x + w) <= width)
|
|
assert((y + h) <= height)
|
|
var ret = load("res://tools/maze.gd").new()
|
|
ret.init_from(w, h, self, x, y)
|
|
return ret
|
|
|
|
# Transformations
|
|
# Identity : do nothing
|
|
func identity(_x: int = 0, _y: int = 0, _w: int = width, _h: int = height):
|
|
pass
|
|
|
|
# Horizontal flip
|
|
func horizontal_flip(x: int = 0, y: int = 0, w: int = width, h: int = height):
|
|
if parent == null:
|
|
for j in range(0, h):
|
|
for i in range(0, w/2):
|
|
var idx_cell = index(x + i, y + j)
|
|
var idx_other = index(x + w - 1 - i, y + j)
|
|
var cell = cells[idx_cell]
|
|
cells[idx_cell] = cells[idx_other]
|
|
cells[idx_other] = cell
|
|
for j in range(0, h):
|
|
for i in range(0, w):
|
|
var idx_cell = index(x + i, y + j)
|
|
cells[idx_cell].horizontal_flip()
|
|
else:
|
|
parent.horizontal_flip(offset_x + x, offset_y + y, w, h)
|
|
|
|
# Vertical flip
|
|
func vertical_flip(x: int = 0, y: int = 0, w: int = width, h: int = height):
|
|
if parent == null:
|
|
for j in range(0, h/2):
|
|
for i in range(0, w):
|
|
var idx_cell = index(x + i, y + j)
|
|
var idx_other = index(x + i, y + h - 1 - j)
|
|
var cell = cells[idx_cell]
|
|
cells[idx_cell] = cells[idx_other]
|
|
cells[idx_other] = cell
|
|
for j in range(0, h):
|
|
for i in range(0, w):
|
|
var idx_cell = index(x + i, y + j)
|
|
cells[idx_cell].vertical_flip()
|
|
else:
|
|
parent.vertical_flip(offset_x + x, offset_y + y, w, h)
|
|
|
|
# Rotation 180° = horizontal flip + vertical flip
|
|
func rotate_180(x: int = 0, y: int = 0, w: int = width, h: int = height):
|
|
self.horizontal_flip(x, y, w, h)
|
|
self.vertical_flip(x, y, w, h)
|
|
|
|
# Rotation 90° in trigonometric direction (counter-clockwise)
|
|
func rotate_90():
|
|
# TODO
|
|
pass
|
|
|
|
# Rotation 270° in trigonometric direction (counter-clockwise), or 90° clockwise
|
|
func rotate_270():
|
|
# TODO
|
|
pass
|
|
|
|
# Transposition (mirror -45°)
|
|
func transpose(x: int = 0, y: int = 0, w: int = width, h: int = height):
|
|
if parent == null:
|
|
for j in range(0, h):
|
|
for i in range(j + 1, w):
|
|
var idx_cell = index(x + i, y + j)
|
|
var idx_other = index(y + j, x + i)
|
|
var cell = cells[idx_cell]
|
|
cells[idx_cell] = cells[idx_other]
|
|
cells[idx_other] = cell
|
|
for j in range(0, h):
|
|
for i in range(0, w):
|
|
var idx_cell = index(x + i, y + j)
|
|
cells[idx_cell].transpose()
|
|
else:
|
|
parent.transpose(offset_x + x, offset_y + y, w, h)
|
|
|
|
# Anti-transposition (mirror 45°)
|
|
func antitranspose(x: int = 0, y: int = 0, w: int = width, h: int = height):
|
|
if parent == null:
|
|
for j in range(0, h):
|
|
for i in range(0, w - 1 - j):
|
|
var idx_cell = index(x + i, y + j)
|
|
var idx_other = index(y + h - 1 - j, x + w - 1 - i)
|
|
var cell = cells[idx_cell]
|
|
cells[idx_cell] = cells[idx_other]
|
|
cells[idx_other] = cell
|
|
for j in range(0, h):
|
|
for i in range(0, w):
|
|
var idx_cell = index(x + i, y + j)
|
|
cells[idx_cell].antitranspose()
|
|
else:
|
|
parent.antitranspose(offset_x + x, offset_y + y, w, h)
|
|
|
|
# Player-interaction functions
|
|
func visit(pos: Vector2):
|
|
at(pos.x, pos.y).visited = true
|