From f9c1f1380dcfeb977405c0ca290fd917532a7d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20H=C3=BCbner?= Date: Tue, 15 Aug 2017 14:47:41 +0200 Subject: [PATCH] bad coll avoidance --- Asteroid.tscn | 4 +-- EnemyGrunt.gd | 18 +++++++--- EnemyGrunt.tscn | 68 ++++++++++++++++++++++++++++++++++++-- Game.tscn | 87 ++++++++++++++++++++++++++++++++++++++++++++++++- Kinematic.gd | 43 +++++++++++++++++++++++- Missile.gd | 4 +++ Missile.tscn | 44 ++++++++++++++++++++++++- Player.tscn | 2 +- 8 files changed, 256 insertions(+), 14 deletions(-) diff --git a/Asteroid.tscn b/Asteroid.tscn index e80237b..ae3fdfe 100644 --- a/Asteroid.tscn +++ b/Asteroid.tscn @@ -15,8 +15,8 @@ input/pickable = false shapes/0/shape = SubResource( 1 ) shapes/0/transform = Matrix32( 1, 0, 0, 1, -0.17482, 1.87222 ) shapes/0/trigger = false -collision/layers = 3 -collision/mask = 1 +collision/layers = 7 +collision/mask = 0 collision/margin = 0.08 script/script = ExtResource( 1 ) diff --git a/EnemyGrunt.gd b/EnemyGrunt.gd index 77e503c..c1d9b98 100644 --- a/EnemyGrunt.gd +++ b/EnemyGrunt.gd @@ -1,8 +1,9 @@ extends KinematicBody2D -onready var area = get_node("Area2D") onready var gun = get_node("Ship/Gun") onready var launcher = get_node("Ship/MissileLauncher") +onready var firing_area = get_node("FiringCone") +onready var avoid_area = get_node("AvoidCone") var ExplosionEffect = load("res://ExplosionEffect.tscn") @@ -19,6 +20,7 @@ var cur_kinematic var steering var s_seek var s_arrive +var s_avoid var player_in_cone = false @@ -31,20 +33,21 @@ func _ready(): s_seek = km.Seek.new(self) s_arrive = km.Arrive.new(self, grunt_arrive_radius, grunt_arrive_speed) + s_avoid = km.Avoid.new(self, avoid_area) var player = get_tree().get_root().get_node("Game/Player") s_seek.set_target(player) s_arrive.set_target(player) # firing cone! - area.connect("body_enter", self, "on_body_enter") - area.connect("body_exit", self, "on_body_exit") + firing_area.connect("body_enter", self, "on_body_enter_firing_cone") + firing_area.connect("body_exit", self, "on_body_exit_firing_cone") -func on_body_enter(b): +func on_body_enter_firing_cone(b): if b.type() == "Player": player_in_cone = true -func on_body_exit(b): +func on_body_exit_firing_cone(b): if b.type() == "Player": player_in_cone = false @@ -61,9 +64,14 @@ func do_damage(v): func type(): return "Enemy" +func get_kinematic_position(): + return get_global_pos() + cur_kinematic.velocity + func _fixed_process(delta): + s_seek.get_steering(steering) s_arrive.get_steering(steering) + s_avoid.get_steering(steering) cur_kinematic.update(steering, delta) # pass on velocity diff --git a/EnemyGrunt.tscn b/EnemyGrunt.tscn index 716c840..2d4f28c 100644 --- a/EnemyGrunt.tscn +++ b/EnemyGrunt.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=8 format=1] +[gd_scene load_steps=11 format=1] [ext_resource path="res://EnemyGrunt.gd" type="Script" id=1] [ext_resource path="res://raw/enemy_grunt.png" type="Texture" id=2] @@ -16,6 +16,24 @@ extents = Vector2( 8.55915, 8.40247 ) custom_solver_bias = 0.0 points = Vector2Array( 0, -10, 8.66025, 5, -8.66025, 5 ) +[sub_resource type="SegmentShape2D" id=3] + +custom_solver_bias = 0.0 +a = Vector2( 0, 0 ) +b = Vector2( 0, 10 ) + +[sub_resource type="SegmentShape2D" id=4] + +custom_solver_bias = 0.0 +a = Vector2( 0, 0 ) +b = Vector2( 0, 10 ) + +[sub_resource type="SegmentShape2D" id=5] + +custom_solver_bias = 0.0 +a = Vector2( 0, 0 ) +b = Vector2( 0, 10 ) + [node name="EnemyGrunt" type="KinematicBody2D"] transform/pos = Vector2( 0.12851, 0 ) @@ -75,7 +93,7 @@ script/script = ExtResource( 4 ) transform/pos = Vector2( 1.3176, 15.4159 ) script/script = ExtResource( 5 ) -[node name="Area2D" type="Area2D" parent="."] +[node name="FiringCone" type="Area2D" parent="."] input/pickable = true shapes/0/shape = SubResource( 2 ) @@ -86,7 +104,7 @@ gravity = 98.0 linear_damp = 0.1 angular_damp = 1.0 -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="FiringCone"] transform/pos = Vector2( 0.173824, 148.748 ) transform/scale = Vector2( 4, 16 ) @@ -94,4 +112,48 @@ shape = SubResource( 2 ) trigger = true _update_shape_index = 0 +[node name="AvoidCone" type="Area2D" parent="."] + +transform/pos = Vector2( 0.118912, -0.118912 ) +input/pickable = true +shapes/0/shape = SubResource( 3 ) +shapes/0/transform = Matrix32( 0.707107, -0.707107, 1.41421, 1.41421, 0, 0 ) +shapes/0/trigger = true +shapes/1/shape = SubResource( 4 ) +shapes/1/transform = Matrix32( 0.707107, 0.707107, -1.41421, 1.41421, 0, 0 ) +shapes/1/trigger = true +shapes/2/shape = SubResource( 5 ) +shapes/2/transform = Matrix32( 1, 0, 0, 12, 0, 7.88369 ) +shapes/2/trigger = true +gravity_vec = Vector2( 0, 1 ) +gravity = 98.0 +linear_damp = 0.1 +angular_damp = 1.0 +collision/layers = 4 +collision/mask = 4 + +[node name="LeftFeeler" type="CollisionShape2D" parent="AvoidCone"] + +transform/rot = 45.0 +transform/scale = Vector2( 1, 2 ) +shape = SubResource( 3 ) +trigger = true +_update_shape_index = 0 + +[node name="RightFeeler" type="CollisionShape2D" parent="AvoidCone"] + +transform/rot = -45.0 +transform/scale = Vector2( 1, 2 ) +shape = SubResource( 4 ) +trigger = true +_update_shape_index = 1 + +[node name="MiddleFeeler" type="CollisionShape2D" parent="AvoidCone"] + +transform/pos = Vector2( 0, 7.88369 ) +transform/scale = Vector2( 1, 12 ) +shape = SubResource( 5 ) +trigger = true +_update_shape_index = 2 + diff --git a/Game.tscn b/Game.tscn index 8aae030..ef2a26d 100644 --- a/Game.tscn +++ b/Game.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=8 format=1] +[gd_scene load_steps=9 format=1] [ext_resource path="res://Game.gd" type="Script" id=1] [ext_resource path="res://Minimap.tscn" type="PackedScene" id=2] @@ -7,6 +7,7 @@ [ext_resource path="res://Player.tscn" type="PackedScene" id=5] [ext_resource path="res://raw/space.png" type="Texture" id=6] [ext_resource path="res://EnemyGrunt.tscn" type="PackedScene" id=7] +[ext_resource path="res://Missile.tscn" type="PackedScene" id=8] [node name="Game" type="Node"] @@ -71,4 +72,88 @@ region_rect = Rect2( 0, 0, 8192, 8192 ) transform/pos = Vector2( 127.878, -20.3627 ) transform/scale = Vector2( 1.5, 1.5 ) +[node name="Missile" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -185.011, -27.2074 ) + +[node name="Missile1" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -406.751, 14.9641 ) + +[node name="Missile2" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -529.185, 130.596 ) + +[node name="Missile3" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -635.294, 254.39 ) + +[node name="Missile4" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -681.546, 423.076 ) + +[node name="Missile5" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -872.16, 532.262 ) + +[node name="Missile6" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -935.081, 743.232 ) + +[node name="Missile7" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -935.081, 743.232 ) + +[node name="Missile8" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 491.753, 33.61 ) + +[node name="Missile9" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 802.924, 120.89 ) + +[node name="Missile10" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 954.715, 219.554 ) + +[node name="Missile11" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 1106.51, 299.244 ) + +[node name="Missile12" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 1227.94, 420.677 ) + +[node name="Missile13" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 1356.96, 576.262 ) + +[node name="Missile14" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 1459.42, 716.669 ) + +[node name="Missile15" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 1573.26, 906.407 ) + +[node name="Missile16" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 1675.72, 1020.25 ) + +[node name="Missile17" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( 1804.74, 1206.19 ) + +[node name="Missile18" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -274.79, 48.7891 ) + +[node name="Missile19" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -532.835, 348.576 ) + +[node name="Missile20" parent="." instance=ExtResource( 8 )] + +transform/pos = Vector2( -631.499, 591.441 ) + diff --git a/Kinematic.gd b/Kinematic.gd index 643ff6c..acf5a86 100644 --- a/Kinematic.gd +++ b/Kinematic.gd @@ -23,6 +23,7 @@ class Kinematic: func update(steering, delta): owner.move(velocity * delta) + # owner.set_pos(owner.get_pos() + velocity * delta) if velocity.length() > 0: owner.set_rot(velocity.normalized().angle()) @@ -58,7 +59,10 @@ class Seek: target = null func set_target(t): - target = weakref(t) + if t != null: + target = weakref(t) + else: + target = null class Arrive: @@ -87,6 +91,43 @@ class Arrive: func set_target(t): target = weakref(t) +class AvoidTarget: + + var position + + func _init(p): + position = p + + func get_kinematic_position(): + return position + +class Avoid extends Seek: + + var avoid_target = AvoidTarget.new(Vector2(0, 0)) + var avoid_distance = 128 + + func _init(o, a).(o): + a.connect("body_enter_shape", self, "on_body_enter_feeler") + a.connect("body_exit_shape", self, "on_body_exit_feeler") + + func set_turn_direction(body, id): + var cp = body.get_collision_pos() + var cn = body.get_collision_normal() + avoid_target.position = cp + cn * avoid_distance + + func on_body_enter_feeler(body_id, body, body_shape, area_shape): + set_turn_direction(body, area_shape) + .set_target(avoid_target) + print("Y", area_shape) + + func on_body_exit_feeler(body_id, body, body_shape, area_shape): + .set_target(null) + print("N", area_shape) + + func get_steering(s): + if target == null: return + return .get_steering(s) + class Flee: func init(): pass diff --git a/Missile.gd b/Missile.gd index 6669556..0f7a5e2 100644 --- a/Missile.gd +++ b/Missile.gd @@ -6,6 +6,7 @@ var MissileImpact = load("res://MissileImpact.tscn") onready var sprite = get_node("Sprite") onready var ps = get_node("Particles2D") onready var cs = get_node("CollisionShape2D") +onready var avoid_area = get_node("AvoidCone") var missile_max_speed = 384 # pixels per second var missile_arrive_radius = 64 @@ -17,6 +18,7 @@ var cur_kinematic var steering var s_seek var s_arrive +var s_avoid # is dead? var is_dead = false @@ -35,6 +37,7 @@ func _ready(): s_seek = km.Seek.new(self) s_arrive = km.Arrive.new(self, missile_arrive_radius, missile_arrive_speed) + s_avoid = km.Avoid.new(self, avoid_area) var player = get_tree().get_root().get_node("Game/Player") s_seek.set_target(player) @@ -88,6 +91,7 @@ func _fixed_process(delta): s_seek.get_steering(steering) s_arrive.get_steering(steering) + s_avoid.get_steering(steering) cur_kinematic.update(steering, delta) if is_colliding(): diff --git a/Missile.tscn b/Missile.tscn index 4051777..d43fdb0 100644 --- a/Missile.tscn +++ b/Missile.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=4 format=1] +[gd_scene load_steps=6 format=1] [ext_resource path="res://Missile.gd" type="Script" id=1] [ext_resource path="res://raw/missile_one.png" type="Texture" id=2] @@ -8,6 +8,18 @@ custom_solver_bias = 0.0 extents = Vector2( 0.531269, 3.07443 ) +[sub_resource type="SegmentShape2D" id=2] + +custom_solver_bias = 0.0 +a = Vector2( 0, 0 ) +b = Vector2( 0, 10 ) + +[sub_resource type="SegmentShape2D" id=3] + +custom_solver_bias = 0.0 +a = Vector2( 0, 0 ) +b = Vector2( 0, 10 ) + [node name="Missile" type="KinematicBody2D"] transform/scale = Vector2( 2, 2 ) @@ -55,4 +67,34 @@ shape = SubResource( 1 ) trigger = false _update_shape_index = 0 +[node name="AvoidCone" type="Area2D" parent="."] + +input/pickable = true +shapes/0/shape = SubResource( 2 ) +shapes/0/transform = Matrix32( -0.92388, 0.382683, -0.382683, -0.92388, 0, 0 ) +shapes/0/trigger = true +shapes/1/shape = SubResource( 3 ) +shapes/1/transform = Matrix32( -0.92388, -0.382683, 0.382683, -0.92388, 0, 0 ) +shapes/1/trigger = true +gravity_vec = Vector2( 0, 1 ) +gravity = 98.0 +linear_damp = 0.1 +angular_damp = 1.0 +collision/layers = 4 +collision/mask = 6 + +[node name="LeftFeeler" type="CollisionShape2D" parent="AvoidCone"] + +transform/rot = 202.5 +shape = SubResource( 2 ) +trigger = true +_update_shape_index = 0 + +[node name="RightFeeler" type="CollisionShape2D" parent="AvoidCone"] + +transform/rot = 157.5 +shape = SubResource( 3 ) +trigger = true +_update_shape_index = 1 + diff --git a/Player.tscn b/Player.tscn index c4377e2..906da87 100644 --- a/Player.tscn +++ b/Player.tscn @@ -87,7 +87,7 @@ shapes/3/trigger = false shapes/4/shape = SubResource( 5 ) shapes/4/transform = Matrix32( 1, 0, 0, 1, 1.13636, -0.699295 ) shapes/4/trigger = false -collision/layers = 3 +collision/layers = 7 collision/mask = 1 collision/margin = 0.08 script/script = ExtResource( 1 )