implement basic power hit
This commit is contained in:
parent
1c3b7b6f32
commit
c2e3fa2ac2
14 changed files with 173 additions and 38 deletions
|
|
@ -111,6 +111,16 @@ p2_hit_right={
|
|||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194441,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
p1_power_hit={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":73,"key_label":0,"unicode":105,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
p2_power_hit={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194439,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[layer_names]
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ func _ready() -> void:
|
|||
launch()
|
||||
|
||||
|
||||
func launch(angle: float = 0) -> void:
|
||||
func launch(angle: float = 0, speed_override: float = 0) -> void:
|
||||
angle = randf_range(-PI/3, PI/3) + PI * float(randi()%2) if angle == 0 else angle
|
||||
linear_velocity = Vector2(cos(angle), sin(angle)) * randf_range(launch_speed.x, launch_speed.y)
|
||||
linear_velocity = Vector2(cos(angle), sin(angle)) * (randf_range(launch_speed.x, launch_speed.y) if speed_override == 0 else speed_override)
|
||||
var length: float = linear_velocity.length()/100
|
||||
play_animation(length)
|
||||
decelerate_to_stop(length*2)
|
||||
|
|
@ -45,15 +45,17 @@ func decelerate_to_stop(duration: float = 0.3) -> void: # Call this after colli
|
|||
)
|
||||
|
||||
|
||||
func _on_hit(hitbox: Area2D) -> void:
|
||||
func _on_hit(hitbox: Hit) -> void:
|
||||
print("area detected")
|
||||
if not is_hit:
|
||||
if hitbox.is_in_group("hit"):
|
||||
assert(hitbox.power_hit != null, "hit doesnt have correct metadata, is it a hit?")
|
||||
print("ball not hit yet")
|
||||
var player: Player = hitbox.get_parent()
|
||||
var timer: Timer = player.hit_timer
|
||||
var angle: float = randf_range(3*PI/4, PI/4) * (-1 if player.id == 1 else 1)
|
||||
launch(angle)
|
||||
var speed: float = randf_range(300, 350) if hitbox.power_hit else 0.0 # o.o
|
||||
launch(angle, speed)
|
||||
print("ball hit")
|
||||
if not timer.is_connected("timeout", _on_hit_end):
|
||||
timer.connect("timeout", _on_hit_end)
|
||||
|
|
|
|||
3
scenes/classes/hit.gd
Normal file
3
scenes/classes/hit.gd
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
class_name Hit extends Area2D
|
||||
|
||||
@export var power_hit: bool = false
|
||||
1
scenes/classes/hit.gd.uid
Normal file
1
scenes/classes/hit.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://b440ri3521uio
|
||||
14
scenes/classes/hit.tscn
Normal file
14
scenes/classes/hit.tscn
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://d04legmj3c42r"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b440ri3521uio" path="res://scenes/classes/hit.gd" id="1_udkr8"]
|
||||
|
||||
[node name="Hit2D" type="Area2D" groups=["hit"]]
|
||||
collision_layer = 64
|
||||
collision_mask = 0
|
||||
script = ExtResource("1_udkr8")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
rotation = 1.5707964
|
||||
debug_color = Color(0.6205005, 0.42311785, 0.8432588, 0.41960785)
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## Emitted when the state finishes and wants to transition to another state.
|
||||
@warning_ignore("unused_signal")
|
||||
signal finished(next_state_path: String, data: Dictionary[String, Variant])
|
||||
signal finished(next_state_path: String, data: Dictionary)
|
||||
|
||||
|
||||
## For 'ghost frame' update fix
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://d0c57c37o75b0"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://d0c57c37o75b0"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://d3qem75thpant" path="res://scenes/hit/assets/power_hit.png" id="1_g005q"]
|
||||
[ext_resource type="Script" uid="uid://b440ri3521uio" path="res://scenes/classes/hit.gd" id="1_kwsj5"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_g005q"]
|
||||
radius = 21.023796
|
||||
|
||||
[node name="Hit" type="Area2D" groups=["hit"]]
|
||||
[node name="PowerHit2D" type="Area2D" groups=["hit"]]
|
||||
collision_layer = 64
|
||||
collision_mask = 0
|
||||
script = ExtResource("1_kwsj5")
|
||||
power_hit = true
|
||||
metadata/_custom_type_script = "uid://b440ri3521uio"
|
||||
metadata/power_hit = true
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://px67runjx6ex"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://px67runjx6ex"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://c6a62gvw7218s" path="res://scenes/hit/assets/hit.png" id="1_wjo4f"]
|
||||
[ext_resource type="Script" uid="uid://b440ri3521uio" path="res://scenes/classes/hit.gd" id="1_dk3vy"]
|
||||
[ext_resource type="Texture2D" uid="uid://c6a62gvw7218s" path="res://scenes/hit/assets/hit.png" id="1_rmj1p"]
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_fxeki"]
|
||||
radius = 11.0
|
||||
height = 24.0
|
||||
|
||||
[node name="Hit" type="Area2D" groups=["hit"]]
|
||||
[node name="SmallHit2D" type="Area2D" groups=["hit"]]
|
||||
collision_layer = 64
|
||||
collision_mask = 0
|
||||
script = ExtResource("1_dk3vy")
|
||||
metadata/_custom_type_script = "uid://b440ri3521uio"
|
||||
metadata/power_hit = false
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
position = Vector2(7, -4)
|
||||
texture = ExtResource("1_wjo4f")
|
||||
texture = ExtResource("1_rmj1p")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(4, 1)
|
||||
|
|
@ -20,14 +20,18 @@ metadata/_edit_lock_ = true
|
|||
|
||||
[node name="Player1" parent="." instance=ExtResource("2_r0du0")]
|
||||
position = Vector2(141, 184)
|
||||
id = 1
|
||||
max_speed = 90.0
|
||||
|
||||
[node name="Player2" parent="." instance=ExtResource("2_r0du0")]
|
||||
position = Vector2(167, 77)
|
||||
id = 2
|
||||
max_speed = 90.0
|
||||
|
||||
[node name="Ball" parent="." instance=ExtResource("3_r0du0")]
|
||||
position = Vector2(162, 115)
|
||||
launch_speed = Vector2(150, 300)
|
||||
speed_mult = null
|
||||
|
||||
[node name="LevelCamera2D" parent="." instance=ExtResource("4_jyhfs")]
|
||||
ball_weight = 0.4
|
||||
|
|
|
|||
|
|
@ -9,19 +9,36 @@ const DEADZONE: float = 0.1
|
|||
@onready var anim_player: AnimationPlayer = $AnimationPlayer
|
||||
@onready var state_machine: StateMachine = $StateMachine
|
||||
@onready var hit_timer: Timer = $HitTimer
|
||||
@onready var power_timer: Timer = $PowerTimer
|
||||
|
||||
var anim_dir: String
|
||||
var def_dir: String
|
||||
var power_bar: float
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
assert(id == 1 or id == 2, "id ("+str(id)+") is invalid")
|
||||
anim_dir = 'up' if id == 1 else 'down'
|
||||
def_dir = 'idle_up' if id == 1 else 'idle_down'
|
||||
power_bar = 0
|
||||
hit_timer.connect("timeout", $StateMachine/Hitting._on_hit_end)
|
||||
power_timer.connect("timeout", func() -> void:
|
||||
print(power_bar)
|
||||
)
|
||||
|
||||
|
||||
func get_movement_vector() -> Vector2:
|
||||
var x_mov: float = Input.get_action_strength('p'+str(id)+'_move_right') - Input.get_action_strength('p'+str(id)+'_move_left')
|
||||
var y_mov: float = Input.get_action_strength('p'+str(id)+'_move_down') - Input.get_action_strength('p'+str(id)+'_move_up')
|
||||
return Vector2(x_mov, y_mov)
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("p"+str(id)+"_power_hit") and power_bar == 100:
|
||||
power_bar = 0
|
||||
state_machine.state.finished.emit(PlayerState.HITTING, {"hit": "power"})
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if Input.is_action_pressed("p"+str(id)+"_hit_left") and Input.is_action_pressed("p"+str(id)+"_hit_right"):
|
||||
if power_bar < 100: power_bar += 1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=38 format=3 uid="uid://642nm6c4mpxx"]
|
||||
[gd_scene load_steps=40 format=3 uid="uid://642nm6c4mpxx"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://rdqmsvofiots" path="res://scenes/player/player.gd" id="1_v6fml"]
|
||||
[ext_resource type="Texture2D" uid="uid://b8ptokcqwpdud" path="res://scenes/player/saffron.png" id="2_3li8b"]
|
||||
|
|
@ -363,11 +363,69 @@ tracks/1/keys = {
|
|||
"values": [0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_myrg7"]
|
||||
resource_name = "hit_power_up"
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("AnimatedSprite2D:animation")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [&"idle_up"]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("AnimatedSprite2D:frame")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [2]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_kvlxm"]
|
||||
resource_name = "hit_power_down"
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("AnimatedSprite2D:animation")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [&"idle_down"]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("AnimatedSprite2D:frame")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [2]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ugbui"]
|
||||
_data = {
|
||||
&"RESET": SubResource("Animation_gx1jg"),
|
||||
&"hit_left_down": SubResource("Animation_fcs02"),
|
||||
&"hit_left_up": SubResource("Animation_h17s1"),
|
||||
&"hit_power_down": SubResource("Animation_kvlxm"),
|
||||
&"hit_power_up": SubResource("Animation_myrg7"),
|
||||
&"hit_right_down": SubResource("Animation_ugbui"),
|
||||
&"hit_right_up": SubResource("Animation_je7p5"),
|
||||
&"idle_down": SubResource("Animation_fm80t"),
|
||||
|
|
@ -585,3 +643,7 @@ metadata/_custom_type_script = "uid://b2sr7p80gdjii"
|
|||
[node name="HitTimer" type="Timer" parent="."]
|
||||
wait_time = 0.5
|
||||
one_shot = true
|
||||
|
||||
[node name="PowerTimer" type="Timer" parent="."]
|
||||
wait_time = 0.847
|
||||
autostart = true
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ var hit_type: String
|
|||
var hit_node_ref: WeakRef
|
||||
|
||||
|
||||
func _enter(_previous_state_path: String, _data: Dictionary[String, Variant] = {}) -> void:
|
||||
func _enter(_previous_state_path: String, _data: Dictionary = {}) -> void:
|
||||
print("entering hitting")
|
||||
player.velocity = Vector2.ZERO
|
||||
player.move_and_slide()
|
||||
assert(
|
||||
_data.get("hit") == "left" or _data.get("hit") == "right",
|
||||
_data.get("hit") == "left" or
|
||||
_data.get("hit") == "right" or
|
||||
_data.get("hit") == "power",
|
||||
"Invalid hit_type ("+str(_data.get("hit"))+")."
|
||||
)
|
||||
print("previous state path: "+_previous_state_path)
|
||||
|
|
@ -28,28 +30,41 @@ func _enter(_previous_state_path: String, _data: Dictionary[String, Variant] = {
|
|||
player.anim_player.current_animation == "hit_left_up" or
|
||||
player.anim_player.current_animation == "hit_left_down" or
|
||||
player.anim_player.current_animation == "hit_right_up" or
|
||||
player.anim_player.current_animation == "hit_right_down",
|
||||
player.anim_player.current_animation == "hit_right_down" or
|
||||
player.anim_player.current_animation == "hit_power_up" or
|
||||
player.anim_player.current_animation == "hit_power_down",
|
||||
"invalid animation ("+player.anim_player.current_animation+")"
|
||||
)
|
||||
|
||||
var sprite_texture: Texture2D = player.sprite.sprite_frames.get_frame_texture('up', 1)
|
||||
var hit_node: Area2D = preload("res://scenes/hit/hit.tscn").instantiate()
|
||||
var sprite_texture: Texture2D = player.sprite.sprite_frames.get_frame_texture(player.sprite.animation, 1)
|
||||
var hit_node: Hit
|
||||
|
||||
# flip entire node horizontally if spawning left
|
||||
# flip vertically if player 2
|
||||
hit_node.scale = Vector2(
|
||||
-1 if hit_type == "left" else 1,
|
||||
1 if player.id == 1 else -1
|
||||
)
|
||||
player.add_child(hit_node)
|
||||
|
||||
# set position according to frame width and height
|
||||
@warning_ignore("integer_division")
|
||||
hit_node.global_position = player.global_position + Vector2(
|
||||
(sprite_texture.get_width()/2)*(-1 if hit_type == "left" else 1),
|
||||
(sprite_texture.get_height()*-1) if player.id == 1 else 4
|
||||
)
|
||||
if hit_type == "left" or hit_type == "right":
|
||||
hit_node = preload("res://scenes/hit/small_hit.tscn").instantiate()
|
||||
# flip entire node horizontally if spawning left
|
||||
# flip vertically if player 2
|
||||
hit_node.scale = Vector2(
|
||||
-1 if hit_type == "left" else 1,
|
||||
1 if player.id == 1 else -1
|
||||
)
|
||||
|
||||
player.add_child(hit_node)
|
||||
|
||||
# set position according to frame width and height
|
||||
@warning_ignore("integer_division")
|
||||
hit_node.global_position = player.global_position + Vector2(
|
||||
(sprite_texture.get_width()/2)*(-1 if hit_type == "left" else 1),
|
||||
(sprite_texture.get_height()*-1) if player.id == 1 else 4
|
||||
)
|
||||
elif hit_type == "power":
|
||||
hit_node = preload("res://scenes/hit/power_hit.tscn").instantiate()
|
||||
|
||||
player.add_child(hit_node)
|
||||
|
||||
@warning_ignore("integer_division")
|
||||
hit_node.global_position = player.global_position + Vector2(0,(sprite_texture.get_height()/2)*-1)
|
||||
|
||||
assert(hit_node != null, "hit_node is null")
|
||||
hit_node_ref = weakref(hit_node)
|
||||
|
||||
# cooldown
|
||||
|
|
@ -59,7 +74,7 @@ func _on_hit_end() -> void:
|
|||
print("cooldown end")
|
||||
assert(hit_node_ref != null, "hit node is null")
|
||||
|
||||
var hit_node: Area2D = hit_node_ref.get_ref()
|
||||
var hit_node: Hit = hit_node_ref.get_ref()
|
||||
if hit_node and is_instance_valid(hit_node):
|
||||
hit_node.queue_free()
|
||||
|
||||
|
|
@ -72,11 +87,11 @@ func _on_hit_end() -> void:
|
|||
print("transitioning to idling")
|
||||
finished.emit(IDLE)
|
||||
return
|
||||
elif Input.is_action_pressed('p'+str(player.id)+'_hit_left'):
|
||||
elif Input.is_action_just_pressed('p'+str(player.id)+'_hit_left'):
|
||||
print("transitioning to hitting left")
|
||||
finished.emit(HITTING, {"hit": "left"})
|
||||
return
|
||||
elif Input.is_action_pressed('p'+str(player.id)+'_hit_right'):
|
||||
elif Input.is_action_just_pressed('p'+str(player.id)+'_hit_right'):
|
||||
print("transitioning to hitting right")
|
||||
finished.emit(HITTING, {"hit": "right"})
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
extends PlayerState
|
||||
|
||||
|
||||
func _enter(_previous_state_path: String, _data: Dictionary[String, Variant] = {}) -> void:
|
||||
func _enter(_previous_state_path: String, _data: Dictionary = {}) -> void:
|
||||
print("entering idle")
|
||||
player.velocity = Vector2.ZERO
|
||||
player.move_and_slide()
|
||||
|
|
@ -21,9 +21,9 @@ func _state_physics_update(_delta: float) -> void:
|
|||
if movement_vector.length() > player.DEADZONE:
|
||||
finished.emit(RUNNING)
|
||||
return
|
||||
elif Input.is_action_pressed('p'+str(player.id)+'_hit_left'):
|
||||
elif Input.is_action_just_pressed('p'+str(player.id)+'_hit_left'):
|
||||
finished.emit(HITTING, {"hit": "left"})
|
||||
return
|
||||
elif Input.is_action_pressed('p'+str(player.id)+'_hit_right'):
|
||||
elif Input.is_action_just_pressed('p'+str(player.id)+'_hit_right'):
|
||||
finished.emit(HITTING, {"hit": "right"})
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
extends PlayerState
|
||||
|
||||
|
||||
func _enter(_previous_state_path: String, _data: Dictionary[String, Variant] = {}) -> void:
|
||||
func _enter(_previous_state_path: String, _data: Dictionary = {}) -> void:
|
||||
print("entering running")
|
||||
player.move_and_slide()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue