diff --git a/src/Autoloads/Steering.gd b/src/Autoloads/Steering.gd new file mode 100644 index 0000000..46c633b --- /dev/null +++ b/src/Autoloads/Steering.gd @@ -0,0 +1,24 @@ +extends Node + +const DEFAULT_MASS = 2.0 +const DEFAULT_SLOW_RADIUS = 200.0 +const DEFAULT_MAX_SPEED = 300.0 + +func arrive_to(velocity, + position_current, + position_target, + mass=DEFAULT_MASS, + slow_radius=DEFAULT_SLOW_RADIUS, + max_speed=DEFAULT_MAX_SPEED): + """ + Calculates and returns a new velocity with the arrive steering behavior arrived based on + an existing velocity (Vector2), the object's current and target positions (Vector2) + """ + var distance_to_target = position_current.distance_to(position_target) + + var desired_velocity = (position_target - position_current).normalized() * max_speed + if distance_to_target < slow_radius: + desired_velocity *= (distance_to_target / slow_radius) * .75 + .25 + var steering = (desired_velocity - velocity) / mass + + return velocity + steering diff --git a/src/Boss/SlimeBoss/Animations/move_up.png b/src/Boss/SlimeBoss/Animations/move_up.png new file mode 100644 index 0000000..0a12424 Binary files /dev/null and b/src/Boss/SlimeBoss/Animations/move_up.png differ diff --git a/src/Boss/SlimeBoss/Animations/move_up.png.import b/src/Boss/SlimeBoss/Animations/move_up.png.import new file mode 100644 index 0000000..ea4280c --- /dev/null +++ b/src/Boss/SlimeBoss/Animations/move_up.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/move_up.png-2674f54fdbe179d2d3e2767acb2b53b9.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Boss/SlimeBoss/Animations/move_up.png" +dest_files=[ "res://.import/move_up.png-2674f54fdbe179d2d3e2767acb2b53b9.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/src/Boss/SlimeBoss/SlimeBoss.gd b/src/Boss/SlimeBoss/SlimeBoss.gd deleted file mode 100644 index 59e2550..0000000 --- a/src/Boss/SlimeBoss/SlimeBoss.gd +++ /dev/null @@ -1,94 +0,0 @@ -extends KinematicBody2D -class_name SlimeBoss -""" -This is an example player controller script created by Paul -""" -var velocity := Vector2.ZERO -# This is how you export variables with ranges to the editor window -export(bool) var debug := false -export(int, 0, 500) var ACCELERATION := 450 -# Reference for the current player - -onready var player_stats := $Stats -onready var debug_label := $DebugLabel -#onready var animation_player := $AnimationPlayer -#var animation_tree := $AnimationTree -#onready var animation_state = animation_tree.get("parameters/playback") - -enum moveState{ - MOVE, - HIT -} - -var movementState = moveState.MOVE - -var damage_per_second := 0.0 -var totaldamage := 0.0 - -func _debug_update(): - debug_label.text = str(player_stats.health) + "/" + str(player_stats.max_health) + " HP\n" - - -func _physics_process(delta): - totaldamage+=damage_per_second*delta - player_stats.speed+=10*delta - while(totaldamage>1): - totaldamage-=1 - player_stats.health-=1 - while(totaldamage<-1): - totaldamage+=1 - player_stats.health+=1 - _debug_update() - if debug == true: - match movementState: - moveState.MOVE: - movement_move(delta) - moveState.HIT: - movement_hit() - - move() - -# IMPORTANT: If you are using move_and_slide don't multiply by delta -# Godots physics system does that internally -# In move_and_collide(...) you have to multiply by delta. -func move(): - move_and_slide(velocity) - -func movement_move(delta): - var input_vector = Vector2.ZERO - # This is a clever way to handle directional input - # Input.get_action_strength(...) returns a value between 0 and 1 depending - # on how strong the controller direction is pressed - # For keyboards it always returns 1 if pressed and 0 if not - # The actions are custom and defined in the project settings - input_vector.x = Input.get_action_strength("right") - Input.get_action_strength("left") - input_vector.y = Input.get_action_strength("down") - Input.get_action_strength("up") - input_vector = input_vector.normalized() - - if input_vector == Vector2.ZERO: - #animation_state.travel("idle") - velocity = Vector2.ZERO - else: - velocity = velocity.move_toward(player_stats.speed * input_vector, ACCELERATION * delta) - if Input.is_action_just_pressed("roll"): - pass - elif Input.is_action_just_pressed("attack"): - pass - -func movement_hit(): - velocity = Vector2.ZERO - -func hit_finished(): - movementState = moveState.MOVE - -func _on_Stats_no_health(): - queue_free() - - -func _on_Hurtbox_area_entered(area): - player_stats.health-=area.damage - damage_per_second = damage_per_second + area.damage - - -func _on_Hurtbox_area_exited(area): - damage_per_second = damage_per_second - area.damage diff --git a/src/Boss/SlimeBoss/SlimeBoss.tscn b/src/Boss/SlimeBoss/SlimeBoss.tscn index 4c38dd5..c9159f0 100644 --- a/src/Boss/SlimeBoss/SlimeBoss.tscn +++ b/src/Boss/SlimeBoss/SlimeBoss.tscn @@ -1,15 +1,17 @@ -[gd_scene load_steps=16 format=2] +[gd_scene load_steps=29 format=2] [ext_resource path="res://Overlap/HurtHit_Box/Hurtbox.tscn" type="PackedScene" id=1] [ext_resource path="res://Overlap/HurtHit_Box/Hitbox.tscn" type="PackedScene" id=2] [ext_resource path="res://Overlap/Stats/Stats.tscn" type="PackedScene" id=3] -[ext_resource path="res://Boss/SlimeBoss/SlimeBoss.gd" type="Script" id=4] +[ext_resource path="res://Boss/SlimeBoss/SlimeBossStateMachine.gd" type="Script" id=4] [ext_resource path="res://Boss/SlimeBoss/Animations/move_down.png" type="Texture" id=5] [ext_resource path="res://Boss/SlimeBoss/Animations/move_right.png" type="Texture" id=6] -[ext_resource path="res://Boss/SlimeBoss/States/Motion/Idle.gd" type="Script" id=7] -[ext_resource path="res://Boss/SlimeBoss/States/Motion/Stagger.gd" type="Script" id=8] -[ext_resource path="res://Boss/SlimeBoss/States/Motion/Wander.gd" type="Script" id=9] -[ext_resource path="res://Boss/SlimeBoss/States/Motion/SplitUp.gd" type="Script" id=10] +[ext_resource path="res://Boss/SlimeBoss/States/Roam/RoamSequence.gd" type="Script" id=7] +[ext_resource path="res://Boss/SlimeBoss/States/Roam/Wait.gd" type="Script" id=8] +[ext_resource path="res://Boss/SlimeBoss/States/FightStart.gd" type="Script" id=9] +[ext_resource path="res://Boss/SlimeBoss/Animations/move_down_angry.png" type="Texture" id=10] +[ext_resource path="res://Boss/SlimeBoss/Animations/move_up.png" type="Texture" id=11] +[ext_resource path="res://Boss/SlimeBoss/States/Roam/MoveToRandomPosition.gd" type="Script" id=12] [sub_resource type="CapsuleShape2D" id=1] radius = 18.0 @@ -19,13 +21,92 @@ height = 18.0 radius = 18.0 height = 18.0 -[sub_resource type="CapsuleShape2D" id=3] -radius = 8.0 -height = 15.0 +[sub_resource type="CircleShape2D" id=3] +radius = 150.0 -[sub_resource type="Animation" id=4] -resource_name = "MoveDown" -length = 2.65556 +[sub_resource type="CapsuleShape2D" id=4] +radius = 8.0 +height = 32.0 + +[sub_resource type="Animation" id=5] +resource_name = "FightStart" +length = 1.9 +step = 0.025 +tracks/0/type = "value" +tracks/0/path = NodePath("Sprite:texture") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.175, 0.3, 0.65, 0.775, 1.075, 1.2, 1.35, 1.9 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ ExtResource( 5 ), ExtResource( 10 ), ExtResource( 5 ), ExtResource( 10 ), ExtResource( 5 ), ExtResource( 10 ), ExtResource( 5 ), ExtResource( 10 ), ExtResource( 5 ) ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("Sprite:vframes") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 10 ] +} +tracks/2/type = "value" +tracks/2/path = NodePath("Sprite:hframes") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 24 ] +} +tracks/3/type = "value" +tracks/3/path = NodePath("Sprite:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ Vector2( 0, -28 ) ] +} +tracks/4/type = "value" +tracks/4/path = NodePath("Sprite:flip_h") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ false ] +} +tracks/5/type = "value" +tracks/5/path = NodePath("Sprite:frame") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/keys = { +"times": PoolRealArray( 0, 0.025, 0.05, 0.075, 0.1, 0.125, 0.15, 0.175, 0.2, 0.225, 0.25, 0.275, 0.3, 0.325, 0.35, 0.375, 0.4, 0.425, 0.45, 0.475, 0.5, 0.525, 0.55, 0.575, 0.6, 0.625, 0.65, 0.675, 0.7, 0.725, 0.75, 0.775, 0.8, 0.825, 0.85, 0.875, 0.9, 0.925, 0.95, 0.975, 1, 1.025, 1.05, 1.075, 1.1, 1.125, 1.15, 1.175, 1.2, 1.225, 1.25, 1.275, 1.3, 1.325, 1.35, 1.375, 1.4, 1.425, 1.45, 1.475, 1.5, 1.525, 1.55, 1.575, 1.6, 1.625, 1.65, 1.675, 1.7, 1.725, 1.75, 1.775, 1.8, 1.825, 1.85, 1.875 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 0, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] +} + +[sub_resource type="Animation" id=6] +length = 2.66666 loop = true step = 0.0111111 tracks/0/type = "value" @@ -35,10 +116,10 @@ tracks/0/loop_wrap = true tracks/0/imported = false tracks/0/enabled = true tracks/0/keys = { -"times": PoolRealArray( 0, 2.64444 ), -"transitions": PoolRealArray( 1, 1 ), -"update": 0, -"values": [ 0, 237 ] +"times": PoolRealArray( 0, 0.0111111, 0.0222222, 0.0333333, 0.0444444, 0.0555555, 0.0666666, 0.0777777, 0.0888888, 0.0999999, 0.111111, 0.122222, 0.133333, 0.144444, 0.155555, 0.166667, 0.177778, 0.188889, 0.2, 0.211111, 0.222222, 0.233333, 0.244444, 0.255555, 0.266666, 0.277777, 0.288889, 0.3, 0.311111, 0.322222, 0.333333, 0.344444, 0.355555, 0.366666, 0.377777, 0.388889, 0.4, 0.411111, 0.422222, 0.433333, 0.444444, 0.455555, 0.466666, 0.477777, 0.488888, 0.5, 0.511111, 0.522222, 0.533333, 0.544444, 0.555555, 0.566666, 0.577777, 0.588888, 0.599999, 0.611111, 0.622222, 0.633333, 0.644444, 0.655555, 0.666666, 0.677777, 0.688888, 0.699999, 0.71111, 0.722221, 0.733333, 0.744444, 0.755555, 0.766666, 0.777777, 0.788888, 0.799999, 0.81111, 0.822221, 0.833333, 0.844444, 0.855555, 0.866666, 0.877777, 0.888888, 0.899999, 0.91111, 0.922221, 0.933332, 0.944444, 0.955555, 0.966666, 0.977777, 0.988888, 0.999999, 1.01111, 1.02222, 1.03333, 1.04444, 1.05555, 1.06667, 1.07778, 1.08889, 1.1, 1.11111, 1.12222, 1.13333, 1.14444, 1.15555, 1.16667, 1.17778, 1.18889, 1.2, 1.21111, 1.22222, 1.23333, 1.24444, 1.25555, 1.26667, 1.27778, 1.28889, 1.3, 1.31111, 1.32222, 1.33333, 1.34444, 1.35555, 1.36667, 1.37778, 1.38889, 1.4, 1.41111, 1.42222, 1.43333, 1.44444, 1.45555, 1.46667, 1.47778, 1.48889, 1.5, 1.51111, 1.52222, 1.53333, 1.54444, 1.55555, 1.56667, 1.57778, 1.58889, 1.6, 1.61111, 1.62222, 1.63333, 1.64444, 1.65555, 1.66667, 1.67778, 1.68889, 1.7, 1.71111, 1.72222, 1.73333, 1.74444, 1.75555, 1.76666, 1.77778, 1.78889, 1.8, 1.81111, 1.82222, 1.83333, 1.84444, 1.85555, 1.86666, 1.87778, 1.88889, 1.9, 1.91111, 1.92222, 1.93333, 1.94444, 1.95555, 1.96666, 1.97778, 1.98889, 2, 2.01111, 2.02222, 2.03333, 2.04444, 2.05555, 2.06666, 2.07778, 2.08889, 2.1, 2.11111, 2.12222, 2.13333, 2.14444, 2.15555, 2.16666, 2.17778, 2.18889, 2.2, 2.21111, 2.22222, 2.23333, 2.24444, 2.25555, 2.26666, 2.27778, 2.28889, 2.3, 2.31111, 2.32222, 2.33333, 2.34444, 2.35555, 2.36666, 2.37778, 2.38889, 2.4, 2.41111, 2.42222, 2.43333, 2.44444, 2.45555, 2.46666, 2.47778, 2.48889, 2.5, 2.51111, 2.52222, 2.53333, 2.54444, 2.55555, 2.56666, 2.57778, 2.58889, 2.6, 2.61111, 2.62222, 2.63333, 2.64444, 2.65555 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 ] } tracks/1/type = "value" tracks/1/path = NodePath("Sprite:texture") @@ -85,12 +166,23 @@ tracks/4/enabled = true tracks/4/keys = { "times": PoolRealArray( 0 ), "transitions": PoolRealArray( 1 ), -"update": 0, -"values": [ Vector2( 0, -20.142 ) ] +"update": 1, +"values": [ Vector2( 0, -28 ) ] +} +tracks/5/type = "value" +tracks/5/path = NodePath("Sprite:flip_h") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ false ] } -[sub_resource type="Animation" id=5] -resource_name = "MoveRight" +[sub_resource type="Animation" id=7] length = 1.28333 loop = true step = 0.0166667 @@ -101,28 +193,295 @@ tracks/0/loop_wrap = true tracks/0/imported = false tracks/0/enabled = true tracks/0/keys = { -"times": PoolRealArray( 0, 1.26667 ), -"transitions": PoolRealArray( 1, 1 ), -"update": 0, -"values": [ 0, 76 ] +"times": PoolRealArray( 0, 0.0166667, 0.0333334, 0.0500001, 0.0666668, 0.0833335, 0.1, 0.116667, 0.133334, 0.15, 0.166667, 0.183334, 0.2, 0.216667, 0.233334, 0.25, 0.266667, 0.283334, 0.300001, 0.316667, 0.333334, 0.350001, 0.366667, 0.383334, 0.400001, 0.416667, 0.433334, 0.450001, 0.466668, 0.483334, 0.500001, 0.516668, 0.533334, 0.550001, 0.566668, 0.583334, 0.600001, 0.616668, 0.633335, 0.650001, 0.666668, 0.683335, 0.700001, 0.716668, 0.733335, 0.750001, 0.766668, 0.783335, 0.800002, 0.816668, 0.833335, 0.850002, 0.866668, 0.883335, 0.900002, 0.916668, 0.933335, 0.950002, 0.966669, 0.983335, 1, 1.01667, 1.03334, 1.05, 1.06667, 1.08334, 1.1, 1.11667, 1.13334, 1.15, 1.16667, 1.18334, 1.2, 1.21667, 1.23334, 1.25, 1.26667 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("Sprite:texture") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ ExtResource( 6 ) ] +} +tracks/2/type = "value" +tracks/2/path = NodePath("Sprite:vframes") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 7 ] +} +tracks/3/type = "value" +tracks/3/path = NodePath("Sprite:hframes") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 11 ] +} +tracks/4/type = "value" +tracks/4/path = NodePath("Sprite:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ Vector2( 5, -28 ) ] +} +tracks/5/type = "value" +tracks/5/path = NodePath("Sprite:flip_h") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ true ] } +[sub_resource type="Animation" id=8] +length = 1.28333 +loop = true +step = 0.0166667 +tracks/0/type = "value" +tracks/0/path = NodePath("Sprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.0166667, 0.0333334, 0.0500001, 0.0666668, 0.0833335, 0.1, 0.116667, 0.133334, 0.15, 0.166667, 0.183334, 0.2, 0.216667, 0.233334, 0.25, 0.266667, 0.283334, 0.300001, 0.316667, 0.333334, 0.350001, 0.366667, 0.383334, 0.400001, 0.416667, 0.433334, 0.450001, 0.466668, 0.483334, 0.500001, 0.516668, 0.533334, 0.550001, 0.566668, 0.583334, 0.600001, 0.616668, 0.633335, 0.650001, 0.666668, 0.683335, 0.700001, 0.716668, 0.733335, 0.750001, 0.766668, 0.783335, 0.800002, 0.816668, 0.833335, 0.850002, 0.866668, 0.883335, 0.900002, 0.916668, 0.933335, 0.950002, 0.966669, 0.983335, 1, 1.01667, 1.03334, 1.05, 1.06667, 1.08334, 1.1, 1.11667, 1.13334, 1.15, 1.16667, 1.18334, 1.2, 1.21667, 1.23334, 1.25, 1.26667 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("Sprite:texture") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ ExtResource( 6 ) ] +} +tracks/2/type = "value" +tracks/2/path = NodePath("Sprite:vframes") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 7 ] +} +tracks/3/type = "value" +tracks/3/path = NodePath("Sprite:hframes") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 11 ] +} +tracks/4/type = "value" +tracks/4/path = NodePath("Sprite:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ Vector2( -5, -28 ) ] +} +tracks/5/type = "value" +tracks/5/path = NodePath("Sprite:flip_h") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ false ] +} + +[sub_resource type="Animation" id=9] +length = 1.28333 +loop = true +step = 0.0166667 +tracks/0/type = "value" +tracks/0/path = NodePath("Sprite:texture") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ ExtResource( 11 ) ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("Sprite:vframes") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 7 ] +} +tracks/2/type = "value" +tracks/2/path = NodePath("Sprite:hframes") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 11 ] +} +tracks/3/type = "value" +tracks/3/path = NodePath("Sprite:flip_h") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ false ] +} +tracks/4/type = "value" +tracks/4/path = NodePath("Sprite:frame") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/keys = { +"times": PoolRealArray( 0, 0.0166667, 0.0333333, 0.05, 0.0666667, 0.0833333, 0.1, 0.116667, 0.133333, 0.15, 0.166667, 0.183333, 0.2, 0.216667, 0.233333, 0.25, 0.266667, 0.283333, 0.3, 0.316667, 0.333333, 0.35, 0.366667, 0.383333, 0.4, 0.416667, 0.433333, 0.45, 0.466667, 0.483333, 0.5, 0.516667, 0.533333, 0.55, 0.566667, 0.583333, 0.6, 0.616667, 0.633333, 0.65, 0.666667, 0.683333, 0.7, 0.716667, 0.733333, 0.75, 0.766667, 0.783333, 0.8, 0.816667, 0.833333, 0.85, 0.866667, 0.883333, 0.9, 0.916667, 0.933333, 0.95, 0.966667, 0.983333, 1, 1.01667, 1.03333, 1.05, 1.06667, 1.08333, 1.1, 1.11667, 1.13333, 1.15, 1.16667, 1.18333, 1.2, 1.21667, 1.23333, 1.25 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75 ] +} +tracks/5/type = "value" +tracks/5/path = NodePath("Sprite:position") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ Vector2( 0, -28 ) ] +} + +[sub_resource type="AnimationNodeAnimation" id=10] +animation = "MoveRight" + +[sub_resource type="AnimationNodeAnimation" id=11] +animation = "MoveUp" + +[sub_resource type="AnimationNodeAnimation" id=12] +animation = "MoveDown" + +[sub_resource type="AnimationNodeAnimation" id=13] +animation = "MoveLeft" + +[sub_resource type="AnimationNodeBlendSpace2D" id=14] +blend_point_0/node = SubResource( 10 ) +blend_point_0/pos = Vector2( 1, 0 ) +blend_point_1/node = SubResource( 11 ) +blend_point_1/pos = Vector2( 0, -1.1 ) +blend_point_2/node = SubResource( 12 ) +blend_point_2/pos = Vector2( 0, 1.1 ) +blend_point_3/node = SubResource( 13 ) +blend_point_3/pos = Vector2( -1, 0 ) +min_space = Vector2( -1, -1.1 ) +max_space = Vector2( 1, 1.1 ) +blend_mode = 1 + +[sub_resource type="AnimationNodeStateMachine" id=15] +states/move/node = SubResource( 14 ) +states/move/position = Vector2( 143, 70 ) + +[sub_resource type="AnimationNodeStateMachinePlayback" id=16] + [node name="SlimeBoss" type="KinematicBody2D"] -position = Vector2( 168, 128 ) +collision_layer = 4 +collision_mask = 3 script = ExtResource( 4 ) __meta__ = { "_edit_group_": true } +[node name="Stats" parent="." instance=ExtResource( 3 )] +max_health = 3 + +[node name="States" type="Node" parent="."] + +[node name="FightStart" type="Node" parent="States"] +script = ExtResource( 9 ) + +[node name="RoamSequence" type="Node" parent="States"] +script = ExtResource( 7 ) + +[node name="Wait" type="Node" parent="States/RoamSequence"] +script = ExtResource( 8 ) + +[node name="Timer" type="Timer" parent="States/RoamSequence/Wait"] +one_shot = true + +[node name="MoveToRandomPosition" type="Node" parent="States/RoamSequence"] +script = ExtResource( 12 ) + [node name="Sprite" type="Sprite" parent="."] -position = Vector2( -10, -20.142 ) -texture = ExtResource( 6 ) -vframes = 7 -hframes = 11 -frame = 40 +position = Vector2( 0, -28 ) +texture = ExtResource( 5 ) +vframes = 10 +hframes = 24 +frame = 2 [node name="Hitbox" parent="." instance=ExtResource( 2 )] -collision_layer = 0 +visible = false +collision_layer = 4 [node name="CollisionShape2D" parent="Hitbox" index="0"] position = Vector2( 0, -15 ) @@ -136,10 +495,16 @@ collision_mask = 0 position = Vector2( 0, -15 ) shape = SubResource( 2 ) +[node name="HeroCloseZone" type="Area2D" parent="."] +collision_layer = 0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="HeroCloseZone"] +shape = SubResource( 3 ) + [node name="CollisionShape2D" type="CollisionShape2D" parent="."] position = Vector2( -1.52588e-05, 0 ) rotation = 1.5708 -shape = SubResource( 3 ) +shape = SubResource( 4 ) [node name="DebugLabel" type="Label" parent="."] margin_left = -42.2456 @@ -151,30 +516,23 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="Stats" parent="." instance=ExtResource( 3 )] - -[node name="States" type="Node" parent="."] - -[node name="Idle" type="Node" parent="States"] -script = ExtResource( 7 ) - -[node name="Wander" type="Node" parent="States"] -script = ExtResource( 9 ) - -[node name="SplitUp" type="Node" parent="States"] -script = ExtResource( 10 ) - -[node name="Stagger" type="Node" parent="States"] -script = ExtResource( 8 ) - [node name="AnimationPlayer" type="AnimationPlayer" parent="."] autoplay = "MoveRight" -playback_speed = 0.1 -anims/MoveDown = SubResource( 4 ) -anims/MoveRight = SubResource( 5 ) -[connection signal="area_entered" from="Hurtbox" to="." method="_on_Hurtbox_area_entered"] -[connection signal="area_exited" from="Hurtbox" to="." method="_on_Hurtbox_area_exited"] +anims/FightStart = SubResource( 5 ) +anims/MoveDown = SubResource( 6 ) +anims/MoveLeft = SubResource( 7 ) +anims/MoveRight = SubResource( 8 ) +anims/MoveUp = SubResource( 9 ) + +[node name="AnimationTree" type="AnimationTree" parent="."] +tree_root = SubResource( 15 ) +anim_player = NodePath("../AnimationPlayer") +active = true +parameters/playback = SubResource( 16 ) +parameters/move/blend_position = Vector2( 0.210872, 0.275 ) [connection signal="no_health" from="Stats" to="." method="_on_Stats_no_health"] +[connection signal="area_entered" from="Hurtbox" to="." method="_on_Hurtbox_area_entered"] +[connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_finished"] [editable path="Hitbox"] diff --git a/src/Boss/SlimeBoss/SlimeBossStateMachine.gd b/src/Boss/SlimeBoss/SlimeBossStateMachine.gd index d480320..8339fd4 100644 --- a/src/Boss/SlimeBoss/SlimeBossStateMachine.gd +++ b/src/Boss/SlimeBoss/SlimeBossStateMachine.gd @@ -1,9 +1,181 @@ -extends "res://Overlap/StateMachine/StateMachine.gd" +extends KinematicBody2D + +onready var animation_playback = $AnimationTree.get("parameters/playback") +signal target_position_changed +signal state_changed(new_state_name) +signal phase_changed(new_phase_name) + +export(float) var MASS = 8.0 +onready var start_global_position = global_position + +var target_position = Vector2() + +var state_active = null +var sequence_cycles = 0 + +enum PHASES {PHASE_ONE, PHASE_TWO, PHASE_THREE} +export(PHASES) var _phase = PHASES.PHASE_ONE func _ready(): - states_map = { - "idle": $Idle, - "wander": $Wander, - "split_up": $SplitUp, - "stagger": $Stagger - } + print("Hey.") + _change_phase(_phase) + $AnimationPlayer.play("__INIT__") + + # We check if the Player node is a sibling so that we don't get errors + # playing the WildBoar scene + if get_parent().has_node('Player'): + var player_node = get_parent().get_node('Player') + player_node.connect('position_changed', self, '_on_target_position_changed') + target_position = player_node.global_position + + for state_node in $States.get_children(): + state_node.connect('finished', self, '_on_active_state_finished') + go_to_next_state() + + +func _physics_process(delta): + state_active.update(delta) + + +func _on_animation_finished(anim_name): + state_active._on_animation_finished(anim_name) + + +func _on_active_state_finished(): + go_to_next_state() + + +# Well.. guess I'll die. +func _on_Stats_no_health(): + print("dead") + set_invincible(true) + go_to_next_state($States/Die) + + +func go_to_next_state(state_override=null): + if state_active: + state_active.exit() + + if state_override != null: + state_active = state_override + else: + state_active = _decide_on_next_state() + emit_signal("state_changed", state_active.name) + state_active.enter() + + +func _on_Health_health_changed(new_health): + $Tween.interpolate_property($Pivot, 'scale', Vector2(0.92, 1.12), Vector2(1.0, 1.0), 0.3, Tween.TRANS_ELASTIC, Tween.EASE_IN_OUT) + $Tween.interpolate_property($Pivot/Body, 'modulate', Color('#ff48de'), Color('#ffffff'), 0.2, Tween.TRANS_QUINT, Tween.EASE_IN) + $Tween.start() + + if _phase == PHASES.PHASE_ONE and new_health < 100: + _change_phase(PHASES.PHASE_TWO) + if _phase == PHASES.PHASE_TWO and new_health < 50: + _change_phase(PHASES.PHASE_THREE) + + +func _change_phase(new_phase): + var phase_name = "" + match new_phase: + PHASES.PHASE_ONE: + $AnimationPlayer.playback_speed = 1.0 + phase_name = "One" + PHASES.PHASE_TWO: + $AnimationPlayer.playback_speed = 1.4 + phase_name = "Two" + PHASES.PHASE_THREE: + $AnimationPlayer.playback_speed = 1.8 + phase_name = "Three" + + emit_signal("phase_changed", phase_name) + _phase = new_phase + + +# The AI's brain. This function defines the flow of states +# That's a big advantage of the state pattern +# If it grows too big you can swap it with a node +# Or move the flow of states to a data file, like JSON or a text file +func _decide_on_next_state(): + # Battle start + if state_active == null: + set_invincible(true) + return $States/FightStart + if state_active == $States/FightStart: + set_invincible(false) + return $States/RoamSequence + if state_active == $States/RoamSequence: + return $States/FightStart + +# # Death +# if state_active == $States/Die: +# queue_free() +# return $States/Dead +# +# # PHASE ONE +# if _phase == PHASES.PHASE_ONE: +# if state_active == $States/RoamSequence: +# sequence_cycles += 1 +# if sequence_cycles < 2: +# return $States/RoamSequence +# else: +# sequence_cycles = 0 +# return $States/Stomp +# if state_active == $States/Stomp: +# return $States/RoamSequence +# +# # PHASE TWO +# elif _phase == PHASES.PHASE_TWO: +# if state_active == $States/RoamSequence: +# return $States/Stomp +# if state_active == $States/Stomp: +# if sequence_cycles < 2: +# sequence_cycles += 1 +# return $States/Stomp +# else: +# sequence_cycles = 0 +# return $States/ChargeSequence +# if state_active == $States/ChargeSequence: +# return $States/RoamSequence +# +# +# # PHASE THREE +# elif _phase == PHASES.PHASE_THREE: +# if state_active == $States/RoamSequence: +# return $States/Stomp +# if state_active == $States/Stomp: +# if sequence_cycles < 2: +# sequence_cycles += 1 +# return $States/Stomp +# else: +# sequence_cycles = 0 +# return $States/ChargeSequence +# if state_active == $States/ChargeSequence: +# if sequence_cycles < 2: +# sequence_cycles += 1 +# return $States/ChargeSequence +# else: +# sequence_cycles = 0 +# return $States/Stomp + + +# Using a public method makes it so we can change the entire particle setup anytime +func set_particles_active(value): + $DustPuffsLarge.emitting = value + + +# Same thing here, we will likely need more collision shapes in the final version +# So using a function we can group these disabled toggles together +func set_invincible(value): + $CollisionShape2D.disabled = value + $Hitbox/CollisionShape2D.disabled = value + $Hurtbox/CollisionShape2D.disabled = value + + +func _on_target_position_changed(new_position): + target_position = new_position + + +func _on_Hurtbox_area_entered(area): + $Stats.health -= area.damage + diff --git a/src/Boss/SlimeBoss/States/Charge/Prepare.gd b/src/Boss/SlimeBoss/States/Charge/Prepare.gd new file mode 100644 index 0000000..d616208 --- /dev/null +++ b/src/Boss/SlimeBoss/States/Charge/Prepare.gd @@ -0,0 +1,7 @@ +extends "res://Overlap/StateMachine/State.gd" + +func enter(): + owner.get_node('AnimationPlayer').play('prepare') + +func _on_animation_finished(anim_name): + emit_signal('finished') diff --git a/src/Boss/SlimeBoss/States/FightStart.gd b/src/Boss/SlimeBoss/States/FightStart.gd new file mode 100644 index 0000000..b51aa26 --- /dev/null +++ b/src/Boss/SlimeBoss/States/FightStart.gd @@ -0,0 +1,13 @@ +extends "res://Overlap/StateMachine/State.gd" + +onready var animation_player = owner.get_node("AnimationPlayer") +onready var animation_tree = owner.get_node("AnimationTree") + +func enter(): + animation_tree.active = false + animation_player.playback_active = true + animation_player.play('FightStart') + +func _on_animation_finished(anim_name): + assert(anim_name == 'FightStart') + emit_signal('finished') diff --git a/src/Boss/SlimeBoss/States/Motion/Idle.gd b/src/Boss/SlimeBoss/States/Motion/Idle.gd deleted file mode 100644 index 992b176..0000000 --- a/src/Boss/SlimeBoss/States/Motion/Idle.gd +++ /dev/null @@ -1,13 +0,0 @@ -extends "res://Overlap/StateMachine/MotionState.gd" - -func enter(): - owner.get_node("AnimationPlayer").play("MoveDown") # TODO: Replace animation - -func handle_input(event): - return .handle_input(event) - -func update(delta): - var input_direction = get_input_direction() - if input_direction: - # emit_signal("finished", "move") - pass diff --git a/src/Boss/SlimeBoss/States/Motion/SplitUp.gd b/src/Boss/SlimeBoss/States/Motion/SplitUp.gd deleted file mode 100644 index 1eccaec..0000000 --- a/src/Boss/SlimeBoss/States/Motion/SplitUp.gd +++ /dev/null @@ -1,16 +0,0 @@ -extends Node - - -# Declare member variables here. Examples: -# var a = 2 -# var b = "text" - - -# Called when the node enters the scene tree for the first time. -func _ready(): - pass # Replace with function body. - - -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass diff --git a/src/Boss/SlimeBoss/States/Motion/Stagger.gd b/src/Boss/SlimeBoss/States/Motion/Stagger.gd deleted file mode 100644 index 1eccaec..0000000 --- a/src/Boss/SlimeBoss/States/Motion/Stagger.gd +++ /dev/null @@ -1,16 +0,0 @@ -extends Node - - -# Declare member variables here. Examples: -# var a = 2 -# var b = "text" - - -# Called when the node enters the scene tree for the first time. -func _ready(): - pass # Replace with function body. - - -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass diff --git a/src/Boss/SlimeBoss/States/Motion/Wander.gd b/src/Boss/SlimeBoss/States/Motion/Wander.gd deleted file mode 100644 index 1eccaec..0000000 --- a/src/Boss/SlimeBoss/States/Motion/Wander.gd +++ /dev/null @@ -1,16 +0,0 @@ -extends Node - - -# Declare member variables here. Examples: -# var a = 2 -# var b = "text" - - -# Called when the node enters the scene tree for the first time. -func _ready(): - pass # Replace with function body. - - -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass diff --git a/src/Boss/SlimeBoss/States/Roam/MoveToRandomPosition.gd b/src/Boss/SlimeBoss/States/Roam/MoveToRandomPosition.gd new file mode 100644 index 0000000..16908d7 --- /dev/null +++ b/src/Boss/SlimeBoss/States/Roam/MoveToRandomPosition.gd @@ -0,0 +1,34 @@ +extends "res://Overlap/StateMachine/State.gd" + +export(float) var ARRIVE_DISTANCE = 6.0 +export(float) var SLOW_RADIUS = 200.0 +export(float) var MASS = 4.0 +export(float) var MAX_SPEED = 300.0 +export(float) var ROAM_RADIUS = 150.0 + + + +var target_position = Vector2() +var start_position = Vector2() +var velocity = Vector2() + +func enter(): + start_position = get_parent().start_position + target_position = calculate_new_target_position() + owner.get_node('AnimationPlayer').play('move') + + +func update(delta): + velocity = Steering.arrive_to(velocity, owner.global_position, target_position, MASS, SLOW_RADIUS, MAX_SPEED) + owner.move_and_slide(velocity) + + if owner.global_position.distance_to(target_position) < ARRIVE_DISTANCE: + emit_signal('finished') + + +func calculate_new_target_position(): + randomize() + var random_angle = randf() * 2 * PI + randomize() + var random_radius = (randf() * ROAM_RADIUS) / 2 + ROAM_RADIUS / 2 + return start_position + Vector2(cos(random_angle) * random_radius, sin(random_angle) * random_radius) diff --git a/src/Boss/SlimeBoss/States/Roam/RoamSequence.gd b/src/Boss/SlimeBoss/States/Roam/RoamSequence.gd new file mode 100644 index 0000000..3b4087f --- /dev/null +++ b/src/Boss/SlimeBoss/States/Roam/RoamSequence.gd @@ -0,0 +1,15 @@ +extends "res://Overlap/StateMachine/SequenceState.gd" + +var start_position = Vector2() + +func enter(): + start_position = owner.global_position + .enter() + + +func exit(): + .exit() + + +func update(delta): + .update(delta) diff --git a/src/Boss/SlimeBoss/States/Roam/Wait.gd b/src/Boss/SlimeBoss/States/Roam/Wait.gd new file mode 100644 index 0000000..dfc5be8 --- /dev/null +++ b/src/Boss/SlimeBoss/States/Roam/Wait.gd @@ -0,0 +1,12 @@ +extends "res://Overlap/StateMachine/State.gd" + +func enter(): + owner.get_node('AnimationPlayer').play('idle') + $Timer.start() + +func update(delta): + if $Timer.time_left <= 0.0: + emit_signal('finished') + +func exit(): + $Timer.stop() diff --git a/src/Debug/BossStateDisplay.gd b/src/Debug/BossStateDisplay.gd new file mode 100644 index 0000000..41d8ed8 --- /dev/null +++ b/src/Debug/BossStateDisplay.gd @@ -0,0 +1,8 @@ +extends Panel + +func _on_SlimeBoss_state_changed(new_state_name): + $VBoxContainer/State.text = new_state_name + + +func _on_SlimeBoss_phase_changed(new_phase_name): + $VBoxContainer/Phase.text = "Phase: " + new_phase_name diff --git a/src/Maps/Grid.gd b/src/Maps/Grid.gd index 396f8c9..e8c2371 100644 --- a/src/Maps/Grid.gd +++ b/src/Maps/Grid.gd @@ -38,7 +38,7 @@ func _reset_grids(): func _ready(): - var walls = get_tree().current_scene.get_child(1) + var walls = get_tree().current_scene.get_node("FloorTileMap") offset = walls.global_position #todo put in grid_lul for x in range(14): diff --git a/src/Overlap/HurtHit_Box/Hitbox.tscn b/src/Overlap/HurtHit_Box/Hitbox.tscn index 6ca90b2..3642e2c 100644 --- a/src/Overlap/HurtHit_Box/Hitbox.tscn +++ b/src/Overlap/HurtHit_Box/Hitbox.tscn @@ -2,7 +2,9 @@ [ext_resource path="res://Overlap/HurtHit_Box/Hitbox.gd" type="Script" id=1] -[node name="Hitbox" type="Area2D"] +[node name="Hitbox" type="Area2D" groups=[ +"hitbox", +]] script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] diff --git a/src/Overlap/HurtHit_Box/Hurtbox.tscn b/src/Overlap/HurtHit_Box/Hurtbox.tscn index fde26df..143d196 100644 --- a/src/Overlap/HurtHit_Box/Hurtbox.tscn +++ b/src/Overlap/HurtHit_Box/Hurtbox.tscn @@ -2,7 +2,9 @@ [ext_resource path="res://Overlap/HurtHit_Box/Hurtbox.gd" type="Script" id=1] -[node name="Hurtbox" type="Area2D"] +[node name="Hurtbox" type="Area2D" groups=[ +"hurtbox", +]] script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] diff --git a/src/Overlap/StateMachine/SequenceState.gd b/src/Overlap/StateMachine/SequenceState.gd new file mode 100644 index 0000000..e9e68e7 --- /dev/null +++ b/src/Overlap/StateMachine/SequenceState.gd @@ -0,0 +1,41 @@ +extends 'State.gd' + +var state_active = null + + +func _ready(): + for child in get_children(): + child.connect('finished', self, '_on_state_active_finished') + + +func enter(): + state_active = get_child(0) + state_active.enter() + + +func exit(): + state_active = null + + +func update(delta): + state_active.update(delta) + + +func _on_animation_finished(anim_name): + state_active._on_animation_finished(anim_name) + + +func _on_state_active_finished(): + go_to_next_state_in_sequence() + + +func go_to_next_state_in_sequence(): + state_active.exit() + + var new_state_index = (state_active.get_index() + 1) % get_child_count() + if new_state_index == 0: + emit_signal('finished') + return + state_active = get_child(new_state_index) + + state_active.enter() diff --git a/src/Overlap/StateMachine/StateMachine.gd b/src/Overlap/StateMachine/StateMachine.gd index bdf4c42..8c5f9a7 100644 --- a/src/Overlap/StateMachine/StateMachine.gd +++ b/src/Overlap/StateMachine/StateMachine.gd @@ -2,6 +2,7 @@ extends Node signal state_changed(current_state) +export(NodePath) var STATES_COLLECTION = "." export(NodePath) var START_STATE var states_map = {} @@ -9,10 +10,11 @@ var states_stack = [] var current_state = null var _active = false setget set_active + func _ready(): - for child in get_children(): + for child in get_node(STATES_COLLECTION).get_children(): child.connect("finished", self, "change_state") - initialize(START_STATE) + initialize(START_STATE) func initialize(start_state): set_active(true) diff --git a/src/Player/Player.gd b/src/Player/Player.gd index 33c4e3a..176cbd7 100644 --- a/src/Player/Player.gd +++ b/src/Player/Player.gd @@ -174,19 +174,21 @@ func roll_finished(): func _on_Hurtbox_area_entered(area): - player_stats.health -= area.damage - - if area.damage > 0: - damage_per_second += area.damage - else: - heal_per_second += abs(area.damage) + if area.is_in_group("hitbox"): + player_stats.health -= area.damage + + if area.damage > 0: + damage_per_second += area.damage + else: + heal_per_second += abs(area.damage) func _on_Hurtbox_area_exited(area): - if area.damage > 0: - damage_per_second -= area.damage - else: - heal_per_second -= abs(area.damage) + if area.is_in_group("hitbox"): + if area.damage > 0: + damage_per_second -= area.damage + else: + heal_per_second -= abs(area.damage) func _on_Stats_no_health(): diff --git a/src/Player/Player.tscn b/src/Player/Player.tscn index 5247dda..553af83 100644 --- a/src/Player/Player.tscn +++ b/src/Player/Player.tscn @@ -623,7 +623,10 @@ height = 6.99104 size = 12 font_data = ExtResource( 6 ) -[node name="Player" type="KinematicBody2D"] +[node name="Player" type="KinematicBody2D" groups=[ +"hero", +]] +collision_mask = 14 script = ExtResource( 1 ) FRICTION = 270 @@ -637,7 +640,7 @@ scale = Vector2( 0.5, 0.5 ) texture = ExtResource( 2 ) offset = Vector2( 0, -18 ) hframes = 60 -frame = 9 +frame = 12 [node name="Body" type="CollisionShape2D" parent="."] position = Vector2( 0.0107212, 0.0456073 ) @@ -740,6 +743,7 @@ script = ExtResource( 16 ) [node name="Effects" type="Node2D" parent="."] [node name="HealEffect" parent="Effects" instance=ExtResource( 8 )] +emitting = false [connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] [connection signal="area_entered" from="Hurtbox" to="." method="_on_Hurtbox_area_entered"] [connection signal="area_exited" from="Hurtbox" to="." method="_on_Hurtbox_area_exited"] diff --git a/src/World.tscn b/src/World.tscn index ab36bb7..15e1d5b 100644 --- a/src/World.tscn +++ b/src/World.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=2] +[gd_scene load_steps=13 format=2] [ext_resource path="res://Player/Player.tscn" type="PackedScene" id=1] [ext_resource path="res://World.gd" type="Script" id=2] @@ -6,8 +6,11 @@ [ext_resource path="res://testSprites/dark.png" type="Texture" id=4] [ext_resource path="res://Menus/DragNDrop/DragNDropUI.tscn" type="PackedScene" id=5] [ext_resource path="res://Menus/DialogueBox/DialogueBox.tscn" type="PackedScene" id=6] +[ext_resource path="res://Maps/Background/Background.tscn" type="PackedScene" id=7] +[ext_resource path="res://Boss/SlimeBoss/SlimeBoss.tscn" type="PackedScene" id=8] +[ext_resource path="res://Debug/BossStateDisplay.gd" type="Script" id=9] [ext_resource path="res://Objects/Bonfire/Bonfire.tscn" type="PackedScene" id=10] -[ext_resource path="res://Boss/Boss_template.tscn" type="PackedScene" id=17] +[ext_resource path="res://Fonts/Harmonic/Harmonic12.tres" type="DynamicFont" id=11] [ext_resource path="res://Maps/Grid.tscn" type="PackedScene" id=18] [node name="World" type="Node2D"] @@ -19,12 +22,18 @@ texture = ExtResource( 4 ) region_enabled = true region_rect = Rect2( 0, 0, 1280, 720 ) +[node name="Background" parent="." instance=ExtResource( 7 )] +frame = 49 + [node name="FloorTileMap" type="TileMap" parent="."] +visible = false position = Vector2( 16, 16 ) tile_set = ExtResource( 3 ) cell_size = Vector2( 32, 32 ) +collision_layer = 2 +collision_mask = 0 format = 1 -tile_data = PoolIntArray( -1, 47, 4, -65536, 47, 196609, -65535, 47, 196609, -65534, 47, 196609, -65533, 47, 196609, -65532, 47, 196609, -65531, 47, 196609, -65530, 47, 8, -65529, 47, 196609, -65528, 47, 8, -65527, 47, 196609, -65526, 47, 196609, -65525, 47, 196609, -65524, 47, 196609, -65523, 47, 196609, -65522, 47, 7, 65535, 47, 65539, 6, 47, 131075, 8, 47, 131075, 14, 47, 65539, 131071, 47, 65539, 65541, 47, 196611, 65550, 47, 65539, 196607, 47, 65539, 131075, 47, 196608, 131076, 47, 196610, 131086, 47, 65539, 262143, 47, 65539, 196614, 47, 196611, 196622, 47, 65539, 327679, 47, 65539, 262147, 47, 196611, 262149, 47, 196611, 262158, 47, 65539, 393215, 47, 65539, 327684, 47, 196611, 327688, 47, 196611, 327694, 47, 65539, 458751, 47, 65539, 393221, 47, 3, 393225, 47, 3, 393230, 47, 65539, 524287, 47, 196612, 458752, 47, 196609, 458753, 47, 196609, 458754, 47, 196609, 458755, 47, 196609, 458756, 47, 196609, 458757, 47, 196616, 458758, 47, 196609, 458759, 47, 196609, 458760, 47, 196609, 458761, 47, 196616, 458762, 47, 196609, 458763, 47, 196609, 458764, 47, 196609, 458765, 47, 196609, 458766, 47, 196615 ) +tile_data = PoolIntArray( -1, -1610612689, 4, -65536, -1610612689, 196609, -65535, -1610612689, 196609, -65534, -1610612689, 196609, -65533, -1610612689, 196609, -65532, -1610612689, 196609, -65531, -1610612689, 196609, -65530, -1610612689, 196609, -65529, -1610612689, 196609, -65528, -1610612689, 196609, -65527, -1610612689, 196609, -65526, -1610612689, 196609, -65525, -1610612689, 196609, -65524, -1610612689, 196609, -65523, -1610612689, 196610, -65522, -1610612720, 131073, 65535, -1610612689, 65539, 14, -1610612689, 3, 131071, 47, 65539, 65550, -1610612689, 65539, 196607, 47, 65539, 131086, -1610612689, 65539, 262143, 47, 65539, 196622, -1610612689, 65539, 327679, 47, 65539, 262158, -1610612689, 65539, 393215, 47, 65539, 327694, -1610612689, 65539, 458751, -1610612689, 131076, 393216, -1610612689, 1, 393217, -1610612689, 1, 393218, -1610612689, 1, 393219, -1610612689, 1, 393220, -1610612689, 1, 393221, -1610612689, 1, 393222, -1610612689, 1, 393223, -1610612689, 1, 393224, -1610612689, 1, 393225, -1610612689, 1, 393226, -1610612689, 1, 393227, -1610612689, 1, 393228, -1610612689, 1, 393229, -1610612689, 1, 393230, -1610612689, 131079, 524287, -1610612689, 131072, 458752, 47, 131073, 458753, 47, 131073, 458754, 47, 131073, 458755, 47, 131073, 458756, 47, 131073, 458757, 47, 131073, 458758, 47, 131073, 458759, 47, 131073, 458760, 47, 131073, 458761, 47, 131073, 458762, 47, 131073, 458763, 47, 131073, 458764, 47, 131073, 458765, 47, 131073, 458766, -1610612689, 131074 ) __meta__ = { "_edit_group_": true, "_edit_lock_": true @@ -33,18 +42,17 @@ __meta__ = { [node name="YSort" type="YSort" parent="."] [node name="Bonfire" parent="YSort" instance=ExtResource( 10 )] -position = Vector2( 406.635, 139.865 ) +position = Vector2( 265.543, -16 ) [node name="Player" parent="YSort" instance=ExtResource( 1 )] -position = Vector2( 342.83, 130.381 ) +position = Vector2( 344, 125.768 ) scale = Vector2( 2, 2 ) debug = true ROLL_SPEED = 140 FRICTION = 200 -[node name="Boss_template" parent="YSort" instance=ExtResource( 17 )] -position = Vector2( 71.566, 94.4929 ) -debug = true +[node name="SlimeBoss" parent="YSort" instance=ExtResource( 8 )] +position = Vector2( 104, 80 ) [node name="Grid" parent="." instance=ExtResource( 18 )] @@ -58,4 +66,46 @@ margin_top = -0.735092 margin_bottom = -0.735107 ObjectParent = NodePath("../../YSort") -[editable path="YSort/Bonfire"] +[node name="DebugInterface" type="Control" parent="CanvasLayer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="BossStateDisplay" type="Panel" parent="CanvasLayer/DebugInterface"] +anchor_left = 1.0 +anchor_right = 1.0 +margin_left = -80.0 +margin_bottom = 60.0 +script = ExtResource( 9 ) + +[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/DebugInterface/BossStateDisplay"] +margin_right = 40.0 +margin_bottom = 40.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Title" type="Label" parent="CanvasLayer/DebugInterface/BossStateDisplay/VBoxContainer"] +margin_right = 40.0 +margin_bottom = 12.0 +custom_fonts/font = ExtResource( 11 ) +text = "Boss" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Phase" type="Label" parent="CanvasLayer/DebugInterface/BossStateDisplay/VBoxContainer"] +margin_top = 16.0 +margin_right = 40.0 +margin_bottom = 28.0 +custom_fonts/font = ExtResource( 11 ) + +[node name="State" type="Label" parent="CanvasLayer/DebugInterface/BossStateDisplay/VBoxContainer"] +margin_top = 32.0 +margin_right = 40.0 +margin_bottom = 44.0 +custom_fonts/font = ExtResource( 11 ) +[connection signal="phase_changed" from="YSort/SlimeBoss" to="CanvasLayer/DebugInterface/BossStateDisplay" method="_on_SlimeBoss_phase_changed"] +[connection signal="state_changed" from="YSort/SlimeBoss" to="CanvasLayer/DebugInterface/BossStateDisplay" method="_on_SlimeBoss_state_changed"] diff --git a/src/project.godot b/src/project.godot index 2004c48..4492c03 100644 --- a/src/project.godot +++ b/src/project.godot @@ -29,11 +29,6 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://Player/Player.gd" }, { -"base": "KinematicBody2D", -"class": "SlimeBoss", -"language": "GDScript", -"path": "res://Boss/SlimeBoss/SlimeBoss.gd" -}, { "base": "Button", "class": "TitleSceenButton", "language": "GDScript", @@ -49,7 +44,6 @@ _global_script_class_icons={ "DialougeBox": "", "Hero": "", "Player": "", -"SlimeBoss": "", "TitleSceenButton": "", "TitleScreen": "" } @@ -63,6 +57,7 @@ config/icon="res://icon.png" [autoload] SoundControler="*res://Autoloads/SoundControler.gd" +Steering="*res://Autoloads/Steering.gd" [display]