generate level not from code

This commit is contained in:
2026-04-22 17:53:15 +03:00
parent 8a6ecf3f45
commit 029a43fa40
4 changed files with 152 additions and 116 deletions
+104
View File
@@ -0,0 +1,104 @@
[gd_scene format=3 uid="uid://clevel2xm8n4p"]
[ext_resource type="Script" path="res://scripts/Level.gd" id="1_level"]
[sub_resource type="Environment" id="Environment_1"]
background_mode = 1
background_color = Color(0.04, 0.04, 0.08, 1)
ambient_light_source = 2
ambient_light_color = Color(0.35, 0.35, 0.5, 1)
ambient_light_energy = 0.6
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.12, 0.12, 0.18, 1)
roughness = 1.0
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_2"]
albedo_color = Color(0.28, 0.28, 0.42, 1)
roughness = 0.9
metallic = 0.1
[sub_resource type="PlaneMesh" id="PlaneMesh_1"]
size = Vector2(28, 28)
subdivide_width = 8
subdivide_depth = 8
[sub_resource type="BoxShape3D" id="BoxShape3D_1"]
size = Vector3(28, 0.2, 28)
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(30.4, 1.0, 1.2)
[sub_resource type="BoxMesh" id="BoxMesh_2"]
size = Vector3(1.2, 1.0, 28.0)
[sub_resource type="BoxShape3D" id="BoxShape3D_2"]
size = Vector3(30.4, 1.0, 1.2)
[sub_resource type="BoxShape3D" id="BoxShape3D_3"]
size = Vector3(1.2, 1.0, 28.0)
[node name="Level" type="Node3D"]
script = ExtResource("1_level")
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_1")
[node name="Sun" type="DirectionalLight3D" parent="."]
rotation_degrees = Vector3(-55, -25, 0)
light_energy = 1.8
shadow_enabled = true
[node name="Floor" type="MeshInstance3D" parent="."]
mesh = SubResource("PlaneMesh_1")
material_override = SubResource("StandardMaterial3D_1")
[node name="FloorBody" type="StaticBody3D" parent="."]
position = Vector3(0, -0.1, 0)
[node name="CollisionShape3D" type="CollisionShape3D" parent="FloorBody"]
shape = SubResource("BoxShape3D_1")
[node name="WallNorth" type="StaticBody3D" parent="."]
position = Vector3(0, 0.5, -14.6)
metadata/is_wall = true
[node name="Mesh" type="MeshInstance3D" parent="WallNorth"]
mesh = SubResource("BoxMesh_1")
material_override = SubResource("StandardMaterial3D_2")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallNorth"]
shape = SubResource("BoxShape3D_2")
[node name="WallSouth" type="StaticBody3D" parent="."]
position = Vector3(0, 0.5, 14.6)
metadata/is_wall = true
[node name="Mesh" type="MeshInstance3D" parent="WallSouth"]
mesh = SubResource("BoxMesh_1")
material_override = SubResource("StandardMaterial3D_2")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallSouth"]
shape = SubResource("BoxShape3D_2")
[node name="WallEast" type="StaticBody3D" parent="."]
position = Vector3(14.6, 0.5, 0)
metadata/is_wall = true
[node name="Mesh" type="MeshInstance3D" parent="WallEast"]
mesh = SubResource("BoxMesh_2")
material_override = SubResource("StandardMaterial3D_2")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallEast"]
shape = SubResource("BoxShape3D_3")
[node name="WallWest" type="StaticBody3D" parent="."]
position = Vector3(-14.6, 0.5, 0)
metadata/is_wall = true
[node name="Mesh" type="MeshInstance3D" parent="WallWest"]
mesh = SubResource("BoxMesh_2")
material_override = SubResource("StandardMaterial3D_2")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallWest"]
shape = SubResource("BoxShape3D_3")
+29
View File
@@ -0,0 +1,29 @@
extends Node3D
@export var arena_size: float = 14.0
@export var show_grid: bool = true
func _ready() -> void:
if show_grid:
_draw_grid()
func _draw_grid() -> void:
var grid_mat := StandardMaterial3D.new()
grid_mat.albedo_color = Color(0.2, 0.2, 0.3, 0.5)
grid_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
grid_mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
var step := 4.0
var n := int(arena_size / step)
for i in range(-n, n + 1):
for axis in [0, 1]:
var msh := MeshInstance3D.new()
var box := BoxMesh.new()
if axis == 0:
box.size = Vector3(0.05, 0.01, arena_size * 2)
msh.position = Vector3(i * step, 0.005, 0)
else:
box.size = Vector3(arena_size * 2, 0.01, 0.05)
msh.position = Vector3(0, 0.005, i * step)
msh.mesh = box
msh.material_override = grid_mat
add_child(msh)
+1
View File
@@ -0,0 +1 @@
uid://3llsew1f8mgs
+16 -114
View File
@@ -3,15 +3,15 @@ extends Node3D
const PLAYER_SCENE := preload("res://scenes/Player.tscn")
const ENEMY_SCENE := preload("res://scenes/Enemy.tscn")
const ROCK_SCENE := preload("res://scenes/Rock.tscn")
const LEVEL_SCENE := preload("res://scenes/Level.tscn")
const ARENA := 14.0
const WALL_T := 1.2
const CAM_DIST := 8.0
const MOUSE_SENS := 0.18
const PITCH_MIN := 5.0
const PITCH_MAX := 70.0
const SPAWN_TIME := 10
var arena_size: float = 14.0
var cam_yaw: float = 0.0
var cam_pitch: float = 28.0
@@ -38,8 +38,7 @@ var upgrade_panel: Panel
var gameover_panel: Panel
func _ready() -> void:
_create_environment()
_create_arena()
_spawn_level()
_create_camera()
_create_ui()
_spawn_player()
@@ -61,111 +60,14 @@ func _input(event: InputEvent) -> void:
else:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
# ─── Environment ──────────────────────────────────────────────────────────────
# ─── Level ────────────────────────────────────────────────────────────────────
func _create_environment() -> void:
var env := Environment.new()
env.background_mode = Environment.BG_COLOR
env.background_color = Color(0.04, 0.04, 0.08)
env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
env.ambient_light_color = Color(0.35, 0.35, 0.5)
env.ambient_light_energy = 0.6
var we := WorldEnvironment.new()
we.environment = env
add_child(we)
var sun := DirectionalLight3D.new()
sun.rotation_degrees = Vector3(-55, -25, 0)
sun.light_energy = 1.8
sun.shadow_enabled = true
add_child(sun)
# ─── Arena ────────────────────────────────────────────────────────────────────
func _create_arena() -> void:
var floor_mat := StandardMaterial3D.new()
floor_mat.albedo_color = Color(0.12, 0.12, 0.18)
floor_mat.roughness = 1.0
# Floor mesh (visual only)
var fm := MeshInstance3D.new()
var plane := PlaneMesh.new()
plane.size = Vector2(ARENA * 2, ARENA * 2)
plane.subdivide_width = 8
plane.subdivide_depth = 8
fm.mesh = plane
fm.material_override = floor_mat
add_child(fm)
# Floor collider
var fb := StaticBody3D.new()
var fc := CollisionShape3D.new()
var fs := BoxShape3D.new()
fs.size = Vector3(ARENA * 2, 0.2, ARENA * 2)
fc.shape = fs
fb.position.y = -0.1
fb.add_child(fc)
add_child(fb)
# Grid lines on floor
_draw_grid()
# Four walls
var wall_mat := StandardMaterial3D.new()
wall_mat.albedo_color = Color(0.28, 0.28, 0.42)
wall_mat.roughness = 0.9
wall_mat.metallic = 0.1
_make_wall(Vector3(0, 0.5, -(ARENA + WALL_T * 0.5)),
Vector3(ARENA * 2 + WALL_T * 2, 1.0, WALL_T), wall_mat)
_make_wall(Vector3(0, 0.5, (ARENA + WALL_T * 0.5)),
Vector3(ARENA * 2 + WALL_T * 2, 1.0, WALL_T), wall_mat)
_make_wall(Vector3(-(ARENA + WALL_T * 0.5), 0.5, 0),
Vector3(WALL_T, 1.0, ARENA * 2), wall_mat)
_make_wall(Vector3( (ARENA + WALL_T * 0.5), 0.5, 0),
Vector3(WALL_T, 1.0, ARENA * 2), wall_mat)
func _make_wall(pos: Vector3, size: Vector3, mat: StandardMaterial3D) -> void:
var body := StaticBody3D.new()
body.position = pos
body.set_meta("is_wall", true)
var col := CollisionShape3D.new()
var shape := BoxShape3D.new()
shape.size = size
col.shape = shape
body.add_child(col)
var msh := MeshInstance3D.new()
var box := BoxMesh.new()
box.size = size
msh.mesh = box
msh.material_override = mat
body.add_child(msh)
add_child(body)
func _draw_grid() -> void:
# Subtle grid as thin quads
var grid_mat := StandardMaterial3D.new()
grid_mat.albedo_color = Color(0.2, 0.2, 0.3, 0.5)
grid_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
grid_mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
var step := 4.0
var n := int(ARENA / step)
for i in range(-n, n + 1):
for axis in [0, 1]:
var msh := MeshInstance3D.new()
var box := BoxMesh.new()
if axis == 0:
box.size = Vector3(0.05, 0.01, ARENA * 2)
msh.position = Vector3(i * step, 0.005, 0)
else:
box.size = Vector3(ARENA * 2, 0.01, 0.05)
msh.position = Vector3(0, 0.005, i * step)
msh.mesh = box
msh.material_override = grid_mat
add_child(msh)
func _spawn_level() -> void:
var level := LEVEL_SCENE.instantiate()
add_child(level)
var sz = level.get("arena_size")
if sz != null:
arena_size = float(sz)
# ─── Camera ───────────────────────────────────────────────────────────────────
@@ -196,7 +98,7 @@ func _spawn_rocks() -> void:
var rock := ROCK_SCENE.instantiate()
add_child(rock)
var angle := randf() * TAU
var dist := randf_range(3.5, ARENA - 2.0)
var dist := randf_range(3.5, arena_size - 2.0)
rock.position = Vector3(cos(angle) * dist, 0.0, sin(angle) * dist)
# ─── Player ───────────────────────────────────────────────────────────────────
@@ -243,12 +145,12 @@ func _spawn_enemy() -> void:
# Spawn at random edge
var side := randi() % 4
var r := randf_range(-(ARENA - 1.0), ARENA - 1.0)
var r := randf_range(-(arena_size - 1.0), arena_size - 1.0)
match side:
0: enemy.position = Vector3(r, 0, -(ARENA - 0.5))
1: enemy.position = Vector3(r, 0, (ARENA - 0.5))
2: enemy.position = Vector3(-(ARENA - 0.5), 0, r)
3: enemy.position = Vector3( (ARENA - 0.5), 0, r)
0: enemy.position = Vector3(r, 0, -(arena_size - 0.5))
1: enemy.position = Vector3(r, 0, (arena_size - 0.5))
2: enemy.position = Vector3(-(arena_size - 0.5), 0, r)
3: enemy.position = Vector3( (arena_size - 0.5), 0, r)
func add_bonus_score(amount: int) -> void:
score += amount