213 lines
6.3 KiB
GDScript
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)
|