diff --git a/enemy_spawner.gd b/enemy_spawner.gd index 2155f07..f309865 100644 --- a/enemy_spawner.gd +++ b/enemy_spawner.gd @@ -1,6 +1,7 @@ extends Path3D var clock := 0. +var count := 5.0 func _get_spawn_pos() -> Vector3: return curve.samplef(randf_range(0, curve.point_count)) @@ -15,7 +16,7 @@ func _process(delta: float) -> void: if clock <= 0: clock = 5. var ps: Array[Vector3] - while ps.size() < 5: + while ps.size() < count: var p := _get_spawn_pos() if ps.any(func(_p): return _p.distance_to(p) < 3.): break @@ -23,3 +24,5 @@ func _process(delta: float) -> void: for p in ps: _spawn_police_car(p) + + count += .6 diff --git a/player.gd b/player.gd index 4e324a4..9a59b0b 100644 --- a/player.gd +++ b/player.gd @@ -1,7 +1,14 @@ class_name Player extends CharacterBody3D +enum State { + NORMAL, + DASHING, + LOCKED, +} + const MOVE_SPEED := 5. +const DASH_SPEED := 25. static var instance: Player @@ -17,18 +24,39 @@ var health := 3: if is_node_ready(): %HealthLabel.text = "Health: %d" % v +var state := State.NORMAL +var dash_direction: Vector2 +var stamina := 1.0 + func _init() -> void: instance = self func _ready() -> void: health = health +func _process_stamina(delta: float) -> void: + stamina = move_toward(stamina, 1., delta * 0.2) + %StaminaBar.value = stamina + 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() + if Input.is_action_just_pressed("dash") and stamina >= 1.: + stamina = 0. + dash_direction = input + state = State.DASHING + await get_tree().create_timer(.25, false).timeout + state = State.LOCKED + await get_tree().create_timer(.5, false).timeout + state = State.NORMAL + +func _process_dash() -> void: + velocity = Vector3(dash_direction.x, 0., dash_direction.y) * DASH_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) @@ -48,13 +76,22 @@ func _process_aim() -> void: %Reticle.position = to_mouse_pos -func _process_shoot() -> void: - if Input.is_action_just_pressed("fire"): +var fire_clock := 0. +func _process_shoot(delta: float) -> void: + var clock_mul := 1. + + match state: + State.DASHING: clock_mul = 2.5 + State.LOCKED: clock_mul = 2.5 + + fire_clock -= delta * clock_mul + if Input.is_action_pressed("fire") and fire_clock <= 0.: 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) + fire_clock = 60. / 125. func _process_cam_shake(delta: float) -> void: shake_duration -= delta @@ -72,18 +109,27 @@ func _process_cam_shake(delta: float) -> void: %Camera3D.position += v * .5 func _process(delta: float) -> void: - _process_movement() + match state: + State.NORMAL: _process_movement() + State.DASHING: _process_dash() + State.LOCKED: pass + + _process_aim() - _process_shoot() + _process_shoot(delta) _process_cam_shake(delta) + _process_stamina(delta) damage_clock -= delta -func damage() -> void: - if damage_clock <= 0.: - health -= 1 - damage_clock = 3 - shake_duration = .25 +func damage(damager: Node3D) -> void: + if state == State.DASHING: + damager.queue_free() + else: + if damage_clock <= 0.: + health -= 1 + damage_clock = 3 + shake_duration = .25 - if health == 0: - get_tree().reload_current_scene() + if health == 0: + get_tree().reload_current_scene() diff --git a/player.tscn b/player.tscn index d7fca90..55c904f 100644 --- a/player.tscn +++ b/player.tscn @@ -63,3 +63,26 @@ size_flags_horizontal = 10 theme_override_font_sizes/font_size = 48 text = "Health: 2" horizontal_alignment = 2 + +[node name="StaminaBar" type="ProgressBar" parent="CanvasLayer" unique_id=946230934] +unique_name_in_owner = true +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -103.0 +offset_top = -27.0 +offset_right = 103.0 +grow_horizontal = 2 +grow_vertical = 0 +max_value = 1.0 +show_percentage = false + +[node name="Label" type="Label" parent="CanvasLayer/StaminaBar" unique_id=2033673779] +layout_mode = 0 +offset_left = 65.0 +offset_top = -28.0 +offset_right = 129.0 +offset_bottom = -5.0 +text = "Stamina" diff --git a/player_projectile.gd b/player_projectile.gd index 7655a9d..d2efe9a 100644 --- a/player_projectile.gd +++ b/player_projectile.gd @@ -4,12 +4,17 @@ extends Area3D const SPEED := 20. var _initialized := false var velocity: Vector3 +var health: int = 1: + set(v): + health = v + if v == 0: + queue_free() func _ready() -> void: body_entered.connect(func(body: Node3D): if body.has_method("hit"): body.hit(self) - queue_free() + health -= 1 ) func init(dir: Vector3) -> void: diff --git a/police_car.gd b/police_car.gd index 4ad2e2a..ce724ad 100644 --- a/police_car.gd +++ b/police_car.gd @@ -21,5 +21,5 @@ func hit(_proj: PlayerProjectile): func _on_hurtbox_body_entered(body: Node3D) -> void: if body is Player: - body.damage() + body.damage(self) diff --git a/project.godot b/project.godot index faaf5c0..57559de 100644 --- a/project.godot +++ b/project.godot @@ -21,7 +21,7 @@ SignalBus="*uid://cj4jk5xvv2n3l" [editor_plugins] -enabled=PackedStringArray("res://addons/voronoishatter/plugin.cfg") +enabled=PackedStringArray() [global_group] @@ -54,6 +54,11 @@ fire={ "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) ] } +dash={ +"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":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} [layer_names] diff --git a/world.tscn b/world.tscn index e29819f..02e43a2 100644 --- a/world.tscn +++ b/world.tscn @@ -26,6 +26,10 @@ _data = { } point_count = 5 +[sub_resource type="Environment" id="Environment_tlwt5"] +ambient_light_source = 2 +ambient_light_color = Color(0.76, 0.76, 0.76, 1) + [node name="World" type="Node3D" unique_id=1756877658] [node name="NavigationRegion3D" type="NavigationRegion3D" parent="." unique_id=514937994] @@ -44,7 +48,7 @@ surface_material_override/0 = SubResource("StandardMaterial3D_aqk2v") [node name="Player" parent="." unique_id=1904432250 instance=ExtResource("1_f3sb7")] [node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=570825208] -transform = Transform3D(-0.0140324235, 0.60681456, -0.79471964, -0.7547328, 0.5149172, 0.40649557, 0.65588236, 0.60550505, 0.45075715, 0, 0, 0) +transform = Transform3D(-0.10242973, 0.87742776, -0.4686457, -0.38568807, 0.39923847, 0.83177733, 0.91692597, 0.26594973, 0.2975195, 0, 0, 0) shadow_enabled = true [node name="Block" type="Node3D" parent="." unique_id=2039876952 groups=["navigation_mesh_source_group"]] @@ -338,3 +342,6 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.2965031, 0, 1.1315079) [node name="EnemySpawner" type="Path3D" parent="." unique_id=1620392916] curve = SubResource("Curve3D_036b0") script = ExtResource("4_aqk2v") + +[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=21088355] +environment = SubResource("Environment_tlwt5")