Fixed enemy rays

This commit is contained in:
2026-01-29 20:58:11 +03:00
parent f870bd4dfe
commit 36c123ea5d
25 changed files with 42 additions and 30 deletions
+193
View File
@@ -0,0 +1,193 @@
class_name Player
extends CharacterBody2D
signal dead
const ANIMATION_IDLE = "idle"
const ANIMATION_LOOK_AROUND_1 = "look_around_1"
const ANIMATION_LOOK_AROUND_2 = "look_around_2"
const ANIMATION_WALK_LEFT = "walk_left"
const ANIMATION_WALK_RIGHT = "walk_right"
const ANIMATION_FALL_DOWN = "fall_down"
const ANIMATION_FALL_DOWN_LEFT = "fall_down_left"
const ANIMATION_FALL_DOWN_RIGHT = "fall_down_right"
const ANIMATION_FALL_UP = "fall_up"
const ANIMATION_FALL_UP_LEFT = "fall_up_left"
const ANIMATION_FALL_UP_RIGHT = "fall_up_right"
const ANIMATION_DEATH = "death"
const LOOK_AROUND_CHANCE = 25
const PICKUP_OFFSET = 16.0
@export_range(0.0, 1000.0) var max_speed := 160
@export_range(0.0, 1000.0) var max_fall_speed := 640
@export_range(0.0, 1000.0) var acceleration := 600.0
@export_range(0.0, 1000.0) var jump_velocity := 320.0
@export_range(0.0, 2.0) var jump_gravity_factor := 1.0
@export_range(0.0, 2.0) var fall_gravity_factor := 1.5
@export_range(0.0, 1.0) var passive_jump_factor := 0.5
var _is_alive := true
@onready var sprite : AnimatedSprite2D = $AnimatedSprite2D
@onready var collision_switcher : CollisionSwitcher = $CollisionSwitcher
@onready var pickups : Node2D = $Pickups
@onready var jump_buffer_timer : Timer = $JumpBufferTimer
@onready var coyote_time_timer : Timer = $CoyoteTimeTimer
func _ready() -> void:
collision_switcher.material = sprite.material
func _physics_process(delta: float) -> void:
if is_on_floor():
coyote_time_timer.start()
if is_on_ceiling_only() and velocity.y < 0.0:
velocity.y = 0.0
if not is_on_floor():
var gravity_factor := jump_gravity_factor if velocity.y < 0.0 else fall_gravity_factor
if velocity.y < 0.0 and not Input.is_action_pressed("jump"):
velocity.y *= passive_jump_factor
velocity += get_gravity() * gravity_factor * delta
velocity.y = clampf(velocity.y, -max_fall_speed, max_fall_speed)
if not _is_alive:
_slow_down(delta)
else:
if Input.is_action_just_pressed("jump"):
jump_buffer_timer.start()
if not coyote_time_timer.is_stopped() and not jump_buffer_timer.is_stopped():
SoundManager.play_sfx_stream(SoundManager.sfx_stream_jump, global_position)
velocity.y = -jump_velocity
jump_buffer_timer.stop()
var direction := Input.get_axis("move_left", "move_right")
if direction:
velocity.x = move_toward(velocity.x, direction * max_speed, acceleration * delta)
else:
_slow_down(delta)
_update_animation()
move_and_slide()
#var was_collided := move_and_slide()
#if was_collided and _is_alive:
#for i in range(get_slide_collision_count()): #TODO remove
#var collision := get_slide_collision(i)
#if _is_killing_collider(collision.get_collider()):
#kill()
func _input(event: InputEvent) -> void:
if event.is_action_pressed("switch_color") and _is_alive:
SoundManager.play_sfx_stream(SoundManager.sfx_stream_switch, global_position)
collision_switcher.switch_color()
func kill() -> void:
if not _is_alive: return
SoundManager.play_sfx_stream(SoundManager.sfx_stream_death, global_position)
_is_alive = false
get_tree().paused = true
process_mode = Node.PROCESS_MODE_ALWAYS
sprite.play(ANIMATION_DEATH)
func add_pickup(pickup: AbstractPickup) -> void:
pickup.reparent.call_deferred(pickups)
_rearrange_pickups.call_deferred()
func remove_pickup(pickup: AbstractPickup) -> void:
if pickup in pickups.get_children():
pickups.remove_child(pickup)
pickup.queue_free()
_rearrange_pickups()
func _slow_down(delta: float) -> void:
velocity.x = move_toward(velocity.x, 0, acceleration * delta)
func _is_killing_collider(collider: Object) -> bool:
if not collider is Node: return false
var node := collider as Node
return node.has_node("PlayerKiller")
func _update_animation() -> void:
var animation := _get_animation()
if sprite.animation != animation:
sprite.play(animation)
func _get_animation() -> String:
if is_on_floor():
if velocity.x > 0:
return ANIMATION_WALK_RIGHT
elif velocity.x < 0:
return ANIMATION_WALK_LEFT
else:
if is_zero_approx(velocity.x):
if velocity.y > 0:
return ANIMATION_FALL_DOWN
else:
return ANIMATION_FALL_UP
if velocity.x > 0:
if velocity.y > 0:
return ANIMATION_FALL_DOWN_RIGHT
else:
return ANIMATION_FALL_UP_RIGHT
elif velocity.x < 0:
if velocity.y > 0:
return ANIMATION_FALL_DOWN_LEFT
else:
return ANIMATION_FALL_UP_LEFT
if sprite.animation in [ANIMATION_LOOK_AROUND_1, ANIMATION_LOOK_AROUND_2]:
return sprite.animation
return ANIMATION_IDLE
func _rearrange_pickups() -> void:
var children := pickups.get_children()
var pickup_shift := (children.size() - 1) * PICKUP_OFFSET / 2.0
for i in range(children.size()):
if not children[i] is Node2D: continue
var node := children[i] as Node2D
node.position.x = i * PICKUP_OFFSET - pickup_shift
node.position.y = 0
func _play_look_around_animation() -> void:
sprite.play(ANIMATION_LOOK_AROUND_1 if randi_range(1, 2) == 1 else ANIMATION_LOOK_AROUND_2)
func _on_animation_finished() -> void:
match sprite.animation:
ANIMATION_LOOK_AROUND_1, ANIMATION_LOOK_AROUND_2:
sprite.play(ANIMATION_IDLE)
ANIMATION_DEATH:
dead.emit()
queue_free()
func _on_animation_looped() -> void:
match sprite.animation:
ANIMATION_IDLE:
if randi_range(1, 100) <= LOOK_AROUND_CHANCE:
_play_look_around_animation()
+1
View File
@@ -0,0 +1 @@
uid://bb8kc32sggrn2
+41
View File
@@ -0,0 +1,41 @@
[gd_scene format=3 uid="uid://dtcad8tdx78tg"]
[ext_resource type="Script" uid="uid://bb8kc32sggrn2" path="res://game/characters/player/player.gd" id="1_xln5q"]
[ext_resource type="PackedScene" uid="uid://5qlocc0yu8ug" path="res://game/collision_switcher.tscn" id="2_j06tb"]
[ext_resource type="PackedScene" uid="uid://cvx6akiplg21s" path="res://game/characters/player/player_sprite.tscn" id="2_n6ad3"]
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_xln5q"]
radius = 4.0
[node name="Player" type="CharacterBody2D" unique_id=508706417]
collision_layer = 128
collision_mask = 33
script = ExtResource("1_xln5q")
[node name="AnimatedSprite2D" parent="." unique_id=237719081 instance=ExtResource("2_n6ad3")]
animation = &"death"
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1101386361]
position = Vector2(0, 1)
shape = SubResource("CapsuleShape2D_xln5q")
[node name="CollisionSwitcher" parent="." unique_id=601548821 node_paths=PackedStringArray("object") instance=ExtResource("2_j06tb")]
object = NodePath("..")
[node name="Camera2D" type="Camera2D" parent="." unique_id=45512317]
process_callback = 0
position_smoothing_enabled = true
[node name="Pickups" type="Node2D" parent="." unique_id=958829860]
position = Vector2(0, -24)
[node name="JumpBufferTimer" type="Timer" parent="." unique_id=740877224]
wait_time = 0.1
one_shot = true
[node name="CoyoteTimeTimer" type="Timer" parent="." unique_id=117837002]
wait_time = 0.1
one_shot = true
[connection signal="animation_finished" from="AnimatedSprite2D" to="." method="_on_animation_finished"]
[connection signal="animation_looped" from="AnimatedSprite2D" to="." method="_on_animation_looped"]
+432
View File
@@ -0,0 +1,432 @@
[gd_scene load_steps=53 format=3 uid="uid://cvx6akiplg21s"]
[ext_resource type="Shader" uid="uid://lqq1mg6l1qqe" path="res://game/shaders/black_n_white.gdshader" id="1_57ht8"]
[ext_resource type="Texture2D" uid="uid://bjccaucrio6ht" path="res://images/characters/player.png" id="2_mi53p"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_i05k5"]
shader = ExtResource("1_57ht8")
shader_parameter/black_color = Color(0, 0, 0, 1)
shader_parameter/white_color = Color(1, 1, 1, 1)
shader_parameter/switch_colors = false
shader_parameter/threshold = 0.5
shader_parameter/speed = 5.0
shader_parameter/intensity = 1.0
shader_parameter/scale = 20.0
[sub_resource type="AtlasTexture" id="AtlasTexture_v6e46"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 128, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_qikhv"]
atlas = ExtResource("2_mi53p")
region = Rect2(32, 128, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_xtgne"]
atlas = ExtResource("2_mi53p")
region = Rect2(64, 128, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_qvokx"]
atlas = ExtResource("2_mi53p")
region = Rect2(96, 128, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_cc0lq"]
atlas = ExtResource("2_mi53p")
region = Rect2(128, 128, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_dw7uy"]
atlas = ExtResource("2_mi53p")
region = Rect2(160, 128, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_ecm54"]
atlas = ExtResource("2_mi53p")
region = Rect2(192, 128, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_0l1kh"]
atlas = ExtResource("2_mi53p")
region = Rect2(224, 128, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_c3gpp"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_myk4l"]
atlas = ExtResource("2_mi53p")
region = Rect2(32, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_kwrpx"]
atlas = ExtResource("2_mi53p")
region = Rect2(64, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_0n461"]
atlas = ExtResource("2_mi53p")
region = Rect2(96, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_bgbv2"]
atlas = ExtResource("2_mi53p")
region = Rect2(128, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_h5vay"]
atlas = ExtResource("2_mi53p")
region = Rect2(160, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_4u621"]
atlas = ExtResource("2_mi53p")
region = Rect2(128, 96, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_tqwgk"]
atlas = ExtResource("2_mi53p")
region = Rect2(64, 96, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_ly4f6"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 96, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_htqrf"]
atlas = ExtResource("2_mi53p")
region = Rect2(160, 96, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_vkuli"]
atlas = ExtResource("2_mi53p")
region = Rect2(96, 96, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_457no"]
atlas = ExtResource("2_mi53p")
region = Rect2(32, 96, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_n6ad3"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_i05k5"]
atlas = ExtResource("2_mi53p")
region = Rect2(32, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_mrbkc"]
atlas = ExtResource("2_mi53p")
region = Rect2(64, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_166ew"]
atlas = ExtResource("2_mi53p")
region = Rect2(32, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_kepaj"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_mi53p"]
atlas = ExtResource("2_mi53p")
region = Rect2(96, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_57ht8"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_vfr3e"]
atlas = ExtResource("2_mi53p")
region = Rect2(128, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_v8w1g"]
atlas = ExtResource("2_mi53p")
region = Rect2(128, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_ss7fc"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_14vf2"]
atlas = ExtResource("2_mi53p")
region = Rect2(96, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_rfvyr"]
atlas = ExtResource("2_mi53p")
region = Rect2(96, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_gjv0h"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 64, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_1qt2f"]
atlas = ExtResource("2_mi53p")
region = Rect2(32, 64, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_gdvfa"]
atlas = ExtResource("2_mi53p")
region = Rect2(64, 64, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_mg2nh"]
atlas = ExtResource("2_mi53p")
region = Rect2(96, 64, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_gcjjm"]
atlas = ExtResource("2_mi53p")
region = Rect2(128, 64, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_e3g8f"]
atlas = ExtResource("2_mi53p")
region = Rect2(160, 64, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_6pjby"]
atlas = ExtResource("2_mi53p")
region = Rect2(192, 64, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_b0cbm"]
atlas = ExtResource("2_mi53p")
region = Rect2(224, 64, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_dd46j"]
atlas = ExtResource("2_mi53p")
region = Rect2(0, 32, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_wvo82"]
atlas = ExtResource("2_mi53p")
region = Rect2(32, 32, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_kdo6l"]
atlas = ExtResource("2_mi53p")
region = Rect2(64, 32, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_hapb4"]
atlas = ExtResource("2_mi53p")
region = Rect2(96, 32, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_lof82"]
atlas = ExtResource("2_mi53p")
region = Rect2(128, 32, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_6toyj"]
atlas = ExtResource("2_mi53p")
region = Rect2(160, 32, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_2eclv"]
atlas = ExtResource("2_mi53p")
region = Rect2(192, 32, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_ojxu4"]
atlas = ExtResource("2_mi53p")
region = Rect2(224, 32, 32, 32)
[sub_resource type="SpriteFrames" id="SpriteFrames_v8w1g"]
animations = [{
"frames": [{
"duration": 2.0,
"texture": SubResource("AtlasTexture_v6e46")
}, {
"duration": 2.0,
"texture": SubResource("AtlasTexture_qikhv")
}, {
"duration": 2.0,
"texture": SubResource("AtlasTexture_xtgne")
}, {
"duration": 2.0,
"texture": SubResource("AtlasTexture_qvokx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_cc0lq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_dw7uy")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ecm54")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0l1kh")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_c3gpp")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_myk4l")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_kwrpx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0n461")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_bgbv2")
}, {
"duration": 5.0,
"texture": SubResource("AtlasTexture_h5vay")
}],
"loop": false,
"name": &"death",
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_4u621")
}],
"loop": true,
"name": &"fall_down",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_tqwgk")
}],
"loop": true,
"name": &"fall_down_left",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_ly4f6")
}],
"loop": true,
"name": &"fall_down_right",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_htqrf")
}],
"loop": true,
"name": &"fall_up",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_vkuli")
}],
"loop": true,
"name": &"fall_up_left",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_457no")
}],
"loop": true,
"name": &"fall_up_right",
"speed": 5.0
}, {
"frames": [{
"duration": 3.0,
"texture": SubResource("AtlasTexture_n6ad3")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_i05k5")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_mrbkc")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_166ew")
}, {
"duration": 4.0,
"texture": SubResource("AtlasTexture_kepaj")
}],
"loop": true,
"name": &"idle",
"speed": 5.0
}, {
"frames": [{
"duration": 3.0,
"texture": SubResource("AtlasTexture_mi53p")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_57ht8")
}, {
"duration": 3.0,
"texture": SubResource("AtlasTexture_vfr3e")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_57ht8")
}],
"loop": true,
"name": &"look_around",
"speed": 5.0
}, {
"frames": [{
"duration": 2.0,
"texture": SubResource("AtlasTexture_v8w1g")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ss7fc")
}, {
"duration": 2.0,
"texture": SubResource("AtlasTexture_14vf2")
}],
"loop": false,
"name": &"look_around_1",
"speed": 5.0
}, {
"frames": [{
"duration": 2.0,
"texture": SubResource("AtlasTexture_rfvyr")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ss7fc")
}, {
"duration": 2.0,
"texture": SubResource("AtlasTexture_v8w1g")
}],
"loop": false,
"name": &"look_around_2",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_gjv0h")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_1qt2f")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_gdvfa")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_mg2nh")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_gcjjm")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_e3g8f")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_6pjby")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_b0cbm")
}],
"loop": true,
"name": &"walk_left",
"speed": 20.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_dd46j")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_wvo82")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_kdo6l")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_hapb4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_lof82")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_6toyj")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_2eclv")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ojxu4")
}],
"loop": true,
"name": &"walk_right",
"speed": 20.0
}]
[node name="AnimatedSprite2D" type="AnimatedSprite2D"]
material = SubResource("ShaderMaterial_i05k5")
sprite_frames = SubResource("SpriteFrames_v8w1g")
animation = &"look_around"