Basic ground enemy AI, crosshair + laser for aiming
This commit is contained in:
parent
be879a03a4
commit
e4893a5cc6
6 changed files with 299 additions and 55 deletions
|
|
@ -6,7 +6,7 @@
|
|||
[ext_resource type="Texture2D" uid="uid://c0cyhybh30ogt" path="res://textures/player-ground-sheet.png" id="4_2c1ag"]
|
||||
[ext_resource type="Texture2D" uid="uid://csrlh1sbdroud" path="res://textures/pistol.png" id="5_8gbjj"]
|
||||
[ext_resource type="AudioStream" uid="uid://5x8fl2mk082h" path="res://sounds/gunshot_1.mp3" id="6_2c1ag"]
|
||||
[ext_resource type="Script" uid="uid://bv7ymrwe6ciax" path="res://scripts/enemy_ground.gd" id="7_modao"]
|
||||
[ext_resource type="Texture2D" uid="uid://coflscl1w4vtr" path="res://textures/crosshair.png" id="7_modao"]
|
||||
[ext_resource type="Shader" uid="uid://d3hoh7ec2w8q7" path="res://scripts/outline.gdshader" id="7_vuhkc"]
|
||||
[ext_resource type="Shader" uid="uid://d2e0541hawkml" path="res://scripts/vignette.gdshader" id="9_5vwr8"]
|
||||
[ext_resource type="Shader" uid="uid://bk7q00br1ms30" path="res://scripts/retro.gdshader" id="9_257nh"]
|
||||
|
|
@ -160,6 +160,15 @@ texture = ExtResource("5_8gbjj")
|
|||
[node name="Gunshot" type="AudioStreamPlayer2D" parent="PlayerGround/HeldItem"]
|
||||
stream = ExtResource("6_2c1ag")
|
||||
|
||||
[node name="Crosshair" type="Sprite2D" parent="PlayerGround/HeldItem"]
|
||||
scale = Vector2(2, 2)
|
||||
texture = ExtResource("7_modao")
|
||||
|
||||
[node name="Line" type="Line2D" parent="PlayerGround/HeldItem"]
|
||||
points = PackedVector2Array(0, 0, 512, 0)
|
||||
width = 2.0
|
||||
default_color = Color(1, 0, 0, 1)
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="PlayerGround"]
|
||||
collision_layer = 2
|
||||
collision_mask = 2
|
||||
|
|
@ -168,43 +177,6 @@ collision_mask = 2
|
|||
shape = SubResource("CapsuleShape2D_8gbjj")
|
||||
debug_color = Color(1, 0, 0, 0.41960785)
|
||||
|
||||
[node name="EnemyTest" type="CharacterBody2D" parent="."]
|
||||
position = Vector2(349, -58)
|
||||
script = ExtResource("7_modao")
|
||||
|
||||
[node name="Sprite" type="AnimatedSprite2D" parent="EnemyTest"]
|
||||
scale = Vector2(2, 2)
|
||||
sprite_frames = SubResource("SpriteFrames_aergo")
|
||||
|
||||
[node name="Camera" type="Camera2D" parent="EnemyTest"]
|
||||
position_smoothing_enabled = true
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape2D" parent="EnemyTest"]
|
||||
position = Vector2(0, 40)
|
||||
shape = SubResource("CapsuleShape2D_176r3")
|
||||
|
||||
[node name="HeldItem" type="Node2D" parent="EnemyTest"]
|
||||
|
||||
[node name="Cast" type="RayCast2D" parent="EnemyTest/HeldItem"]
|
||||
target_position = Vector2(2048, 0)
|
||||
collision_mask = 2
|
||||
collide_with_areas = true
|
||||
|
||||
[node name="Sprite" type="Sprite2D" parent="EnemyTest/HeldItem"]
|
||||
position = Vector2(56, 0)
|
||||
texture = ExtResource("5_8gbjj")
|
||||
|
||||
[node name="Gunshot" type="AudioStreamPlayer2D" parent="EnemyTest/HeldItem"]
|
||||
stream = ExtResource("6_2c1ag")
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="EnemyTest"]
|
||||
collision_layer = 2
|
||||
collision_mask = 2
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape2D" parent="EnemyTest/Hitbox"]
|
||||
shape = SubResource("CapsuleShape2D_8gbjj")
|
||||
debug_color = Color(1, 0, 0, 0.41960785)
|
||||
|
||||
[node name="UI" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="Vignette" type="ColorRect" parent="UI"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=47 format=4 uid="uid://dfjnikjjynj0e"]
|
||||
[gd_scene load_steps=57 format=4 uid="uid://dfjnikjjynj0e"]
|
||||
|
||||
[ext_resource type="AudioStream" uid="uid://dgv01wy8r7ej2" path="res://sounds/uglyburger.mp3" id="1_kpeax"]
|
||||
[ext_resource type="Texture2D" uid="uid://btcap3oh2dqt8" path="res://textures/wall_tile.png" id="2_4uppp"]
|
||||
|
|
@ -20,6 +20,9 @@
|
|||
[ext_resource type="Texture2D" uid="uid://ktvnppfhchoj" path="res://textures/bed.png" id="17_50pdk"]
|
||||
[ext_resource type="Texture2D" uid="uid://cmv4wou5glrl7" path="res://textures/bed_foot.png" id="18_83fjc"]
|
||||
[ext_resource type="Script" uid="uid://cva4b60iqolqy" path="res://scripts/story_handler_1.gd" id="19_akl5n"]
|
||||
[ext_resource type="Script" uid="uid://bv7ymrwe6ciax" path="res://scripts/enemy_ground.gd" id="21_tvsp8"]
|
||||
[ext_resource type="Texture2D" uid="uid://csrlh1sbdroud" path="res://textures/pistol.png" id="22_6l1ru"]
|
||||
[ext_resource type="AudioStream" uid="uid://5x8fl2mk082h" path="res://sounds/gunshot_1.mp3" id="23_janyw"]
|
||||
|
||||
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_vmimc"]
|
||||
light_mode = 1
|
||||
|
|
@ -39,36 +42,65 @@ texture = ExtResource("3_ir5n7")
|
|||
texture_region_size = Vector2i(32, 32)
|
||||
0:0/0 = 0
|
||||
|
||||
[sub_resource type="NavigationPolygon" id="NavigationPolygon_tvsp8"]
|
||||
vertices = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16)
|
||||
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3)])
|
||||
outlines = Array[PackedVector2Array]([PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)])
|
||||
agent_radius = 0.0
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_bhfm6"]
|
||||
texture = ExtResource("4_50pdk")
|
||||
texture_region_size = Vector2i(32, 32)
|
||||
0:0/0 = 0
|
||||
0:0/0/navigation_layer_0/polygon = SubResource("NavigationPolygon_tvsp8")
|
||||
|
||||
[sub_resource type="NavigationPolygon" id="NavigationPolygon_6l1ru"]
|
||||
vertices = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16)
|
||||
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3)])
|
||||
outlines = Array[PackedVector2Array]([PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)])
|
||||
agent_radius = 0.0
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_kl2qk"]
|
||||
texture = ExtResource("5_83fjc")
|
||||
texture_region_size = Vector2i(32, 32)
|
||||
0:0/0 = 0
|
||||
0:0/0/navigation_layer_0/polygon = SubResource("NavigationPolygon_6l1ru")
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_ga4dw"]
|
||||
texture = ExtResource("6_akl5n")
|
||||
texture_region_size = Vector2i(32, 32)
|
||||
0:0/0 = 0
|
||||
|
||||
[sub_resource type="NavigationPolygon" id="NavigationPolygon_janyw"]
|
||||
vertices = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16)
|
||||
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3)])
|
||||
outlines = Array[PackedVector2Array]([PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)])
|
||||
agent_radius = 0.0
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_ir5n7"]
|
||||
texture = ExtResource("7_4uppp")
|
||||
texture_region_size = Vector2i(32, 32)
|
||||
0:0/0 = 0
|
||||
0:0/0/navigation_layer_0/polygon = SubResource("NavigationPolygon_janyw")
|
||||
|
||||
[sub_resource type="NavigationPolygon" id="NavigationPolygon_vmpfq"]
|
||||
vertices = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16)
|
||||
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3)])
|
||||
outlines = Array[PackedVector2Array]([PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)])
|
||||
agent_radius = 0.0
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_50pdk"]
|
||||
texture = ExtResource("8_ir5n7")
|
||||
texture_region_size = Vector2i(32, 32)
|
||||
0:0/0 = 0
|
||||
0:0/0/navigation_layer_0/polygon = SubResource("NavigationPolygon_vmpfq")
|
||||
|
||||
[sub_resource type="TileSet" id="TileSet_uxsmb"]
|
||||
tile_size = Vector2i(32, 32)
|
||||
occlusion_layer_0/light_mask = 1
|
||||
physics_layer_0/collision_layer = 3
|
||||
physics_layer_0/collision_mask = 3
|
||||
navigation_layer_0/layers = 1
|
||||
sources/0 = SubResource("TileSetAtlasSource_k741b")
|
||||
sources/1 = SubResource("TileSetAtlasSource_mdep3")
|
||||
sources/2 = SubResource("TileSetAtlasSource_bhfm6")
|
||||
|
|
@ -200,6 +232,59 @@ size = Vector2(40, 40)
|
|||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_83fjc"]
|
||||
size = Vector2(61.5, 21)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_vmpfq"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_jo68p")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_6gpfv")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_fd1o3")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_yqhs4")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"default",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_jo68p")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"idle",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_6gpfv")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_jo68p")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_fd1o3")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_yqhs4")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"walk",
|
||||
"speed": 7.0
|
||||
}]
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_jxmby"]
|
||||
radius = 21.0
|
||||
height = 48.0
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_tvsp8"]
|
||||
radius = 25.0
|
||||
height = 148.0
|
||||
|
||||
[node name="SpaceStation1" type="Node2D"]
|
||||
|
||||
[node name="Uglyburger" type="AudioStreamPlayer" parent="."]
|
||||
|
|
@ -356,6 +441,50 @@ texture = ExtResource("18_83fjc")
|
|||
position = Vector2(-0.25, 37.5)
|
||||
shape = SubResource("RectangleShape2D_83fjc")
|
||||
|
||||
[node name="EnemyTest" type="CharacterBody2D" parent="."]
|
||||
position = Vector2(-162, -537)
|
||||
script = ExtResource("21_tvsp8")
|
||||
|
||||
[node name="Sprite" type="AnimatedSprite2D" parent="EnemyTest"]
|
||||
scale = Vector2(2, 2)
|
||||
sprite_frames = SubResource("SpriteFrames_vmpfq")
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape2D" parent="EnemyTest"]
|
||||
position = Vector2(0, 40)
|
||||
shape = SubResource("CapsuleShape2D_jxmby")
|
||||
|
||||
[node name="LineOfSight" type="RayCast2D" parent="EnemyTest"]
|
||||
target_position = Vector2(2048, 0)
|
||||
collision_mask = 2
|
||||
collide_with_areas = true
|
||||
|
||||
[node name="HeldItem" type="Node2D" parent="EnemyTest"]
|
||||
|
||||
[node name="Cast" type="RayCast2D" parent="EnemyTest/HeldItem"]
|
||||
target_position = Vector2(2048, 0)
|
||||
collision_mask = 2
|
||||
collide_with_areas = true
|
||||
|
||||
[node name="Sprite" type="Sprite2D" parent="EnemyTest/HeldItem"]
|
||||
position = Vector2(56, 0)
|
||||
texture = ExtResource("22_6l1ru")
|
||||
|
||||
[node name="Gunshot" type="AudioStreamPlayer2D" parent="EnemyTest/HeldItem"]
|
||||
stream = ExtResource("23_janyw")
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="EnemyTest"]
|
||||
collision_layer = 2
|
||||
collision_mask = 2
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape2D" parent="EnemyTest/Hitbox"]
|
||||
shape = SubResource("CapsuleShape2D_tvsp8")
|
||||
debug_color = Color(1, 0, 0, 0.41960785)
|
||||
|
||||
[node name="Navagent" type="NavigationAgent2D" parent="EnemyTest"]
|
||||
path_desired_distance = 34.0
|
||||
target_desired_distance = 34.0
|
||||
path_postprocessing = 1
|
||||
|
||||
[connection signal="body_entered" from="GalactamartWorker/InteractArea" to="GalactamartWorker/InteractArea" method="_on_body_entered"]
|
||||
[connection signal="body_exited" from="GalactamartWorker/InteractArea" to="GalactamartWorker/InteractArea" method="_on_body_exited"]
|
||||
[connection signal="body_entered" from="ExitShip/InteractArea" to="ExitShip/InteractArea" method="_on_body_entered"]
|
||||
|
|
|
|||
|
|
@ -1,32 +1,125 @@
|
|||
extends "res://scripts/character_ground.gd"
|
||||
|
||||
var last_aim_direction = Vector2(0, 0)
|
||||
var alerted = false
|
||||
|
||||
var inaccuracy = 15
|
||||
|
||||
var reaction_time = 0.35
|
||||
var reaction_halve_distance = 720
|
||||
var reaction_timer = 0
|
||||
|
||||
enum {
|
||||
AI_MODE_IDLE,
|
||||
AI_MODE_ATTACK,
|
||||
AI_MODE_SEARCH
|
||||
}
|
||||
|
||||
enum {
|
||||
AI_STATE_DEFAULT,
|
||||
AI_STATE_CHASE,
|
||||
AI_STATE_CHASE_LAST_SEEN
|
||||
}
|
||||
|
||||
var ai_mode = AI_MODE_IDLE
|
||||
var ai_state = AI_STATE_DEFAULT
|
||||
|
||||
var last_seen_player_position = null
|
||||
|
||||
@onready var player = null
|
||||
var game = null
|
||||
|
||||
@export var starting_gun: String = &"pistol"
|
||||
|
||||
@export var starting_health: int = 50
|
||||
|
||||
func _ready() -> void:
|
||||
super()
|
||||
|
||||
health = starting_health
|
||||
|
||||
set_ground_gun(starting_gun)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
super(delta)
|
||||
|
||||
if input_icon.using_gamepad:
|
||||
if !((Input.get_axis("aim_left", "aim_right") == 0) and (Input.get_axis("aim_up", "aim_down") == 0)):
|
||||
$HeldItem.rotation = Vector2(
|
||||
Input.get_axis("aim_left", "aim_right"),
|
||||
Input.get_axis("aim_up", "aim_down")
|
||||
).angle()
|
||||
if !player:
|
||||
if game:
|
||||
player = game.get_node("PlayerGround")
|
||||
else: return
|
||||
|
||||
if ($HeldItem.rotation_degrees < -90) or ($HeldItem.rotation_degrees > 90):
|
||||
$HeldItem/Sprite.scale.y = -1
|
||||
if ai_mode == AI_MODE_IDLE:
|
||||
$LineOfSight.look_at(player.global_position)
|
||||
|
||||
if player.is_ancestor_of($LineOfSight.get_collider()):
|
||||
var divider = clamp((player.global_position - global_position).length() / reaction_halve_distance, 1, 8) * 1.5
|
||||
reaction_timer += delta / divider
|
||||
|
||||
if reaction_time < reaction_timer:
|
||||
ai_mode = AI_MODE_ATTACK
|
||||
reaction_timer = 0
|
||||
else:
|
||||
$HeldItem/Sprite.scale.y = 1
|
||||
else:
|
||||
$HeldItem.look_at(get_global_mouse_position())
|
||||
reaction_timer -= delta
|
||||
|
||||
horizontial_movement = Input.get_axis("ground_left", "ground_right")
|
||||
vertical_movement = Input.get_axis("ground_up", "ground_down")
|
||||
if reaction_timer < 0:
|
||||
reaction_timer = 0
|
||||
|
||||
firing = Input.is_action_pressed("fire")
|
||||
|
||||
elif ai_mode == AI_MODE_ATTACK:
|
||||
$LineOfSight.look_at(player.global_position)
|
||||
if player.is_ancestor_of($LineOfSight.get_collider()):
|
||||
if !$Navagent.target_position or ($Navagent.target_position != player.global_position):
|
||||
$Navagent.target_position = player.global_position
|
||||
|
||||
ai_state = AI_STATE_CHASE
|
||||
elif last_seen_player_position:
|
||||
if !$Navagent.target_position or ($Navagent.target_position != last_seen_player_position):
|
||||
$Navagent.target_position = last_seen_player_position
|
||||
|
||||
ai_state = AI_STATE_CHASE_LAST_SEEN
|
||||
|
||||
$HeldItem.look_at(player.global_position)
|
||||
|
||||
if ai_state == AI_STATE_CHASE:
|
||||
if (player.global_position - global_position).length() > 256:
|
||||
if $Navagent.is_navigation_finished():
|
||||
last_seen_player_position = null
|
||||
ai_mode = AI_MODE_IDLE
|
||||
else:
|
||||
var next_position = $Navagent.get_next_path_position()
|
||||
next_position.y -= 32
|
||||
var axes = global_position.direction_to(next_position)
|
||||
|
||||
horizontial_movement = axes.x
|
||||
vertical_movement = axes.y
|
||||
|
||||
else:
|
||||
horizontial_movement = 0
|
||||
vertical_movement = 0
|
||||
|
||||
reaction_timer += delta
|
||||
|
||||
if reaction_timer > reaction_time:
|
||||
firing = true
|
||||
$HeldItem/Cast.rotation_degrees = randi_range(-inaccuracy, inaccuracy)
|
||||
|
||||
reaction_timer = reaction_time
|
||||
|
||||
last_seen_player_position = player.global_position
|
||||
elif ai_state == AI_STATE_CHASE_LAST_SEEN:
|
||||
if $Navagent.is_navigation_finished():
|
||||
last_seen_player_position = null
|
||||
ai_mode = AI_MODE_IDLE
|
||||
else:
|
||||
var next_position = $Navagent.get_next_path_position()
|
||||
next_position.y -= 32
|
||||
var axes = global_position.direction_to(next_position)
|
||||
|
||||
horizontial_movement = axes.x
|
||||
vertical_movement = axes.y
|
||||
else:
|
||||
reaction_timer -= delta
|
||||
|
||||
if reaction_timer < 0:
|
||||
firing = false
|
||||
reaction_timer = 0
|
||||
|
|
|
|||
|
|
@ -27,4 +27,14 @@ func _process(delta: float) -> void:
|
|||
horizontial_movement = Input.get_axis("ground_left", "ground_right")
|
||||
vertical_movement = Input.get_axis("ground_up", "ground_down")
|
||||
|
||||
if $HeldItem/Cast.get_collision_point():
|
||||
$HeldItem/Crosshair.visible = true
|
||||
$HeldItem/Line.visible = true
|
||||
|
||||
$HeldItem/Crosshair.global_position = $HeldItem/Cast.get_collision_point()
|
||||
$HeldItem/Line.points[1].x = ($HeldItem/Cast.get_collision_point() - global_position).length()
|
||||
else:
|
||||
$HeldItem/Crosshair.visible = false
|
||||
$HeldItem/Line.visible = false
|
||||
|
||||
firing = Input.is_action_pressed("fire")
|
||||
|
|
|
|||
BIN
textures/crosshair.png
Normal file
BIN
textures/crosshair.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 161 B |
40
textures/crosshair.png.import
Normal file
40
textures/crosshair.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://coflscl1w4vtr"
|
||||
path="res://.godot/imported/crosshair.png-226e785e0f22bb09c3ce42bf42008081.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://textures/crosshair.png"
|
||||
dest_files=["res://.godot/imported/crosshair.png-226e785e0f22bb09c3ce42bf42008081.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
|
||||
Loading…
Reference in a new issue