Files
foxfox/tmp/build_level_scene.gd

213 lines
6.3 KiB
GDScript

extends Node2D
const GROUND_ROW := 18
const GROUND_TOP_Y := GROUND_ROW * 32
func _ready() -> void:
# ---------- TileSet ----------
var ts := TileSet.new()
ts.tile_size = Vector2i(32, 32)
ts.add_physics_layer()
ts.set_physics_layer_collision_layer(0, 1)
ts.set_physics_layer_collision_mask(0, 1)
var src := TileSetAtlasSource.new()
src.texture = load("res://assets/tiles/tiles.png")
src.texture_region_size = Vector2i(32, 32)
src.margins = Vector2i(2, 2)
src.separation = Vector2i(0, 0)
for c in range(4):
for r in range(2):
src.create_tile(Vector2i(c, r))
ts.add_source(src, 0)
# Solid: grass, brick, question block -> full tile-sized polygon
for atlas in [Vector2i(0, 0), Vector2i(1, 0), Vector2i(2, 0)]:
var td: TileData = src.get_tile_data(atlas, 0)
td.set_collision_polygons_count(0, 1)
td.set_collision_polygon_points(0, 0, PackedVector2Array([
Vector2(-16, -16), Vector2(16, -16), Vector2(16, 16), Vector2(-16, 16)
]))
ResourceSaver.save(ts, "res://assets/tiles/tileset_stage2.tres")
# ---------- Root ----------
var root := Node2D.new()
root.name = "Level1"
add_child(root)
# ---------- Ground ----------
var ground := TileMapLayer.new()
ground.name = "Ground"
ground.tile_set = ts
ground.set_collision_enabled(true)
for x in range(60):
ground.set_cell(Vector2i(x, GROUND_ROW), 0, Vector2i(0, 0))
ground.set_cell(Vector2i(x, GROUND_ROW + 1), 0, Vector2i(1, 0))
for spec in [
{"x": 12, "y": GROUND_ROW - 4, "len": 4},
{"x": 20, "y": GROUND_ROW - 6, "len": 3},
{"x": 28, "y": GROUND_ROW - 3, "len": 5},
{"x": 40, "y": GROUND_ROW - 5, "len": 4},
]:
for i in range(spec["len"]):
ground.set_cell(Vector2i(spec["x"] + i, spec["y"]), 0, Vector2i(1, 0))
root.add_child(ground)
# ---------- Fox ----------
var fox := CharacterBody2D.new()
fox.name = "Fox"
fox.set_script(load("res://scripts/player.gd"))
fox.collision_layer = 1
fox.collision_mask = 1
fox.position = Vector2(120, GROUND_TOP_Y - 60.0)
var fox_col := CollisionShape2D.new()
fox_col.name = "CollisionShape2D"
var fox_shape := RectangleShape2D.new()
fox_shape.size = Vector2(24, 40)
fox_col.shape = fox_shape
fox.add_child(fox_col)
root.add_child(fox)
fox.collision_layer = 1
fox.collision_mask = 1
# ---------- Camera ----------
var cam := Camera2D.new()
cam.name = "Camera2D"
cam.position = Vector2(640, GROUND_TOP_Y - 300)
cam.limit_left = 0
cam.limit_right = 1920
cam.limit_top = GROUND_TOP_Y - 720
cam.limit_bottom = GROUND_TOP_Y + 200
cam.position_smoothing_enabled = true
cam.position_smoothing_speed = 8.0
root.add_child(cam)
# ---------- Coins ----------
var coin_i := 0
for p in [Vector2(200, GROUND_TOP_Y - 90), Vector2(240, GROUND_TOP_Y - 90),
Vector2(280, GROUND_TOP_Y - 90), Vector2(420, GROUND_TOP_Y - 170),
Vector2(460, GROUND_TOP_Y - 170), Vector2(900, GROUND_TOP_Y - 120)]:
coin_i += 1
var coin := Area2D.new()
coin.name = "Coin%d" % coin_i
coin.set_script(load("res://scripts/coin.gd"))
coin.collision_layer = 2
coin.collision_mask = 1
coin.position = p
var cs := CollisionShape2D.new()
cs.name = "CollisionShape2D"
var circle := CircleShape2D.new()
circle.radius = 12.0
cs.shape = circle
coin.add_child(cs)
root.add_child(coin)
# ---------- Question blocks ----------
var block_i := 0
for p in [Vector2(320, GROUND_TOP_Y - 116), Vector2(352, GROUND_TOP_Y - 116),
Vector2(560, GROUND_TOP_Y - 116)]:
block_i += 1
var qb := StaticBody2D.new()
qb.name = "QuestionBlock%d" % block_i
qb.set_script(load("res://scripts/question_block.gd"))
qb.collision_layer = 1
qb.collision_mask = 1
qb.position = p
var qcs := CollisionShape2D.new()
qcs.name = "CollisionShape2D"
var qshape := RectangleShape2D.new()
qshape.size = Vector2(32, 32)
qcs.shape = qshape
qb.add_child(qcs)
root.add_child(qb)
qb.collision_layer = 1
qb.collision_mask = 1
# ---------- Breakable bricks ----------
var brick_i := 0
for p in [Vector2(384, GROUND_TOP_Y - 100), Vector2(416, GROUND_TOP_Y - 100),
Vector2(592, GROUND_TOP_Y - 100)]:
brick_i += 1
var br := StaticBody2D.new()
br.name = "Brick%d" % brick_i
br.set_script(load("res://scripts/breakable_block.gd"))
br.collision_layer = 1
br.collision_mask = 1
br.position = p
var bcs := CollisionShape2D.new()
bcs.name = "CollisionShape2D"
var bshape := RectangleShape2D.new()
bshape.size = Vector2(32, 32)
bcs.shape = bshape
br.add_child(bcs)
root.add_child(br)
br.collision_layer = 1
br.collision_mask = 1
# ---------- Win zone (right end) ----------
var win_zone := Area2D.new()
win_zone.name = "WinZone"
win_zone.collision_layer = 4
win_zone.collision_mask = 1
var wzcs := CollisionShape2D.new()
wzcs.name = "CollisionShape2D"
var wzshape := RectangleShape2D.new()
wzshape.size = Vector2(48, 200)
wzcs.shape = wzshape
win_zone.add_child(wzcs)
win_zone.position = Vector2(580, GROUND_TOP_Y - 100)
win_zone.body_entered.connect(_on_body_entered)
root.add_child(win_zone)
# ---------- Spawn point indicator ----------
var spawn := Node2D.new()
spawn.name = "SpawnPoint"
spawn.position = Vector2(120, GROUND_TOP_Y - 20.0)
root.add_child(spawn)
# ---------- HUD ----------
var hud := CanvasLayer.new()
hud.name = "HUD"
hud.set_script(load("res://scripts/hud.gd"))
var top := Node2D.new()
top.name = "Top"
hud.add_child(top)
var score_label := Label.new()
score_label.name = "ScoreLabel"
score_label.position = Vector2(16, 16)
score_label.add_theme_font_size_override("font_size", 24.0)
top.add_child(score_label)
var lives_label := Label.new()
lives_label.name = "LivesLabel"
lives_label.position = Vector2(16, 44)
lives_label.add_theme_font_size_override("font_size", 24.0)
top.add_child(lives_label)
var time_label := Label.new()
time_label.name = "TimeLabel"
time_label.position = Vector2(1000, 16)
time_label.add_theme_font_size_override("font_size", 24.0)
top.add_child(time_label)
root.add_child(hud)
_assign_owner(root, root)
var packed := PackedScene.new()
print("pack err=", packed.pack(root))
print("save err=", ResourceSaver.save(packed, "res://scenes/level/level_1.tscn"))
get_tree().quit()
func _on_body_entered(body: Node) -> void:
if body.is_class("CharacterBody2D"):
GameManager.win()
func _assign_owner(node: Node, scene_root: Node) -> void:
for child in node.get_children():
child.owner = scene_root
_assign_owner(child, scene_root)