Basic flying enemy with navigation
This commit is contained in:
parent
d3df3b1424
commit
9bb25a7cbe
@ -3,382 +3,66 @@ const PhysicsFunc = preload("res://src/Utilities/Physic/PhysicsFunc.gd")
|
||||
|
||||
onready var players = get_tree().get_nodes_in_group("player")
|
||||
|
||||
onready var vision_raycast: RayCast2D = $VisionRayCast
|
||||
onready var orientation: RayCast2D = $Orientation
|
||||
onready var nav_agent: NavigationAgent2D = $NavigationAgent2D
|
||||
onready var feeler_raycast: RayCast2D = $FeelerRayCast
|
||||
onready var tilemap: TileMap = $"../%TileMap"
|
||||
onready var jump_timer: Timer
|
||||
onready var target_lost_timer: Timer
|
||||
onready var rng = RandomNumberGenerator.new()
|
||||
|
||||
export var score := 100
|
||||
# Is given in blocks
|
||||
export var vision_distance := 6.0
|
||||
# Jump distance in blocks
|
||||
export var default_jump_distance := 3.0
|
||||
export var default_jump_angle := 70.0
|
||||
export var jump_time_search := 0.7
|
||||
export var jump_time_hunt := 0.3
|
||||
export var jump_time_standard_deviation := 0.1
|
||||
|
||||
|
||||
# Also in blocks
|
||||
var movement_radius: float
|
||||
var anchor: Node2D
|
||||
var is_bound := false
|
||||
var was_restricted := false
|
||||
var has_reversed := false
|
||||
|
||||
var target: Object = null
|
||||
|
||||
var start_x := 0.0
|
||||
var in_air := false
|
||||
var is_hurt := false
|
||||
var stored_x_vel = 0.0
|
||||
var has_reversed := false
|
||||
var avoidance_raycasts := []
|
||||
|
||||
var current_delta = 0.0
|
||||
|
||||
var reversing_possible_searching := true
|
||||
|
||||
# TODO Make parameters tunable!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1111!!
|
||||
func _ready():
|
||||
default_jump_distance = default_jump_distance * tilemap.cell_size.x
|
||||
jump_timer = Timer.new()
|
||||
jump_timer.set_one_shot(true)
|
||||
jump_timer.connect("timeout", self, "jump")
|
||||
target_lost_timer = Timer.new()
|
||||
target_lost_timer.set_one_shot(true)
|
||||
target_lost_timer.connect("timeout", self, "lose_target")
|
||||
add_child(jump_timer)
|
||||
add_child(target_lost_timer)
|
||||
|
||||
|
||||
func bind_to_anchor(anchor_node: Node2D, radius: float ) -> void:
|
||||
anchor = anchor_node
|
||||
movement_radius = radius * 24
|
||||
is_bound = true
|
||||
|
||||
|
||||
func _on_StompDetector_body_entered(body: Node) -> void:
|
||||
if body.global_position.y > get_node("StompDetector").global_position.y:
|
||||
return
|
||||
if body.is_in_group("player"):
|
||||
remove_from_group("harmful")
|
||||
is_hurt = true
|
||||
|
||||
|
||||
func execute_movement(delta: float) -> void:
|
||||
# Navigation2DServer.map_get_path()
|
||||
current_delta = delta
|
||||
velocity.y += _gravity * delta
|
||||
if(is_bound):
|
||||
var next_position = global_position + velocity * current_delta
|
||||
var current_distance = global_position.distance_to(anchor.global_position)
|
||||
var new_distance = next_position.distance_to(anchor.global_position)
|
||||
# TODO Fix this in respects to x and y distances and movement dampening
|
||||
# Maybe use mathemathematics or something idfc
|
||||
if(current_distance >= movement_radius && new_distance > current_distance):
|
||||
velocity.x = velocity.x * 0.8
|
||||
velocity.y = velocity.y * 0.8
|
||||
was_restricted = true
|
||||
velocity = move_and_slide(velocity, FLOOR_NORMAL, false, 4, 0.785398,false)
|
||||
if(is_on_floor()):
|
||||
velocity = Vector2(0,0)
|
||||
# Reverse direction when hitting limit
|
||||
|
||||
|
||||
func die() -> void:
|
||||
GlobalState.score += score
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_EnemySkin_area_entered(area:Area2D) -> void:
|
||||
if area.is_in_group("harmful"):
|
||||
get_node("EnemyBody").disabled = true
|
||||
die()
|
||||
|
||||
spawn_avoidance_raycasts(32, 20)
|
||||
pass
|
||||
|
||||
func searching() -> Vector2:
|
||||
detect_player()
|
||||
# TODO Less often!
|
||||
return nav_agent.get_next_location()
|
||||
|
||||
if(is_on_floor()):
|
||||
if(jump_timer.is_stopped()):
|
||||
jump_timer.start(rng.randfn(jump_time_search, jump_time_standard_deviation))
|
||||
if(in_air):
|
||||
in_air = false
|
||||
else:
|
||||
if(!in_air):
|
||||
start_x = global_position.x
|
||||
reversing_possible_searching = true
|
||||
jump_timer.stop()
|
||||
in_air = true
|
||||
func execute_movement(_delta: float) -> void:
|
||||
nav_agent.set_target_location(players[0].global_position)
|
||||
var next_pos = velocity - global_position
|
||||
var avoidance_obstacle_distance = average_collision_vector(avoidance_raycasts)
|
||||
next_pos = next_pos.normalized() + avoidance_obstacle_distance.rotated(PI).normalized()
|
||||
check_feeler((next_pos * 100))
|
||||
#TODO
|
||||
velocity = move_and_slide(next_pos.normalized() * 50, FLOOR_NORMAL, false, 4, 0.785398,false)
|
||||
|
||||
return velocity
|
||||
|
||||
|
||||
func hunting() -> Vector2:
|
||||
detect_player()
|
||||
|
||||
if(is_on_floor()):
|
||||
if(jump_timer.is_stopped()):
|
||||
jump_timer.start(rng.randfn(jump_time_hunt, jump_time_standard_deviation))
|
||||
if(in_air):
|
||||
in_air = false
|
||||
else:
|
||||
if(!in_air):
|
||||
start_x = global_position.x
|
||||
reversing_possible_searching = true
|
||||
jump_timer.stop()
|
||||
in_air = true
|
||||
|
||||
return velocity
|
||||
|
||||
|
||||
func detect_player() -> void:
|
||||
var player
|
||||
if(players.empty()):
|
||||
print("no player found")
|
||||
return
|
||||
player = players[0]
|
||||
vision_raycast.cast_to = (player.global_position - global_position).normalized() * 24 * vision_distance
|
||||
var ray_angle_to_facing = vision_raycast.cast_to.angle_to(orientation.cast_to)
|
||||
vision_raycast.force_raycast_update()
|
||||
var collider = vision_raycast.get_collider()
|
||||
if(target == null && abs(ray_angle_to_facing) < PI/4 && collider != null && collider.is_in_group("player")):
|
||||
target_lost_timer.stop()
|
||||
target = collider
|
||||
print("target found")
|
||||
elif(target != null && target_lost_timer.is_stopped()):
|
||||
target_lost_timer.start(3.0)
|
||||
|
||||
|
||||
func sleeping() -> Vector2:
|
||||
jump_timer.stop()
|
||||
detect_player()
|
||||
return velocity
|
||||
|
||||
|
||||
func lose_target() -> void:
|
||||
print("target lost")
|
||||
target = null
|
||||
|
||||
|
||||
func jump():
|
||||
# print("jump calculation initiated")
|
||||
# Can only reverse once per jump calculation
|
||||
has_reversed = false
|
||||
var zero_vector = Vector2(0,0)
|
||||
var v: Vector2 = velocity_for_jump_distance(default_jump_distance, deg2rad(default_jump_angle))
|
||||
v = correct_jump_direction(v)
|
||||
|
||||
if(is_bound):
|
||||
var next_position = global_position + v * current_delta
|
||||
var current_distance = global_position.distance_to(anchor.global_position)
|
||||
var new_distance = next_position.distance_to(anchor.global_position)
|
||||
# print(current_distance)
|
||||
# print(new_distance)
|
||||
if((new_distance >= movement_radius && new_distance > current_distance) || (new_distance > current_distance && was_restricted)):
|
||||
if can_reverse_facing_direction():
|
||||
reverse_facing_direction()
|
||||
was_restricted = false
|
||||
|
||||
if (get_facing_direction() < 0 && $Left_Wallcast.is_colliding()):
|
||||
v = zero_vector
|
||||
if (get_facing_direction() > 0 && $Right_Wallcast.is_colliding()):
|
||||
v = zero_vector
|
||||
if ($Right_Wallcast.is_colliding() && $Left_Wallcast.is_colliding()):
|
||||
print("help this is a really tight space :(")
|
||||
return velocity
|
||||
|
||||
v = correct_jump_direction(v)
|
||||
if(v != zero_vector):
|
||||
v = consider_jump_headspace(v)
|
||||
if(v != zero_vector):
|
||||
v = consider_jump_landing_space(v)
|
||||
if(v == zero_vector):
|
||||
# TODO fix that you could call jump from jumping on top
|
||||
# and let it fail if the top is dangerous for jump height or not safe
|
||||
v = consider_jumping_on_top()
|
||||
if(v == zero_vector && can_reverse_facing_direction()):
|
||||
reverse_facing_direction()
|
||||
jump()
|
||||
velocity = v
|
||||
|
||||
|
||||
func correct_jump_direction(v: Vector2) -> Vector2:
|
||||
if sign(v.x) != get_facing_direction():
|
||||
v.x *= -1
|
||||
return v
|
||||
|
||||
|
||||
# Cast a ray to the highest point of the jump
|
||||
# Check the highest point for collision
|
||||
# Calculate safe jump height and then a safe jump velocity
|
||||
func consider_jump_headspace(v: Vector2) -> Vector2:
|
||||
var height = calculate_jump_height(v)
|
||||
var distance = calculate_jump_distance(v)
|
||||
# Half distance is an estimate of the jumps apex()
|
||||
var height_collider = check_feeler(Vector2(get_facing_direction()*(distance/2), (-height)), Vector2(0,-9))
|
||||
if(height_collider != null):
|
||||
# check half jump height
|
||||
var half_height_v = jump_height_to_velocity(height/3, v)
|
||||
var half_height = calculate_jump_height(half_height_v)
|
||||
height_collider = check_feeler(Vector2(get_facing_direction()*(distance/2), (-half_height)), Vector2(0,-9))
|
||||
if(height_collider != null && can_reverse_facing_direction()):
|
||||
print("no safe height for frog jump")
|
||||
return Vector2(0,0)
|
||||
else:
|
||||
var collision_point = feeler_raycast.get_collision_point()
|
||||
#TODO Consider sprite size for height
|
||||
var target_height = collision_point.y - (feeler_raycast.global_position.y - 9)
|
||||
v = jump_height_to_velocity(abs(target_height), v)
|
||||
return v
|
||||
|
||||
|
||||
# Check the block in jump distance for danger or height
|
||||
# If danger check neighboring blocks: if still danger, then jump closer (or jump over)
|
||||
# If height move to distance which allows 1 block high jump
|
||||
func consider_jump_landing_space(v: Vector2) -> Vector2:
|
||||
var jump_distance = calculate_jump_distance(v)
|
||||
var jump_height = calculate_jump_height(v)
|
||||
var collider = check_feeler(Vector2(jump_distance * get_facing_direction(), - jump_height/2))
|
||||
# TODO Unpacked loop, make function or something?
|
||||
# Shortens the jump in steps to make it more safe
|
||||
if(!is_jump_path_safe(v, global_position) || collider != null):
|
||||
jump_distance = calculate_jump_distance(v) - 24
|
||||
v = change_jump_distance(jump_distance, v)
|
||||
jump_height = calculate_jump_height(v)
|
||||
v = correct_jump_direction(v)
|
||||
collider = check_feeler(Vector2(jump_distance * get_facing_direction(), - jump_height/2))
|
||||
if(!is_jump_path_safe(v, global_position) || collider != null):
|
||||
jump_distance = calculate_jump_distance(v) - 12
|
||||
v = change_jump_distance(jump_distance, v)
|
||||
jump_height = calculate_jump_height(v)
|
||||
v = correct_jump_direction(v)
|
||||
collider = check_feeler(Vector2(jump_distance * get_facing_direction(), - jump_height/2))
|
||||
if((!is_jump_path_safe(v, global_position) || collider != null) && can_reverse_facing_direction()):
|
||||
return Vector2(0,0)
|
||||
return v
|
||||
|
||||
|
||||
# Tries to shorten the jump, so that it lands in a tiles center
|
||||
func jump_to_tile_center(v: Vector2) -> Vector2:
|
||||
var distance = stepify(calculate_jump_distance(v), 0.01)
|
||||
if !is_equal_approx(fmod(abs(global_position.x + distance * get_facing_direction()), 24), 12):
|
||||
# print(distance)
|
||||
# print(global_position.x + distance)
|
||||
# print(fmod((global_position.x + distance), 24))
|
||||
var new_distance = distance
|
||||
if(get_facing_direction() < 0):
|
||||
new_distance = fmod((global_position.x + distance), 24) - 12 + distance
|
||||
else:
|
||||
new_distance = distance + 12 - fmod((global_position.x + distance), 24)
|
||||
# print("centering distance")
|
||||
# print(new_distance)
|
||||
v = change_jump_distance(abs(new_distance), v)
|
||||
v = correct_jump_direction(v)
|
||||
return v
|
||||
|
||||
|
||||
# TODO Depends on Frog Shape and Tile Shape
|
||||
func is_jump_path_safe(v: Vector2, pos: Vector2) -> bool:
|
||||
var v0 = v.length()
|
||||
var angle = v.angle()
|
||||
var jump_distance = calculate_jump_distance(v)
|
||||
var harmful_nodes = get_tree().get_nodes_in_group("harmful")
|
||||
for node in harmful_nodes:
|
||||
var node_pos = node.global_position
|
||||
if abs(node_pos.x - pos.x) > abs(jump_distance) * 3 || abs(node_pos.x - pos.x) < 1:
|
||||
func average_collision_vector(var raycasts: Array) -> Vector2:
|
||||
var total_distances = Vector2()
|
||||
for raycast in raycasts:
|
||||
if !raycast.is_colliding():
|
||||
continue
|
||||
var node_y = node_pos.y - 12
|
||||
var initial_throw_height = node_y - (global_position.y + 9)
|
||||
var term1 = (pow(v0, 2) * sin(2 * angle)) / (2 * _gravity)
|
||||
var term2 = ((v0 * cos(angle))/_gravity) * sqrt(pow(v0, 2) * pow(sin(angle), 2) + 2 * _gravity * initial_throw_height)
|
||||
var distance = abs(term1) + abs(term2)
|
||||
# print("distance to next spike")
|
||||
# print(pos.x + sign(v.x) * distance - node_pos.x)
|
||||
var safe_distance = 12
|
||||
if (sign(initial_throw_height) < 0):
|
||||
safe_distance = 24
|
||||
if(abs(pos.x + sign(v.x) * distance - node_pos.x) < safe_distance):
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
func calculate_jump_height(v: Vector2) -> float:
|
||||
return abs((pow(v.length(), 2) * pow(sin(v.angle()), 2))/(2*_gravity))
|
||||
|
||||
|
||||
func consider_jumping_on_top() -> Vector2:
|
||||
var collider = check_feeler(Vector2(36 * get_facing_direction(),0))
|
||||
var facing = 0 if get_facing_direction() >= 0 else - 1
|
||||
if (collider == null):
|
||||
return Vector2(0,0)
|
||||
var local_position = tilemap.to_local(feeler_raycast.get_collision_point())
|
||||
var map_position = tilemap.world_to_map(local_position)
|
||||
var tile_position = Vector2(map_position.x + facing, map_position.y)
|
||||
# print(tile_position)
|
||||
# TODO Here the climb height of frog is limited to one constantly
|
||||
if (tilemap.get_cell(tile_position.x, tile_position.y - 1) != -1):
|
||||
# print("wall is more than one high")
|
||||
return Vector2(0,0)
|
||||
# print("wall is only one high")
|
||||
var tile_upper_left_corner = tilemap.to_global(tilemap.map_to_world(tile_position))
|
||||
var tile_upper_right_corner = Vector2(tile_upper_left_corner.x + tilemap.cell_size.x, tile_upper_left_corner.y)
|
||||
|
||||
var jump_angle = 0
|
||||
if(facing < 0):
|
||||
var frog_bottom_left_corner = Vector2($EnemyBody.global_position.x - $EnemyBody.shape.extents.x,
|
||||
$EnemyBody.global_position.y + $EnemyBody.shape.extents.y)
|
||||
jump_angle = frog_bottom_left_corner.angle_to_point(tile_upper_right_corner)
|
||||
else:
|
||||
var frog_bottom_right_corner = Vector2($EnemyBody.global_position.x + $EnemyBody.shape.extents.x,
|
||||
$EnemyBody.global_position.y + $EnemyBody.shape.extents.y)
|
||||
jump_angle = frog_bottom_right_corner.angle_to_point(tile_upper_left_corner) - PI
|
||||
# print(rad2deg(jump_angle))
|
||||
|
||||
# if(abs(rad2deg(jump_angle)) < default_jump_angle):
|
||||
# return correct_jump_direction(velocity_for_jump_distance(default_jump_distance/2, abs(deg2rad(default_jump_angle))))
|
||||
if(abs(rad2deg(jump_angle)) < 78):
|
||||
return correct_jump_direction(velocity_for_jump_distance(default_jump_distance/2, abs(deg2rad(80))))
|
||||
else:
|
||||
return velocity_for_jump_distance(8, abs(deg2rad(45))) * -1 * facing
|
||||
|
||||
return Vector2(0,0)
|
||||
# Check if there is another obstacle above the block or do a regular jump with adjusted parameters instead(for checking)
|
||||
# Cast from bottom corner to upper tile corner
|
||||
# Check the angle of the raycast
|
||||
# Return small jump backwards if the angle is too steep
|
||||
# Make the angle 1 deg steeper
|
||||
# Return a jump along the angled raycast
|
||||
|
||||
|
||||
# Only works for jumps on straight ground
|
||||
func calculate_jump_distance(v: Vector2) -> float:
|
||||
return abs((pow(v.length(), 2) * sin(-1 * 2 * v.angle()))/(_gravity))
|
||||
|
||||
|
||||
func jump_height_to_velocity(target_height: float, v: Vector2) -> Vector2:
|
||||
var initial_height = calculate_jump_height(v)
|
||||
return v.normalized() * sqrt(pow(v.length(),2)/(initial_height/target_height))
|
||||
|
||||
|
||||
# Changes a Vector for a jump to the targeted distance, keeping the angle
|
||||
func change_jump_distance(target_distance: float, v: Vector2) -> Vector2:
|
||||
var initial_distance = calculate_jump_distance(v)
|
||||
return v.normalized() * sqrt(pow(v.length(),2)/(initial_distance/target_distance))
|
||||
|
||||
# Takes an angle and a distance to calculate a jump launching at that angle and covering the distance
|
||||
func velocity_for_jump_distance(distance: float = 3*24, angle: float = deg2rad(65)) -> Vector2:
|
||||
var abs_velocity = sqrt((distance * _gravity)/sin(2*angle))
|
||||
return Vector2(abs_velocity,0).rotated(-1*angle)
|
||||
|
||||
var collision_point = self.to_local(raycast.get_collision_point())
|
||||
total_distances += collision_point
|
||||
return total_distances/raycasts.size()
|
||||
|
||||
func can_reverse_facing_direction() -> bool:
|
||||
if(is_on_floor() && !has_reversed):
|
||||
return true
|
||||
return false
|
||||
|
||||
func spawn_avoidance_raycasts(var raycount: int, var length: float = 24) -> void:
|
||||
var direction: float = 0
|
||||
while direction <= 2*PI:
|
||||
var raycast: RayCast2D = RayCast2D.new()
|
||||
raycast.enabled = true
|
||||
raycast.exclude_parent = true
|
||||
raycast.collide_with_areas = true
|
||||
raycast.collide_with_bodies = true
|
||||
# Layers 4, 5 & 6
|
||||
raycast.collision_mask = 56
|
||||
raycast.cast_to = Vector2(length, 0).rotated(direction)
|
||||
add_child(raycast)
|
||||
avoidance_raycasts.append(raycast)
|
||||
direction += (2*PI)/raycount
|
||||
|
||||
# Checks the feeler ray for collisions and returns collision or null
|
||||
func check_feeler(v: Vector2, _offset = Vector2(0,0)) -> Object:
|
||||
@ -388,14 +72,3 @@ func check_feeler(v: Vector2, _offset = Vector2(0,0)) -> Object:
|
||||
feeler_raycast.force_raycast_update()
|
||||
feeler_raycast.position = prev_position
|
||||
return feeler_raycast.get_collider()
|
||||
|
||||
|
||||
func reverse_facing_direction() -> void:
|
||||
has_reversed = true
|
||||
print("reversing direction")
|
||||
orientation.cast_to.x *= -1
|
||||
pass
|
||||
|
||||
|
||||
func get_facing_direction() -> float:
|
||||
return orientation.cast_to.x
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
[gd_scene load_steps=8 format=2]
|
||||
|
||||
[ext_resource path="res://src/Actors/Enemies/Beings/WhatAreFrog.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/Actors/Enemies/Beings/Flyer.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/Actors/Enemies/Beings/FlyerStateMachine.gd" type="Script" id=2]
|
||||
[ext_resource path="res://assets/meta/new_dynamicfont.tres" type="DynamicFont" id=3]
|
||||
[ext_resource path="res://assets/enemy/enemy.png" type="Texture" id=4]
|
||||
[ext_resource path="res://assets/blobby/idle/blobby1.png" type="Texture" id=4]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 12, 7 )
|
||||
extents = Vector2( 12, 9 )
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=2]
|
||||
extents = Vector2( 15, 5.12039 )
|
||||
@ -17,13 +17,13 @@ extents = Vector2( 18.2143, 14.3338 )
|
||||
[node name="Flyer" type="KinematicBody2D" groups=["harmful"]]
|
||||
collision_layer = 2
|
||||
collision_mask = 9
|
||||
collision/safe_margin = 0.001
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Statemachine" type="Node2D" parent="."]
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="StateLabel" type="Label" parent="."]
|
||||
visible = false
|
||||
show_behind_parent = true
|
||||
margin_left = -36.0
|
||||
margin_top = -30.0
|
||||
@ -37,8 +37,8 @@ align = 1
|
||||
valign = 1
|
||||
|
||||
[node name="FlyerSprite" type="Sprite" parent="."]
|
||||
position = Vector2( 0, -1.90735e-06 )
|
||||
scale = Vector2( 0.201, 0.193 )
|
||||
position = Vector2( -1, -1 )
|
||||
scale = Vector2( 1, 1.34375 )
|
||||
texture = ExtResource( 4 )
|
||||
|
||||
[node name="VisibilityEnabler2D" type="VisibilityEnabler2D" parent="."]
|
||||
@ -54,15 +54,12 @@ cast_to = Vector2( 0, -1 )
|
||||
collision_mask = 56
|
||||
collide_with_areas = true
|
||||
|
||||
[node name="Orientation" type="RayCast2D" parent="."]
|
||||
cast_to = Vector2( -1, 0 )
|
||||
collision_mask = 0
|
||||
collide_with_bodies = false
|
||||
|
||||
[node name="EnemyBody" type="CollisionShape2D" parent="." groups=["harmful"]]
|
||||
position = Vector2( 0, 4.5 )
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="NavigationAgent2D" type="NavigationAgent2D" parent="."]
|
||||
path_max_distance = 100.0
|
||||
|
||||
[node name="cshape" type="Node2D" parent="."]
|
||||
position = Vector2( 0, -3.8147e-06 )
|
||||
scale = Vector2( 0.1, 0.1 )
|
||||
@ -74,7 +71,7 @@ softness = 0.1
|
||||
|
||||
[node name="StompDetector" type="Area2D" parent="." groups=["weakpoint"]]
|
||||
modulate = Color( 0, 0.0392157, 1, 1 )
|
||||
position = Vector2( 0, -6.44095 )
|
||||
position = Vector2( 0, -9 )
|
||||
scale = Vector2( 0.7, 0.7 )
|
||||
collision_layer = 2
|
||||
input_pickable = false
|
||||
@ -83,14 +80,13 @@ input_pickable = false
|
||||
position = Vector2( -4.76837e-07, 1.56134 )
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="EnemySkin" type="Area2D" parent="." groups=["player"]]
|
||||
[node name="EnemySkin" type="Area2D" parent="."]
|
||||
process_priority = -1
|
||||
scale = Vector2( 0.7, 0.7 )
|
||||
collision_layer = 2
|
||||
collision_mask = 126
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionShape2D" parent="EnemySkin"]
|
||||
position = Vector2( 0, 2.85714 )
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[connection signal="body_entered" from="StompDetector" to="." method="_on_StompDetector_body_entered"]
|
||||
|
||||
@ -271,14 +271,11 @@ func consider_jumping_on_top() -> Vector2:
|
||||
var local_position = tilemap.to_local(feeler_raycast.get_collision_point())
|
||||
var map_position = tilemap.world_to_map(local_position)
|
||||
var tile_position = Vector2(map_position.x + facing, map_position.y)
|
||||
print(tile_position)
|
||||
# TODO Here the climb height of frog is limited to one constantly
|
||||
if (tilemap.get_cell(tile_position.x, tile_position.y - 1) != -1 &&
|
||||
#TODO 9 is the navigation tile!
|
||||
tilemap.get_cell(tile_position.x, tile_position.y - 1) != 9):
|
||||
print("wall is more than one high")
|
||||
return Vector2(0,0)
|
||||
print("wall is only one high")
|
||||
var tile_upper_left_corner = tilemap.to_global(tilemap.map_to_world(tile_position))
|
||||
var tile_upper_right_corner = Vector2(tile_upper_left_corner.x + tilemap.cell_size.x, tile_upper_left_corner.y)
|
||||
|
||||
@ -287,12 +284,10 @@ func consider_jumping_on_top() -> Vector2:
|
||||
var frog_bottom_left_corner = Vector2($EnemyBody.global_position.x - $EnemyBody.shape.extents.x,
|
||||
$EnemyBody.global_position.y + $EnemyBody.shape.extents.y)
|
||||
jump_angle = frog_bottom_left_corner.angle_to_point(tile_upper_right_corner)
|
||||
print(rad2deg(jump_angle))
|
||||
else:
|
||||
var frog_bottom_right_corner = Vector2($EnemyBody.global_position.x + $EnemyBody.shape.extents.x,
|
||||
$EnemyBody.global_position.y + $EnemyBody.shape.extents.y)
|
||||
jump_angle = frog_bottom_right_corner.angle_to_point(tile_upper_left_corner) - PI
|
||||
print(rad2deg(jump_angle))
|
||||
|
||||
if(abs(rad2deg(jump_angle)) < 78):
|
||||
return correct_jump_direction(velocity_for_jump_distance(default_jump_distance/2, abs(deg2rad(80))))
|
||||
|
||||
@ -461,7 +461,7 @@ input_pickable = false
|
||||
position = Vector2( 1.19209e-07, -1.42857 )
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="EnemySkin" type="Area2D" parent="." groups=["player"]]
|
||||
[node name="EnemySkin" type="Area2D" parent="."]
|
||||
process_priority = -1
|
||||
scale = Vector2( 0.7, 0.7 )
|
||||
collision_layer = 2
|
||||
@ -469,7 +469,6 @@ collision_mask = 126
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionShape2D" parent="EnemySkin"]
|
||||
position = Vector2( 0, -0.738329 )
|
||||
scale = Vector2( 1, 1 )
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[connection signal="body_entered" from="StompDetector" to="." method="_on_StompDetector_body_entered"]
|
||||
|
||||
97
src/Levels/Flyer Test Level.tscn
Normal file
97
src/Levels/Flyer Test Level.tscn
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user