prototype

This commit is contained in:
Michael Campbell 2026-01-29 14:23:33 -05:00
commit 5bac9ddd2a
33 changed files with 956 additions and 0 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
# Godot 4+ specific ignores
.godot/

15
building.gd Normal file
View file

@ -0,0 +1,15 @@
class_name Building
extends CollisionObject3D
func _ready() -> void:
scale.y = randf_range(.5, 1.25)
func hit(_proj: PlayerProjectile) -> void:
print("boom!")
SignalBus.building_destroyed.emit(self)
collision_layer = 1 # World collision only
%Mesh.hide()
%DestroyedMesh.show()
%GPUParticles3D.preprocess = randf()

1
building.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://bnr37lfj76u7n

125
building.tscn Normal file
View file

@ -0,0 +1,125 @@
[gd_scene format=3 uid="uid://cm86dxphvhbb"]
[ext_resource type="Script" uid="uid://bnr37lfj76u7n" path="res://building.gd" id="1_5j34s"]
[sub_resource type="BoxMesh" id="BoxMesh_rqn35"]
size = Vector3(3, 5, 3)
[sub_resource type="BoxShape3D" id="BoxShape3D_5j34s"]
size = Vector3(3, 5, 3)
[sub_resource type="Gradient" id="Gradient_2yopf"]
offsets = PackedFloat32Array(0.06315789, 0.6421053, 1)
colors = PackedColorArray(0, 0, 0, 1, 0.1, 0.1, 0.1, 1, 0.58, 0.58, 0.58, 1)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_f1gjg"]
gradient = SubResource("Gradient_2yopf")
[sub_resource type="Gradient" id="Gradient_qnfc1"]
offsets = PackedFloat32Array(0.69473684, 1)
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_0rysw"]
gradient = SubResource("Gradient_qnfc1")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_ow2p3"]
emission_shape = 3
emission_box_extents = Vector3(1.575, 0.185, 1.465)
direction = Vector3(0, 1, 0)
spread = 0.0
initial_velocity_min = 3.0
initial_velocity_max = 5.0
gravity = Vector3(0, 0, 0)
scale_min = 0.19999999
scale_max = 0.75
color_ramp = SubResource("GradientTexture1D_0rysw")
color_initial_ramp = SubResource("GradientTexture1D_f1gjg")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_2vvqs"]
transparency = 1
vertex_color_use_as_albedo = true
[sub_resource type="SphereMesh" id="SphereMesh_8evq1"]
material = SubResource("StandardMaterial3D_2vvqs")
[sub_resource type="BoxMesh" id="BoxMesh_5j34s"]
[node name="Building" type="StaticBody3D" unique_id=713127214]
collision_layer = 5
collision_mask = 0
script = ExtResource("1_5j34s")
[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1919101154]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
mesh = SubResource("BoxMesh_rqn35")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1627500046]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
shape = SubResource("BoxShape3D_5j34s")
[node name="DestroyedMesh" type="Node3D" parent="." unique_id=1889390235]
unique_name_in_owner = true
visible = false
[node name="GPUParticles3D" type="GPUParticles3D" parent="DestroyedMesh" unique_id=405124106]
unique_name_in_owner = true
amount = 1
lifetime = 0.5
speed_scale = 0.5
process_material = SubResource("ParticleProcessMaterial_ow2p3")
draw_pass_1 = SubResource("SphereMesh_8evq1")
[node name="Cubez" type="Node3D" parent="DestroyedMesh" unique_id=84909385]
[node name="MeshInstance3D" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=936603106]
transform = Transform3D(-0.020582985, -0.013163342, -0.9997015, 0.53877074, -0.8424524, -2.0764832e-08, -0.84220093, -0.5386099, 0.02443221, 0, 0, 0)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D2" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=1902773756]
transform = Transform3D(0.55269843, 0.35346538, -0.7547096, 0.53877074, -0.8424524, -2.0764832e-08, -0.6358069, -0.40661544, -0.65605897, 0, 0, 0)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D3" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=693829807]
transform = Transform3D(0.55269843, 0.35346538, -0.7547096, 0.53877074, -0.8424524, -2.0764832e-08, -0.6358069, -0.40661544, -0.65605897, -0.5652933, 0, -0.5979067)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D4" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=1318120052]
transform = Transform3D(0.011722982, 0.9259946, -0.37735477, 0.35865596, 0.34837604, 0.86602545, 0.9333962, -0.14549291, -0.32802945, 0.41309977, 0, -0.7827141)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D5" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=1106985548]
transform = Transform3D(0.011722982, 0.9259946, -0.37735477, 0.35865596, 0.34837604, 0.86602545, 0.9333962, -0.14549291, -0.32802945, 0.91316706, 0, -0.43484128)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D6" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=1830889998]
transform = Transform3D(0.011722982, 0.9259946, -0.37735477, 0.35865596, 0.34837604, 0.86602545, 0.9333962, -0.14549291, -0.32802945, -0.90229505, 0, 0.19567871)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D7" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=223786894]
transform = Transform3D(-0.4571105, 0.47059897, -0.7547096, 0.717312, 0.69675213, -2.0764832e-08, 0.5258455, -0.5413622, -0.65605897, -1.4241041, 0, -0.9131663)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D8" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=220079864]
transform = Transform3D(0.55269843, 0.35346538, -0.7547096, 0.53877074, -0.8424524, -2.0764832e-08, -0.6358069, -0.40661544, -0.65605897, 0.5758959, 0, 0.086833715)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D9" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=235651157]
transform = Transform3D(0.55269843, 0.35346538, -0.7547096, 0.53877074, -0.8424524, -2.0764832e-08, -0.6358069, -0.40661544, -0.65605897, 0.94551057, 0, 0.86954826)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D10" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=1163044184]
transform = Transform3D(-0.4571105, 0.47059897, -0.7547096, 0.717312, 0.69675213, -2.0764832e-08, 0.5258455, -0.5413622, -0.65605897, -0.26117355, 0, 0.8586771)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D11" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=804770500]
transform = Transform3D(0.55074334, -0.56699485, -0.61253464, 0.71731204, 0.6967521, 0, 0.42678478, -0.43937847, 0.7904438, -1.022146, 0, 1.0760975)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D12" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=1102483093]
transform = Transform3D(0.55074334, -0.56699485, -0.61253464, 0.71731204, 0.6967521, 0, 0.42678478, -0.43937847, 0.7904438, 0.977854, 0, -0.9239025)
mesh = SubResource("BoxMesh_5j34s")
[node name="MeshInstance3D13" type="MeshInstance3D" parent="DestroyedMesh/Cubez" unique_id=1341429344]
transform = Transform3D(-0.020582985, -0.013163342, -0.9997015, 0.53877074, -0.8424524, -2.0764832e-08, -0.84220093, -0.5386099, 0.02443221, -0.4571221, 0, -1.3370018)
mesh = SubResource("BoxMesh_5j34s")

25
enemy_spawner.gd Normal file
View file

@ -0,0 +1,25 @@
extends Path3D
var clock := 0.
func _get_spawn_pos() -> Vector3:
return curve.samplef(randf_range(0, curve.point_count))
func _spawn_police_car(p: Vector3) -> void:
var car: Node3D = preload("police_car.tscn").instantiate()
car.position = p + Vector3.UP * 0.1
add_sibling(car)
func _process(delta: float) -> void:
clock -= delta
if clock <= 0:
clock = 5.
var ps: Array[Vector3]
while ps.size() < 5:
var p := _get_spawn_pos()
if ps.any(func(_p): return _p.distance_to(p) < 3.):
break
ps.push_back(p)
for p in ps:
_spawn_police_car(p)

1
enemy_spawner.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://hqa4e1vo1gq

1
icon.svg Normal file
View file

@ -0,0 +1 @@
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 813 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H447l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c3 34 55 34 58 0v-86c-3-34-55-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>

After

Width:  |  Height:  |  Size: 949 B

43
icon.svg.import Normal file
View file

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dvlbutpkwnj27"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

0
images/.gdignore Normal file
View file

BIN
images/3d_textures.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

BIN
images/cube_samples.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
images/node_settings.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

8
lifetime.gd Normal file
View file

@ -0,0 +1,8 @@
extends Node
@export var duration := 10.
func _process(delta: float) -> void:
duration -= delta
if duration <= 0:
get_parent().queue_free()

1
lifetime.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://cw8yt6b6jo17n

6
lifetime.tscn Normal file
View file

@ -0,0 +1,6 @@
[gd_scene format=3 uid="uid://yri7p15m8l1u"]
[ext_resource type="Script" uid="uid://cw8yt6b6jo17n" path="res://lifetime.gd" id="1_4m2ci"]
[node name="Lifetime" type="Node" unique_id=631221358]
script = ExtResource("1_4m2ci")

89
player.gd Normal file
View file

@ -0,0 +1,89 @@
class_name Player
extends CharacterBody3D
const MOVE_SPEED := 5.
static var instance: Player
@export var shake_noise: FastNoiseLite
var shake_duration := 0.
@onready var camera_transform: Transform3D = %Camera3D.transform
var damage_clock := 0.
var aim_angle: float
var health := 3:
set(v):
health = v
if is_node_ready():
%HealthLabel.text = "Health: %d" % v
func _init() -> void:
instance = self
func _ready() -> void:
health = health
func _process_movement() -> void:
var input = Input.get_vector("move_left", "move_right", "move_up", "move_down")
input.normalized()
velocity = Vector3(input.x, 0., input.y) * MOVE_SPEED
move_and_slide()
func _process_aim() -> void:
var viewport_mouse_pos := get_viewport().get_mouse_position()
var r_origin: Vector3 = %Camera3D.project_ray_origin(viewport_mouse_pos)
var r_dir: Vector3 = %Camera3D.project_ray_normal(viewport_mouse_pos)
# y = mx + b
# 0 = mx + b
# -b / m = x
var t := -r_origin.y / r_dir.y
var world_mouse_pos = r_origin + r_dir * t
var to_mouse_pos = world_mouse_pos - global_position
var angle = Vector2(to_mouse_pos.x, -to_mouse_pos.z).angle()
%Cannon.rotation.y = angle
aim_angle = angle
%Reticle.position = to_mouse_pos
func _process_shoot() -> void:
if Input.is_action_just_pressed("fire"):
var dir := Vector3.RIGHT.rotated(Vector3.UP, aim_angle)
var player_projectile: PlayerProjectile = preload("player_projectile.tscn").instantiate()
player_projectile.init(dir)
player_projectile.global_position = global_position + Vector3.UP * 0.5
add_sibling(player_projectile)
func _process_cam_shake(delta: float) -> void:
shake_duration -= delta
%Camera3D.transform = camera_transform
if shake_duration <= 0:
return
var x := shake_noise.get_noise_1d(shake_duration * 10000)
var y := shake_noise.get_noise_1d(-shake_duration * 10000)
var v := \
camera_transform.basis.x * x + \
camera_transform.basis.y * y
print("v = ", v)
%Camera3D.position += v * .5
func _process(delta: float) -> void:
_process_movement()
_process_aim()
_process_shoot()
_process_cam_shake(delta)
damage_clock -= delta
func damage() -> void:
if damage_clock <= 0.:
health -= 1
damage_clock = 3
shake_duration = .25
if health == 0:
get_tree().reload_current_scene()

1
player.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://dhin7ux2njfja

65
player.tscn Normal file
View file

@ -0,0 +1,65 @@
[gd_scene format=3 uid="uid://cv5p3w87nk0wn"]
[ext_resource type="Script" uid="uid://dhin7ux2njfja" path="res://player.gd" id="1_4flbx"]
[ext_resource type="Script" uid="uid://cjdxibg3pnans" path="res://score_label.gd" id="2_onrkg"]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_onrkg"]
[sub_resource type="BoxMesh" id="BoxMesh_onrkg"]
[sub_resource type="BoxShape3D" id="BoxShape3D_i3pqv"]
[sub_resource type="BoxMesh" id="BoxMesh_hqtel"]
size = Vector3(2, 0.1, 0.1)
[sub_resource type="SphereMesh" id="SphereMesh_4flbx"]
[node name="Player" type="CharacterBody3D" unique_id=1904432250]
collision_layer = 2
collision_mask = 13
script = ExtResource("1_4flbx")
shake_noise = SubResource("FastNoiseLite_onrkg")
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=204505475]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
mesh = SubResource("BoxMesh_onrkg")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=918462062]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("BoxShape3D_i3pqv")
[node name="Camera3D" type="Camera3D" parent="." unique_id=253280781]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 0.53349644, 0.84580237, 0, -0.84580237, 0.53349644, 0, 20.150661, 11.874705)
[node name="Cannon" type="Node3D" parent="." unique_id=985210791]
unique_name_in_owner = true
[node name="MeshInstance3D" type="MeshInstance3D" parent="Cannon" unique_id=1149215568]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0.75, 0)
mesh = SubResource("BoxMesh_hqtel")
[node name="Reticle" type="MeshInstance3D" parent="." unique_id=242722222]
unique_name_in_owner = true
visible = false
mesh = SubResource("SphereMesh_4flbx")
[node name="CanvasLayer" type="CanvasLayer" parent="." unique_id=1676328708]
[node name="ScoreLabel" type="Label" parent="CanvasLayer" unique_id=1108751125]
offset_right = 40.0
offset_bottom = 23.0
theme_override_font_sizes/font_size = 48
text = "Score: %s"
script = ExtResource("2_onrkg")
[node name="HealthLabel" type="Label" parent="CanvasLayer" unique_id=1653322479]
unique_name_in_owner = true
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 67.0
grow_horizontal = 2
size_flags_horizontal = 10
theme_override_font_sizes/font_size = 48
text = "Health: 2"
horizontal_alignment = 2

23
player_projectile.gd Normal file
View file

@ -0,0 +1,23 @@
class_name PlayerProjectile
extends Area3D
const SPEED := 20.
var _initialized := false
var velocity: Vector3
func _ready() -> void:
body_entered.connect(func(body: Node3D):
if body.has_method("hit"):
body.hit(self)
queue_free()
)
func init(dir: Vector3) -> void:
_initialized = true
velocity = dir * SPEED
func _physics_process(delta: float) -> void:
position += velocity * delta
func _process(_delta: float) -> void:
assert(_initialized)

1
player_projectile.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://c1owlhp4be7wi

24
player_projectile.tscn Normal file
View file

@ -0,0 +1,24 @@
[gd_scene format=3 uid="uid://beruy087nlwfu"]
[ext_resource type="Script" uid="uid://c1owlhp4be7wi" path="res://player_projectile.gd" id="1_0gc0p"]
[ext_resource type="PackedScene" uid="uid://yri7p15m8l1u" path="res://lifetime.tscn" id="2_73r22"]
[sub_resource type="SphereMesh" id="SphereMesh_wqvto"]
radius = 0.25
height = 0.5
[sub_resource type="SphereShape3D" id="SphereShape3D_0gc0p"]
radius = 0.25
[node name="PlayerProjectile" type="Area3D" unique_id=966789634]
collision_layer = 0
collision_mask = 12
script = ExtResource("1_0gc0p")
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=2116862847]
mesh = SubResource("SphereMesh_wqvto")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=908451103]
shape = SubResource("SphereShape3D_0gc0p")
[node name="Lifetime" parent="." unique_id=631221358 instance=ExtResource("2_73r22")]

25
police_car.gd Normal file
View file

@ -0,0 +1,25 @@
class_name PoliceCar
extends CharacterBody3D
@export var dot_curve: Curve
func _physics_process(delta: float) -> void:
%NavAgent.target_position = Player.instance.global_position
var dir := global_position.direction_to(%NavAgent.get_next_path_position())
dir.y = 0
var dot_power := dot_curve.sample(dir.dot(velocity.normalized()))
velocity += dir * 8. * delta * dot_power
velocity = velocity.limit_length(8.)
move_and_slide()
rotation.y = Vector2(velocity.x, -velocity.z).angle()
func hit(_proj: PlayerProjectile):
queue_free()
func _on_hurtbox_body_entered(body: Node3D) -> void:
if body is Player:
body.damage()

1
police_car.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://c6xr2j0g1ep7j

77
police_car.tscn Normal file
View file

@ -0,0 +1,77 @@
[gd_scene format=3 uid="uid://dusfu1hidkmsk"]
[ext_resource type="Script" uid="uid://c6xr2j0g1ep7j" path="res://police_car.gd" id="1_spw8y"]
[sub_resource type="Curve" id="Curve_spw8y"]
_limits = [1.0, 20.0, -1.0, 1.0]
_data = [Vector2(-1, 20), 0.0, 0.0, 0, 0, Vector2(0.20895529, 4.7216473), -18.980904, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
point_count = 3
[sub_resource type="BoxMesh" id="BoxMesh_2kvnc"]
size = Vector3(1, 0.25, 0.5)
[sub_resource type="BoxShape3D" id="BoxShape3D_spw8y"]
size = Vector3(1, 0.25, 0.5)
[sub_resource type="BoxMesh" id="BoxMesh_spw8y"]
size = Vector3(0.1, 0.05, 0.2)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8364l"]
albedo_color = Color(1, 0.32, 0.32, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6u34r"]
albedo_color = Color(0.26, 0.45733315, 1, 1)
[sub_resource type="CylinderMesh" id="CylinderMesh_e8ulu"]
top_radius = 0.1
bottom_radius = 0.1
height = 0.5
[sub_resource type="BoxShape3D" id="BoxShape3D_8364l"]
size = Vector3(1.7734375, 0.5839844, 1.1367188)
[node name="PoliceCar" type="CharacterBody3D" unique_id=206023291]
collision_layer = 8
collision_mask = 15
script = ExtResource("1_spw8y")
dot_curve = SubResource("Curve_spw8y")
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=423323850]
transform = Transform3D(2, 0, 0, 0, 2, 0, 0, 0, 2, -0.122092836, 0.34972915, -0.0012522953)
mesh = SubResource("BoxMesh_2kvnc")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=637101729]
transform = Transform3D(2, 0, 0, 0, 2, 0, 0, 0, 2, -0.122092836, 0.34972915, -0.0012522953)
shape = SubResource("BoxShape3D_spw8y")
[node name="MeshInstance3D4" type="MeshInstance3D" parent="." unique_id=1230197866]
transform = Transform3D(2, 0, 0, 0, 2, 0, 0, 0, 2, 0.59585166, 0.65602696, 0.24429089)
mesh = SubResource("BoxMesh_spw8y")
surface_material_override/0 = SubResource("StandardMaterial3D_8364l")
[node name="MeshInstance3D5" type="MeshInstance3D" parent="." unique_id=100028974]
transform = Transform3D(2, 0, 0, 0, 2, 0, 0, 0, 2, 0.60364604, 0.65602696, -0.23176795)
mesh = SubResource("BoxMesh_spw8y")
surface_material_override/0 = SubResource("StandardMaterial3D_6u34r")
[node name="MeshInstance3D2" type="MeshInstance3D" parent="." unique_id=425081066]
transform = Transform3D(2, 0, 0, 0, -8.742278e-08, -2, 0, 2, -8.742278e-08, -0.8505253, -0.079150766, -0.0012522853)
mesh = SubResource("CylinderMesh_e8ulu")
[node name="MeshInstance3D3" type="MeshInstance3D" parent="." unique_id=1992142361]
transform = Transform3D(2, 0, 0, 0, -8.742278e-08, -2, 0, 2, -8.742278e-08, 0.62777025, -0.079150766, -0.0012522853)
mesh = SubResource("CylinderMesh_e8ulu")
[node name="NavAgent" type="NavigationAgent3D" parent="." unique_id=774393024]
unique_name_in_owner = true
[node name="Hurtbox" type="Area3D" parent="." unique_id=688205599]
collision_layer = 0
collision_mask = 2
[node name="CollisionShape3D" type="CollisionShape3D" parent="Hurtbox" unique_id=192758567]
transform = Transform3D(2, 0, 0, 0, 2, 0, 0, 0, 2, -0.122092836, 0.34972915, -0.0012522953)
shape = SubResource("BoxShape3D_8364l")
debug_color = Color(0.9913104, 0, 0.27320355, 0.41960785)
[connection signal="body_entered" from="Hurtbox" to="." method="_on_hurtbox_body_entered"]

63
project.godot Normal file
View file

@ -0,0 +1,63 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Road Rage Tank"
run/main_scene="uid://civwljgkv3m53"
config/features=PackedStringArray("4.6")
config/icon="res://icon.svg"
[autoload]
SignalBus="*uid://cj4jk5xvv2n3l"
[editor_plugins]
enabled=PackedStringArray("res://addons/voronoishatter/plugin.cfg")
[global_group]
navigation_mesh_source_group=""
[input]
move_left={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
]
}
move_right={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
]
}
move_up={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
]
}
move_down={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
]
}
fire={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(124, 9),"global_position":Vector2(133, 57),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
[layer_names]
3d_physics/layer_1="World"
3d_physics/layer_2="Player"
3d_physics/layer_3="Building"
3d_physics/layer_4="Police"

12
score_label.gd Normal file
View file

@ -0,0 +1,12 @@
extends Label
var score := 0:
set(v):
score = v
text = "Score: %d" % v
func _ready() -> void:
score = score
SignalBus.building_destroyed.connect(func(_building):
score += 10
)

1
score_label.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://cjdxibg3pnans

3
signal_bus.gd Normal file
View file

@ -0,0 +1,3 @@
extends Node
signal building_destroyed(building: Building)

1
signal_bus.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://cj4jk5xvv2n3l

340
world.tscn Normal file

File diff suppressed because one or more lines are too long