diff --git a/src/Boss/Boss_template.tscn b/src/Boss/Boss_template.tscn index 308ca14..f69f5b1 100644 --- a/src/Boss/Boss_template.tscn +++ b/src/Boss/Boss_template.tscn @@ -31,6 +31,7 @@ hframes = 60 [node name="Hitbox" parent="." instance=ExtResource( 2 )] collision_layer = 0 +collision_mask = 65 [node name="CollisionShape2D" parent="Hitbox" index="0"] position = Vector2( 0, -15 ) diff --git a/src/Boss/Minion.gd b/src/Boss/Minion.gd new file mode 100644 index 0000000..711ee35 --- /dev/null +++ b/src/Boss/Minion.gd @@ -0,0 +1,47 @@ +extends KinematicBody2D + +var velocity := Vector2.ZERO + +# This is how you export variables with ranges to the editor window +export(int, 0, 500) var ACCELERATION := 450 +# Reference for the current player + +onready var player_stats := $Stats +onready var debug_label := $DebugLabel + +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" + +# 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 _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() + move() + + +func _on_Stats_no_health(): + queue_free() + + +func _on_Hurtbox_area_entered(area): + player_stats.health -= area.damage + damage_per_second += area.damage + + +func _on_Hurtbox_area_exited(area): + damage_per_second -= area.damage diff --git a/src/Boss/Minion.tscn b/src/Boss/Minion.tscn new file mode 100644 index 0000000..d2fe865 --- /dev/null +++ b/src/Boss/Minion.tscn @@ -0,0 +1,69 @@ +[gd_scene load_steps=10 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/Kind.tscn" type="PackedScene" id=3] +[ext_resource path="res://Overlap/Stats/Stats.tscn" type="PackedScene" id=4] +[ext_resource path="res://testSprites/white_minion_dog.png" type="Texture" id=5] +[ext_resource path="res://Boss/Minion.gd" type="Script" id=6] + +[sub_resource type="CircleShape2D" id=1] +radius = 6.0 + +[sub_resource type="CapsuleShape2D" id=2] +radius = 11.0 +height = 11.0 + +[sub_resource type="CapsuleShape2D" id=3] +radius = 11.0 +height = 11.0 + +[node name="Minion" type="KinematicBody2D"] +script = ExtResource( 6 ) + +[node name="Kind" parent="." instance=ExtResource( 3 )] +kind = 3 + +[node name="Sprite" type="Sprite" parent="."] +position = Vector2( 0, -10.2123 ) +texture = ExtResource( 5 ) +hframes = 60 + +[node name="Body" type="CollisionShape2D" parent="."] +shape = SubResource( 1 ) + +[node name="Hitbox" parent="." instance=ExtResource( 2 )] +collision_layer = 0 +collision_mask = 65 + +[node name="CollisionShape2D" parent="Hitbox" index="0"] +position = Vector2( 0, -9 ) +shape = SubResource( 2 ) + +[node name="Hurtbox" parent="." instance=ExtResource( 1 )] +collision_layer = 8 +collision_mask = 0 + +[node name="CollisionShape2D" parent="Hurtbox" index="0"] +position = Vector2( 0, -9 ) +shape = SubResource( 3 ) + +[node name="DebugLabel" type="Label" parent="."] +margin_left = -50.8637 +margin_top = -41.3944 +margin_right = 51.1363 +margin_bottom = -27.3944 +text = "the white dog" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Stats" parent="." instance=ExtResource( 4 )] +max_health = 2 +[connection signal="area_entered" from="Hurtbox" to="." method="_on_Hurtbox_area_entered"] +[connection signal="area_exited" from="Hurtbox" to="." method="_on_Hurtbox_area_exited"] +[connection signal="no_health" from="Stats" to="." method="_on_Stats_no_health"] + +[editable path="Hitbox"] + +[editable path="Hurtbox"] diff --git a/src/Maps/Grid.gd b/src/Maps/Grid.gd index 396f8c9..19bea11 100644 --- a/src/Maps/Grid.gd +++ b/src/Maps/Grid.gd @@ -99,6 +99,8 @@ func get_nearest(position, kind): for i in prio_grid[x][y]: if(i == kind): list.append([x, y]) + if list.size() == 0: + return[-1,-1] var dist = [] for field in list: var tmp = sqrt(pow(position[0] - field[0], 2) + pow(position[1] - field[1], 2)) diff --git a/src/Objects/Barrel/Barrel.gd b/src/Objects/Barrel/Barrel.gd index 9dad71c..d45e1bf 100644 --- a/src/Objects/Barrel/Barrel.gd +++ b/src/Objects/Barrel/Barrel.gd @@ -6,7 +6,7 @@ var RedDrop = 0.2 var Heart = 0.2 func offset_vec(): - var offset = 20 + var offset = 16 return Vector2((randf()-0.5)*offset, (randf()-0.5)*offset) func _on_Hurtbox_area_entered(area): diff --git a/src/Objects/Bonfire/Bonfire.tscn b/src/Objects/Bonfire/Bonfire.tscn index 24a2e4d..e2291eb 100644 --- a/src/Objects/Bonfire/Bonfire.tscn +++ b/src/Objects/Bonfire/Bonfire.tscn @@ -30,7 +30,7 @@ texture = ExtResource( 3 ) [node name="Hurtbox" parent="." instance=ExtResource( 1 )] position = Vector2( 1.54256, -4.73786 ) -collision_layer = 8 +collision_layer = 64 collision_mask = 0 [node name="CollisionShape2D" parent="Hurtbox" index="0"] diff --git a/src/Objects/Torch/Torch.gd b/src/Objects/Torch/Torch.gd index 31df32b..860acde 100644 --- a/src/Objects/Torch/Torch.gd +++ b/src/Objects/Torch/Torch.gd @@ -1,20 +1,23 @@ extends Node2D export(int, 1, 5) var lifePoints = 3 -export(int, 1, 30) var spawnRate = 5 +export(int, 1, 30) var spawnRate = 5.0 +var Minion = load("res://Boss/Minion.tscn") var elapsedTime = 0.0 +func offset_vec(): + var offset = 16 + return Vector2((randf()-0.5)*offset, (randf()-0.5)*offset) + func _physics_process(delta): elapsedTime += delta - #if(elapsedTime>=spawnRate): - # elapsedTime-=spawnRate - # var Minion = load("") - # var world = get_tree().current_scene.get_child(2) - # #TODO minions - # var minion = Minion.instance() - # world.add_child(minion) - # minion.global_position = global_position + if(elapsedTime>=spawnRate): + elapsedTime-=spawnRate + var world = get_tree().current_scene.get_child(2) + var minion = Minion.instance() + world.add_child(minion) + minion.global_position = global_position+offset_vec() func _on_Hurtbox_area_entered(area): diff --git a/src/Objects/Torch/Torch.tscn b/src/Objects/Torch/Torch.tscn index 72dcad8..73caedf 100644 --- a/src/Objects/Torch/Torch.tscn +++ b/src/Objects/Torch/Torch.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=6 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://Overlap/HurtHit_Box/Hurtbox.tscn" type="PackedScene" id=1] [ext_resource path="res://testSprites/fackel.png" type="Texture" id=2] @@ -13,12 +13,13 @@ height = 12.0 [node name="Torch" type="Node2D"] script = ExtResource( 3 ) -[node name="FireEffect" parent="." instance=ExtResource( 4 )] -position = Vector2( 1.88936, -12.4698 ) [node name="Kind" parent="." instance=ExtResource( 5 )] general = 4 kind = 2 +[node name="FireEffect" parent="." instance=ExtResource( 4 )] +position = Vector2( 1.88936, -12.4698 ) + [node name="Sprite" type="Sprite" parent="."] position = Vector2( 0, -8 ) texture = ExtResource( 2 ) diff --git a/src/Overlap/AI/AI_Hero.gd b/src/Overlap/AI/AI_Hero.gd index 0f53e77..e855dd9 100644 --- a/src/Overlap/AI/AI_Hero.gd +++ b/src/Overlap/AI/AI_Hero.gd @@ -16,6 +16,7 @@ enum{ enum{ STEP, ROLL, + ATTAC, NOTHING } @@ -77,8 +78,8 @@ func calcPrioTable(): #updates heart and bonfire prio func adjustPrio(currentHealth, maxHealth): var prioVal = 40.0 - (float(currentHealth)/float(maxHealth))*40.0 - var bonfire = prioVal - var hearts = prioVal - 1 + var bonfire = prioVal + 1 + var hearts = prioVal if(hearts < 0): hearts = 0 prios[Grid.Kind.BONFIRE]=bonfire @@ -260,53 +261,81 @@ func AStar(source, target): return [NOTHING, [0,0]] +func movement_calulcaotr(): + var currentPosition = grid._pixel_to_grid_coords(global_position) + var calcNew = false + var MoveAdvice + + if(actionFieldUsed==false): + calcNew = true + + if(calcNew==true): + var enemyKind = calcEnemyKind() + if(enemyKind==Grid.Kind.TERMINAL_SYMBOL): + return + actionField = grid.get_nearest(currentPosition, enemyKind) + if(actionField==[-1,-1]): + return + actionFieldUsed = true + + MoveAdvice = getMoveDescription(currentPosition, actionField) + grid.reset_history() + + return MoveAdvice -func makeMove(delta): +func is_hittable(target): + for element in grid.prio_grid[target[0]][target[1]]: + if(element == grid.Kind.BOSS || element == grid.Kind.TORCH || element == grid.Kind.MINION): + return true + return false + +func hit_or_miss(target, current, hitable, delta): + run(Vector2(target[0]-current[0], target[1]-current[1]), delta*8) + attac(Vector2(target[0]-current[0], target[1]-current[1]), delta*4) + return hitable + +func movement_decider_ai(target, kindOfStep, delta): + var currentPosition = grid._pixel_to_grid_coords(global_position) + var field_of_movement = target - #if(actionFieldUsed==true): - # var random = randf() - # if(random < mindChangeProbability): - # ExecutionState = AI_MOVE + var top = [currentPosition[0]+0, currentPosition[1]-1] + var left = [currentPosition[0]-1, currentPosition[1]-0] + var right = [currentPosition[0]+1, currentPosition[1]-0] + var down = [currentPosition[0]+0, currentPosition[1]+1] + var field = [currentPosition[0]+0, currentPosition[1]+0] - if ExecutionState == AI_MOVE: - threadDelta = 0 - var currentPosition = grid._pixel_to_grid_coords(global_position) - var calcNew = false - var target - var MoveAdvice - if(actionFieldUsed==false): - calcNew = true - - if(calcNew==true): - var enemyKind = calcEnemyKind() - if(enemyKind==Grid.Kind.TERMINAL_SYMBOL): - return - target = grid.get_nearest(currentPosition, enemyKind) - actionField = target - actionFieldUsed = true - MoveAdvice = getMoveDescription(currentPosition, target) - else: - MoveAdvice = getMoveDescription(currentPosition, actionField) - grid.reset_history() - - target = MoveAdvice[1] - if(MoveAdvice[0]==STEP): + if(grid._is_in_grid(Vector2(field[0], field[1])) && hit_or_miss(field, currentPosition, is_hittable(field), delta)): + pass + elif(grid._is_in_grid(Vector2(target[0], target[1])) && hit_or_miss(target, currentPosition, is_hittable(target), delta)): + pass + elif(grid._is_in_grid(Vector2(left[0], left[1])) && hit_or_miss(left, currentPosition, is_hittable(left), delta)): + pass + elif(grid._is_in_grid(Vector2(down[0], down[1])) && hit_or_miss(down, currentPosition, is_hittable(down), delta)): + pass + elif(grid._is_in_grid(Vector2(top[0], top[1])) && hit_or_miss(top, currentPosition, is_hittable(top), delta)): + pass + elif(grid._is_in_grid(Vector2(down[0], down[1])) && hit_or_miss(down, currentPosition, is_hittable(down), delta)): + pass + else: + if(kindOfStep==STEP): run(Vector2(target[0]-currentPosition[0], target[1]-currentPosition[1]), delta*4) targetFieldCur = target targetFieldUsed = true ai_movement_state = STEP - elif(MoveAdvice[0]==ROLL): + elif(kindOfStep==ROLL): roll(Vector2(target[0]-currentPosition[0], target[1]-currentPosition[1]), delta*4) targetFieldCur = target targetFieldUsed = true - ExecutionState = EXECUTING - - elif ExecutionState == EXECUTING: - if(targetFieldUsed): + ExecutionState = EXECUTING + + + +func movement_execution(delta): + if(targetFieldUsed): var cur = grid._pixel_to_grid_coords(global_position) var distance = sqrt(pow(cur[0]-targetFieldCur[0],2)+ pow(cur[1]-targetFieldCur[1],2)) - if(distance<0.4): + if(distance<0.01): targetFieldUsed = false ExecutionState = AI_MOVE if(targetFieldCur[0]==actionField[0]&&targetFieldCur[1]==actionField[1]): @@ -317,10 +346,35 @@ func makeMove(delta): run(Vector2(targetFieldCur[0]-currentPosition[0], targetFieldCur[1]-currentPosition[1]), delta*4) elif(ai_movement_state==ROLL): run(Vector2(targetFieldCur[0]-currentPosition[0], targetFieldCur[1]-currentPosition[1]), delta*4) - threadDelta = threadDelta + delta - if(threadDelta>threadTime): - ExecutionState = AI_MOVE - actionFieldUsed = false + + +func reset_exeution_state(delta): + threadDelta = threadDelta + delta + if(threadDelta>threadTime): + ExecutionState = AI_MOVE + actionFieldUsed = false + + + +func makeMove(delta): + + #if(actionFieldUsed==true): + # var random = randf() + # if(random < mindChangeProbability): + # ExecutionState = AI_MOVE + + if ExecutionState == AI_MOVE: + threadDelta = 0 + var MoveAdvice = movement_calulcaotr() + if(MoveAdvice==null): + return + var target = MoveAdvice[1] + movement_decider_ai(target, MoveAdvice[0], delta) + + elif ExecutionState == EXECUTING: + movement_execution(delta) + reset_exeution_state(delta) + # API Interface for ai_hero -> methods are handled in player.gd func attac(direction, delta): @@ -333,3 +387,5 @@ func roll(direction, delta): func run(direction, delta): pass + +#todo diff --git a/src/Player/Player.gd b/src/Player/Player.gd index 33c4e3a..2dd08ff 100644 --- a/src/Player/Player.gd +++ b/src/Player/Player.gd @@ -149,7 +149,8 @@ func movement_hit(): func hit_finished(): movementState = moveState.IDLE - ExecutionState = AI_MOVE + ai_movement_state = STEP + ExecutionState = EXECUTING func movement_roll(): @@ -207,4 +208,4 @@ func movement_run(direction, delta): func movement_idle(): movementState = moveState.IDLE velocity = Vector2.ZERO - animation_state.change_scene("idle") + animation_state.change_state("idle") diff --git a/src/Player/Player.tscn b/src/Player/Player.tscn index 5247dda..662e5c5 100644 --- a/src/Player/Player.tscn +++ b/src/Player/Player.tscn @@ -624,6 +624,7 @@ size = 12 font_data = ExtResource( 6 ) [node name="Player" type="KinematicBody2D"] +scale = Vector2( 1.1, 1.1 ) script = ExtResource( 1 ) FRICTION = 270 @@ -637,7 +638,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 ) @@ -698,7 +699,7 @@ __meta__ = { [node name="SwordHitbox" parent="Pivot" instance=ExtResource( 4 )] collision_layer = 0 -collision_mask = 12 +collision_mask = 76 [node name="CollisionShape2D" parent="Pivot/SwordHitbox" index="0"] position = Vector2( 8.43416, 0.0698299 ) diff --git a/src/World.tscn b/src/World.tscn index b63f362..8906b4d 100644 --- a/src/World.tscn +++ b/src/World.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=2] +[gd_scene load_steps=11 format=2] [ext_resource path="res://Player/Player.tscn" type="PackedScene" id=1] [ext_resource path="res://World.gd" type="Script" id=2] @@ -6,6 +6,7 @@ [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://Objects/Torch/Torch.tscn" type="PackedScene" id=7] [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://Maps/Grid.tscn" type="PackedScene" id=18] @@ -33,18 +34,21 @@ __meta__ = { [node name="YSort" type="YSort" parent="."] position = Vector2( 152, 120 ) -[node name="Bonfire" parent="YSort" instance=ExtResource( 10 )] -position = Vector2( 264, -24 ) - [node name="Player" parent="YSort" instance=ExtResource( 1 )] -position = Vector2( 240, 72 ) +position = Vector2( 200, 8 ) scale = Vector2( 2, 2 ) +debug = true ROLL_SPEED = 140 FRICTION = 200 [node name="Boss_template" parent="YSort" instance=ExtResource( 17 )] -position = Vector2( -67.0889, 2.27742 ) -debug = true +position = Vector2( -56, 8 ) + +[node name="Bonfire" parent="YSort" instance=ExtResource( 10 )] +position = Vector2( 288, 104 ) + +[node name="Torch" parent="YSort" instance=ExtResource( 7 )] +position = Vector2( 264, -40 ) [node name="Grid" parent="." instance=ExtResource( 18 )] diff --git a/src/project.godot b/src/project.godot index 2004c48..92abe87 100644 --- a/src/project.godot +++ b/src/project.godot @@ -147,6 +147,7 @@ attack={ 2d_physics/layer_4="monster" 2d_physics/layer_5="trap" 2d_physics/layer_6="collectable" +2d_physics/layer_7="Bonfire" [rendering] diff --git a/src/testSprites/white_minion_dog.png b/src/testSprites/white_minion_dog.png new file mode 100644 index 0000000..5d01d9a Binary files /dev/null and b/src/testSprites/white_minion_dog.png differ diff --git a/src/testSprites/white_minion_dog.png.import b/src/testSprites/white_minion_dog.png.import new file mode 100644 index 0000000..2a2fd2a --- /dev/null +++ b/src/testSprites/white_minion_dog.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/white_minion_dog.png-4b59df758535e1f8bd50b861a164b220.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://testSprites/white_minion_dog.png" +dest_files=[ "res://.import/white_minion_dog.png-4b59df758535e1f8bd50b861a164b220.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