Files
Dunkanoid/Level.gd
2024-05-11 20:50:46 +01:00

129 lines
3.3 KiB
GDScript

@tool
extends SubViewport
class_name Level
signal level_cleared
signal brick_destroyed(brick : Node2D)
var _Brick = preload("res://Brick/Brick.tscn")
var Background : TextureRect
var BricksNode : Node2D
var bricks : Array = []
var level_data : Dictionary = {}
@export var LevelName : String = "DUNKANOID" :
set(x):
LevelName = x
load_level(LevelName)
func _ready() -> void:
size = Vector2(448, 360)
Background = TextureRect.new()
Background.size = Vector2(448, 360)
Background.expand_mode = TextureRect.EXPAND_KEEP_SIZE
Background.stretch_mode = TextureRect.STRETCH_TILE
Background.z_index = -2
add_child(Background)
BricksNode = Node2D.new()
add_child(BricksNode)
load_level(LevelName)
#Background = TextureRect.new()
#Background.size = Vector2(448, 360)
#Background.expand_mode = TextureRect.EXPAND_KEEP_SIZE
#Background.stretch_mode = TextureRect.STRETCH_TILE
#Background.z_index = -2
#add_child(Background)
#
#BricksNode = Node2D.new()
#add_child(BricksNode)
func load_level(level_name : String) -> void:
if FileAccess.file_exists("user://Levels/%s.json" % level_name):
load_from_file("user://Levels/%s.json" % level_name)
return
if FileAccess.file_exists("res://Levels/%s.json" % level_name):
load_from_file("res://Levels/%s.json" % level_name)
return
push_warning("Level %s unknown" % level_name)
func load_from_file(filename : String) -> void:
var data = JSON.parse_string(FileAccess.get_file_as_string(filename))
if data != null:
load_from_data(data)
return
push_warning("Corrupt JSON in %s" % filename)
func load_from_data(data : Dictionary) -> void:
purge_bricks()
level_data = data
Background.texture = load("res://Backgrounds/%s.png" % level_data.background)
Background.modulate = Color("#%s" % level_data.get("tint", "FFFFFF"))
for y in level_data.data.size():
var line : String = level_data.data[y]
for x in line.length():
var c = line.substr(x, 1)
if c == " ":
continue
if not Engine.is_editor_hint():
var brick = _Brick.instantiate()
match c:
"R":
brick.type(Brick.NORMAL, Color.RED)
"G":
brick.type(Brick.NORMAL, Color.GREEN)
"Y":
brick.type(Brick.NORMAL, Color.YELLOW)
"B":
brick.type(Brick.NORMAL, Color.ROYAL_BLUE)
"M":
brick.type(Brick.NORMAL, Color.MAGENTA)
"C":
brick.type(Brick.NORMAL, Color.CYAN)
"W":
brick.type(Brick.NORMAL, Color.WHITE)
"O":
brick.type(Brick.NORMAL, Color.ORANGE)
"s":
brick.type(Brick.SILVER, Color.SILVER)
"g":
brick.type(Brick.GOLD, Color.GOLD)
"i":
brick.type(Brick.INVULNERABLE, Color.GRAY)
brick.position = Vector2(x * 32 + 16 + 16, y * 16 + 8 + 16)
bricks.push_back(brick)
brick.brick_destroyed.connect(_brick_destroyed)
BricksNode.add_child(brick)
func purge_bricks() -> void:
for brick in bricks:
BricksNode.call_deferred("remove_child", brick)
brick.call_deferred("queue_free")
bricks.clear()
func _brick_destroyed(brick : Node2D) -> void:
if brick.my_type != Brick.INVULNERABLE:
brick_destroyed.emit(brick)
bricks.erase(brick)
BricksNode.call_deferred("remove_child", brick)
brick.call_deferred("queue_free")
var brick_count = 0
for abrick in bricks:
if abrick.my_type != Brick.INVULNERABLE:
brick_count += 1
if brick_count == 0:
level_cleared.emit()