Code cleanup + state machine for player - WIP
This commit is contained in:
parent
628ad64eef
commit
3997d6e378
29 changed files with 1217 additions and 138 deletions
BIN
assets/HUD/time_hud.png
Normal file
BIN
assets/HUD/time_hud.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
34
assets/HUD/time_hud.png.import
Normal file
34
assets/HUD/time_hud.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/time_hud.png-0544f5cdebd62aa844aeedf56f01d694.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/HUD/time_hud.png"
|
||||
dest_files=[ "res://.import/time_hud.png-0544f5cdebd62aa844aeedf56f01d694.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=true
|
||||
svg/scale=1.0
|
|
@ -19,6 +19,16 @@ _global_script_classes=[ {
|
|||
"language": "GDScript",
|
||||
"path": "res://src/Items/Coin.gd"
|
||||
}, {
|
||||
"base": "Node2D",
|
||||
"class": "CutScene",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/Scripts/CutScene.gd"
|
||||
}, {
|
||||
"base": "Control",
|
||||
"class": "DialogBubble",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/CutScenes/DialogBubble/DialogBubble.gd"
|
||||
}, {
|
||||
"base": "KinematicBody2D",
|
||||
"class": "Enemy",
|
||||
"language": "GDScript",
|
||||
|
@ -42,6 +52,8 @@ _global_script_classes=[ {
|
|||
_global_script_class_icons={
|
||||
"CheckPoint": "",
|
||||
"Coin": "",
|
||||
"CutScene": "",
|
||||
"DialogBubble": "",
|
||||
"Enemy": "",
|
||||
"HUD": "",
|
||||
"Player": "",
|
||||
|
@ -61,11 +73,13 @@ config/icon="res://icon.png"
|
|||
|
||||
AudioManager="*res://src/Singletons/AudioManager.tscn"
|
||||
GameState="*res://src/Singletons/GameState.gd"
|
||||
Utils="*res://src/Singletons/Utils.gd"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/width=480
|
||||
window/size/height=270
|
||||
window/size/fullscreen=true
|
||||
window/stretch/mode="viewport"
|
||||
window/stretch/aspect="keep"
|
||||
|
||||
|
@ -79,6 +93,15 @@ theme/custom="res://assets/Theme/Theme.tres"
|
|||
|
||||
[input]
|
||||
|
||||
ui_accept={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777221,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777222,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
direction_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
|
||||
|
|
26
src/Actors/LightBeam.gd
Normal file
26
src/Actors/LightBeam.gd
Normal file
|
@ -0,0 +1,26 @@
|
|||
extends Particles2D
|
||||
|
||||
export var direction = Vector2.LEFT
|
||||
export var speed = 300
|
||||
|
||||
func _ready() -> void:
|
||||
$AnimationPlayer.play("lights_on")
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if emitting:
|
||||
position = position + (direction * speed * delta)
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_Area2D_body_entered(body: Node) -> void:
|
||||
call_deferred("_disable_area")
|
||||
emitting = false
|
||||
$AnimationPlayer.play("lights_out")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
queue_free()
|
||||
pass # Replace with function body.
|
||||
|
||||
func _disable_area():
|
||||
print("beam area off")
|
||||
$Area2D/CollisionShape2D.disabled = true
|
138
src/Actors/LightBeam.tscn
Normal file
138
src/Actors/LightBeam.tscn
Normal file
|
@ -0,0 +1,138 @@
|
|||
[gd_scene load_steps=11 format=2]
|
||||
|
||||
[ext_resource path="res://src/Actors/ligt_beam.png" type="Texture" id=1]
|
||||
[ext_resource path="res://src/Actors/LightBeam.gd" type="Script" id=2]
|
||||
|
||||
[sub_resource type="Gradient" id=1]
|
||||
offsets = PoolRealArray( 0, 0.189655, 0.366379, 0.616379, 1 )
|
||||
colors = PoolColorArray( 1, 1, 1, 1, 0, 0.992157, 0.894118, 1, 0.844238, 0.964844, 0.95297, 0.826387, 0.0330963, 0.941406, 0.852792, 0.712057, 0.0627451, 0.992157, 0.901961, 0.203922 )
|
||||
|
||||
[sub_resource type="GradientTexture" id=2]
|
||||
gradient = SubResource( 1 )
|
||||
|
||||
[sub_resource type="Curve" id=3]
|
||||
_data = [ Vector2( 0.00784314, 0.894318 ), 0.0, 1.34604, 0, 0, Vector2( 1, 0.237591 ), 0.0, 0.0, 0, 0 ]
|
||||
|
||||
[sub_resource type="CurveTexture" id=4]
|
||||
curve = SubResource( 3 )
|
||||
|
||||
[sub_resource type="ParticlesMaterial" id=5]
|
||||
emission_shape = 1
|
||||
emission_sphere_radius = 1.0
|
||||
flag_disable_z = true
|
||||
direction = Vector3( 0, 0, 0 )
|
||||
gravity = Vector3( 0, 0, 0 )
|
||||
angular_velocity = 0.2
|
||||
angular_velocity_random = 1.0
|
||||
orbit_velocity = 0.0
|
||||
orbit_velocity_random = 0.0
|
||||
angle = 90.0
|
||||
angle_random = 0.6
|
||||
scale = 0.7
|
||||
scale_random = 0.5
|
||||
scale_curve = SubResource( 4 )
|
||||
color_ramp = SubResource( 2 )
|
||||
|
||||
[sub_resource type="CircleShape2D" id=6]
|
||||
radius = 3.0
|
||||
|
||||
[sub_resource type="Animation" id=8]
|
||||
resource_name = "lights_on"
|
||||
length = 0.5
|
||||
loop = true
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("Light2D:texture_scale")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.25, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ 1.0, 1.5, 1.0 ]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/path = NodePath("Light2D:rotation_degrees")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/keys = {
|
||||
"times": PoolRealArray( 0, 0.25, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ 0.0, -86.4, 33.4 ]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id=7]
|
||||
resource_name = "lights_out"
|
||||
length = 0.5
|
||||
step = 0.25
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("Light2D:energy")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ 2.0, 0.0 ]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/path = NodePath("Light2D:texture_scale")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/keys = {
|
||||
"times": PoolRealArray( 0, 0.25, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ 2.0, 1.5, 2.0 ]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/path = NodePath("Light2D:rotation_degrees")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/keys = {
|
||||
"times": PoolRealArray( 0, 0.25, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ 0.0, -86.4, 0.0 ]
|
||||
}
|
||||
|
||||
[node name="LightBeam" type="Particles2D"]
|
||||
amount = 50
|
||||
lifetime = 0.4
|
||||
explosiveness = 0.1
|
||||
local_coords = false
|
||||
process_material = SubResource( 5 )
|
||||
texture = ExtResource( 1 )
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="Light2D" type="Light2D" parent="."]
|
||||
rotation = -0.253422
|
||||
texture = ExtResource( 1 )
|
||||
texture_scale = 0.8
|
||||
energy = 2.0
|
||||
range_item_cull_mask = 15375
|
||||
shadow_enabled = true
|
||||
shadow_item_cull_mask = 28
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
collision_layer = 0
|
||||
collision_mask = 2147483660
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
shape = SubResource( 6 )
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
autoplay = "lights_on"
|
||||
anims/lights_on = SubResource( 8 )
|
||||
anims/lights_out = SubResource( 7 )
|
||||
[connection signal="body_entered" from="Area2D" to="." method="_on_Area2D_body_entered"]
|
|
@ -9,12 +9,13 @@ export var gravity: = 500.0
|
|||
export var max_gravity:= 450.0
|
||||
export var respawn_position:=Vector2.ZERO
|
||||
export var wall_slide_friction:=.2
|
||||
export var wall_jump_speed_factor := Vector2(2.5 ,.85)
|
||||
export var wall_jump_speed_factor := Vector2(1 ,.8)
|
||||
export var dash_thrust = 500.0
|
||||
export var max_wall_slide_gravity := 100.0
|
||||
|
||||
var LandingDust = load("res://src/Actors/LandingDust.tscn")
|
||||
var JumpDust = load("res://src/Actors/JumpDust.tscn")
|
||||
var LightBeam = load("res://src/Actors/LightBeam.tscn")
|
||||
|
||||
|
||||
signal landed
|
||||
|
@ -23,13 +24,21 @@ signal died
|
|||
|
||||
var _velocity: Vector2 = Vector2.ZERO
|
||||
var _landing_position:Vector2 = Vector2.ZERO
|
||||
var _in_air = false;
|
||||
var _is_wall_jumping := false
|
||||
var _alive := false;
|
||||
var _is_wall_sliding := false;
|
||||
var _is_dashing := false;
|
||||
var _can_dash := true;
|
||||
var _is_attaking := false;
|
||||
var _alive := false
|
||||
var _can_dash := true
|
||||
var _is_jump_canceled := false
|
||||
var _direction := Vector2.ZERO
|
||||
|
||||
enum States {
|
||||
IDLE,
|
||||
IN_AIR,
|
||||
DASHING,
|
||||
WALL_SLIDING,
|
||||
ATTACKING
|
||||
}
|
||||
|
||||
var _state = States.IDLE
|
||||
|
||||
enum Direction{
|
||||
RIGHT = 1,
|
||||
|
@ -39,7 +48,8 @@ enum Direction{
|
|||
export var abilities:= {
|
||||
"dash": false,
|
||||
"wall_jump": false,
|
||||
"attack": false
|
||||
"attack": false,
|
||||
"light_beam": false
|
||||
}
|
||||
func _ready() -> void:
|
||||
$AnimationPlayer.play("fade_in")
|
||||
|
@ -47,92 +57,142 @@ func _ready() -> void:
|
|||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if _alive:
|
||||
var is_jump_canceled: = Input.is_action_just_released("jump") and !_is_wall_jumping and _velocity.y < 0.0
|
||||
var direction: = get_direction()
|
||||
var prev_wall_slide_state = _is_wall_sliding
|
||||
_is_wall_sliding = _velocity.y >=0 and is_on_wall() and _in_air
|
||||
_velocity = calculate_move_velocity(direction,is_jump_canceled, delta)
|
||||
if _is_wall_sliding and not prev_wall_slide_state:
|
||||
_velocity.y=0
|
||||
_update_state()
|
||||
_input_check()
|
||||
_velocity = calculate_move_velocity(_direction,_is_jump_canceled, delta)
|
||||
_velocity = move_and_slide(_velocity, Vector2.UP)
|
||||
update_sprite(direction)
|
||||
if is_on_floor() and !_is_dashing: _can_dash = true;
|
||||
if is_on_floor() and _in_air and !_is_dashing:
|
||||
var dust = LandingDust.instance()
|
||||
dust.position = position
|
||||
get_parent().add_child(dust)
|
||||
_in_air = false
|
||||
_is_wall_jumping = false
|
||||
emit_signal("landed", position)
|
||||
if _is_wall_sliding:
|
||||
_is_wall_jumping = false
|
||||
|
||||
func get_direction() -> Vector2:
|
||||
var right_strength = min(Input.get_action_strength("direction_right") , 1)
|
||||
var left_strength = min(Input.get_action_strength("direction_left"), 1)
|
||||
return Vector2(
|
||||
right_strength - left_strength if _in_air or not _is_attaking else 0,
|
||||
-1.0 if Input.is_action_just_pressed("jump") and (is_on_floor() or _is_wall_sliding) else 1.0
|
||||
)
|
||||
|
||||
func calculate_move_velocity(direction:Vector2, is_jump_canceled:bool, delta:float)->Vector2:
|
||||
var output: = _velocity
|
||||
|
||||
var current_gravity = gravity * wall_slide_friction if _is_wall_sliding else gravity
|
||||
|
||||
output.x = lerp(_velocity.x, run_speed * direction.x, .09 if _in_air else .5)
|
||||
|
||||
output.y += current_gravity * delta
|
||||
|
||||
if direction.y == -1.0: # we are jumping
|
||||
_in_air = true
|
||||
if _is_wall_sliding:
|
||||
# wall jump
|
||||
var walljump__x_direction = -1 * direction.x
|
||||
_is_wall_jumping = true
|
||||
var desired = (run_speed * wall_jump_speed_factor.x * walljump__x_direction)
|
||||
output.x = desired
|
||||
output.y = jump_power * wall_jump_speed_factor.y * direction.y
|
||||
else:
|
||||
#jump
|
||||
output.y = jump_power * direction.y
|
||||
var dust = JumpDust.instance()
|
||||
dust.position = position;
|
||||
get_parent().add_child(dust)
|
||||
emit_signal("jumping", position)
|
||||
|
||||
if not _is_dashing:
|
||||
if is_jump_canceled:
|
||||
output.y = 0
|
||||
if output.y < max_gravity * -1:
|
||||
output.y = max_gravity
|
||||
if output.y > 0 and !is_on_floor():
|
||||
_in_air = true;
|
||||
if _is_dashing:
|
||||
return _velocity
|
||||
|
||||
if _is_wall_sliding and output.y > max_wall_slide_gravity:
|
||||
output.y = max_wall_slide_gravity
|
||||
|
||||
var dash_velocity := Vector2(
|
||||
$Sprite.scale.x * dash_thrust,
|
||||
0
|
||||
)
|
||||
|
||||
if Input.is_action_just_pressed("dash") and _can_dash:
|
||||
update_sprite(_direction)
|
||||
|
||||
|
||||
func _input_check() -> void:
|
||||
if GameState.get_state() == GameState.States.GAME:
|
||||
_is_jump_canceled = Input.is_action_just_released("jump") and !_is_wall_jumping and _velocity.y < 0.0;
|
||||
_get_direction()
|
||||
_check_dash()
|
||||
if Input.is_action_just_pressed("attack") and abilities.attack:
|
||||
_attack()
|
||||
else:
|
||||
_direction = Vector2.ZERO
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func _update_state(new_state:int = -1):
|
||||
var auto_update = new_state == -1;
|
||||
if new_state == -1:
|
||||
new_state = _state
|
||||
if _state == States.DASHING: return
|
||||
if _state == States.ATTACKING: return
|
||||
if _state == States.IDLE:
|
||||
if _velocity.y > 0 and not is_on_floor():
|
||||
# Falling from ground
|
||||
new_state = States.IN_AIR
|
||||
elif _state == States.IN_AIR:
|
||||
if is_on_floor():
|
||||
_on_landed()
|
||||
new_state = States.IDLE
|
||||
elif _velocity.y >=0 and is_on_wall():
|
||||
if _state != States.WALL_SLIDING:
|
||||
_velocity.y=0
|
||||
new_state = States.WALL_SLIDING
|
||||
elif _state == States.WALL_SLIDING:
|
||||
if is_on_floor() or not is_on_wall():
|
||||
new_state = States.IDLE
|
||||
else: new_state = States.IDLE
|
||||
_transition_state(_state, new_state, auto_update)
|
||||
|
||||
func _transition_state(old_state, new_state, auto_update):
|
||||
if new_state != old_state:
|
||||
print("[Player]: State Update: [%s] -> [%s] | Automatic: %s" % [old_state, new_state, auto_update])
|
||||
_state = new_state
|
||||
if old_state == States.IDLE:
|
||||
# idle -> attak = ground attack - stop _velocity.x
|
||||
if new_state == States.ATTACKING:
|
||||
_direction.x = 0;
|
||||
_velocity.x = 0;
|
||||
if old_state == States.DASHING:
|
||||
if new_state == States.IDLE:
|
||||
_can_dash = true
|
||||
if old_state == States.WALL_SLIDING:
|
||||
if new_state == States.IDLE:
|
||||
_on_landed()
|
||||
|
||||
func _on_landed():
|
||||
_can_dash = true
|
||||
var dust = LandingDust.instance()
|
||||
dust.position = position
|
||||
get_parent().add_child(dust)
|
||||
emit_signal("landed", position)
|
||||
|
||||
func _on_jump(wall_jump:bool = false):
|
||||
var dust:Node = JumpDust.instance()
|
||||
dust.position = position;
|
||||
get_parent().add_child(dust)
|
||||
if wall_jump:
|
||||
dust.position.x += 2 * -$Sprite.scale.x
|
||||
dust.get_node("Sprite").rotate(deg2rad(90) * -$Sprite.scale.x)
|
||||
emit_signal("jumping", position)
|
||||
|
||||
func _get_direction() -> void:
|
||||
var right_strength = round(Input.get_action_strength("direction_right"))
|
||||
var left_strength = round(Input.get_action_strength("direction_left"))
|
||||
var vertical_movement = right_strength - left_strength if not _state == States.DASHING else 0
|
||||
var is_in_jumpable_state = _state == States.IDLE or _state == States.WALL_SLIDING
|
||||
_direction = Vector2(
|
||||
vertical_movement,
|
||||
-1.0 if Input.is_action_just_pressed("jump") and is_in_jumpable_state else 1.0
|
||||
)
|
||||
func _check_dash():
|
||||
if Input.is_action_just_pressed("dash") and _can_dash and abilities.dash:
|
||||
var dash_velocity := Vector2($Sprite.scale.x * dash_thrust,0)
|
||||
_can_dash = false
|
||||
_is_dashing = true # turn off gravity while dashing
|
||||
# Wall dash first
|
||||
if _is_wall_sliding:
|
||||
if _state == States.WALL_SLIDING:
|
||||
dash_velocity.x = $Sprite.scale.x * dash_thrust * -1
|
||||
|
||||
if dash_velocity.x < 0 :
|
||||
$DashParticlesLeft.emitting = true;
|
||||
else:
|
||||
$DashParticlesRight.emitting = true
|
||||
output = dash_velocity
|
||||
_velocity = dash_velocity
|
||||
$DashTimeout.start()
|
||||
_update_state(States.DASHING) # turn off gravity while dashing
|
||||
|
||||
func calculate_move_velocity(direction:Vector2, is_jump_canceled:bool, delta:float)->Vector2:
|
||||
var output: = _velocity
|
||||
var current_gravity = gravity * wall_slide_friction if _state == States.WALL_SLIDING else gravity
|
||||
|
||||
output.x = lerp(_velocity.x, run_speed * direction.x, .1 if _state == States.IN_AIR else .5)
|
||||
|
||||
output.y += current_gravity * delta
|
||||
|
||||
if _state == States.DASHING:
|
||||
return _velocity
|
||||
|
||||
if direction.y == -1.0: # we are jumping
|
||||
var wall_jump := false
|
||||
if _state == States.WALL_SLIDING and abilities.wall_jump:
|
||||
# wall jump
|
||||
wall_jump = true
|
||||
var walljump__x_direction = -1 * direction.x
|
||||
var desired = (run_speed * wall_jump_speed_factor.x * walljump__x_direction)
|
||||
output.x = desired
|
||||
output.y = jump_power * wall_jump_speed_factor.y * direction.y
|
||||
else:
|
||||
#jump
|
||||
output.y = jump_power * direction.y
|
||||
_update_state(States.IN_AIR)
|
||||
_on_jump(wall_jump)
|
||||
else:
|
||||
if is_jump_canceled:
|
||||
output.y = 0
|
||||
if output.y < max_gravity * -1:
|
||||
output.y = max_gravity
|
||||
|
||||
|
||||
if _state == States.WALL_SLIDING and output.y > max_wall_slide_gravity:
|
||||
output.y = max_wall_slide_gravity
|
||||
|
||||
return output;
|
||||
|
||||
|
@ -147,40 +207,45 @@ func _revive():
|
|||
|
||||
func update_sprite(_direction:Vector2) -> void:
|
||||
var air_animation = "jump" if _velocity.y <= 0 else "fall"
|
||||
if _is_attaking: return
|
||||
if _state == States.ATTACKING: return
|
||||
var attack = Input.is_action_just_pressed("attack") and abilities.attack
|
||||
if _velocity.x > .5 and not _is_wall_sliding:
|
||||
if _velocity.x > .5 and not _state == States.WALL_SLIDING:
|
||||
$Sprite.scale = Vector2(1,1)
|
||||
$AnimationPlayer.play("run" if is_on_floor() else air_animation)
|
||||
elif _velocity.x < -.5 and not _is_wall_sliding:
|
||||
elif _velocity.x < -.5 and not _state == States.WALL_SLIDING:
|
||||
$Sprite.scale = Vector2(-1,1)
|
||||
$AnimationPlayer.play("run" if is_on_floor() else air_animation)
|
||||
else:
|
||||
if not _in_air: $AnimationPlayer.play("idle")
|
||||
if not _state == States.IN_AIR: $AnimationPlayer.play("idle")
|
||||
|
||||
if _is_wall_sliding:
|
||||
if _state == States.WALL_SLIDING:
|
||||
$AnimationPlayer.play("wall_slide")
|
||||
return
|
||||
if attack:
|
||||
_is_attaking = true
|
||||
AudioManager.play_sfx(AudioManager.Sfx.PLAYER_ATTACK)
|
||||
var attack_animation = "attack_right" if $Sprite.scale.x > 0 else "attack_left"
|
||||
$AnimationPlayer.play(attack_animation)
|
||||
$AnimationPlayer.playback_speed = 2.5
|
||||
$AnimationPlayer.seek(0)
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
$AnimationPlayer.playback_speed = 1
|
||||
_is_attaking = false
|
||||
return
|
||||
if _in_air:
|
||||
if _state == States.IN_AIR:
|
||||
$AnimationPlayer.play(air_animation)
|
||||
return
|
||||
|
||||
if _is_dashing:
|
||||
if _state == States.DASHING:
|
||||
$AnimationPlayer.play("jump")
|
||||
return
|
||||
|
||||
|
||||
func _attack():
|
||||
if _state == States.DASHING:
|
||||
var beam = LightBeam.instance()
|
||||
beam.direction = Vector2($Sprite.scale.x, 0)
|
||||
beam.position = $Sprite/LightBeamInitPoint.get_global_transform().get_origin()
|
||||
get_parent().add_child(beam)
|
||||
$DashTimeout.stop()
|
||||
_on_DashTimeout_timeout(false)
|
||||
_update_state(States.ATTACKING)
|
||||
AudioManager.play_sfx(AudioManager.Sfx.PLAYER_ATTACK)
|
||||
var attack_animation = "attack_right" if $Sprite.scale.x > 0 else "attack_left"
|
||||
$AnimationPlayer.play(attack_animation)
|
||||
$AnimationPlayer.playback_speed = 2.5
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
$AnimationPlayer.seek(0)
|
||||
$AnimationPlayer.playback_speed = 1
|
||||
_update_state(States.IDLE)
|
||||
|
||||
func _on_die_animation_done():
|
||||
emit_signal("died")
|
||||
|
@ -201,11 +266,12 @@ func setAbility(ability:String, enabled:bool=false):
|
|||
else:
|
||||
pass
|
||||
|
||||
func _on_DashTimeout_timeout() -> void:
|
||||
func _on_DashTimeout_timeout(timed_out=true) -> void:
|
||||
$AnimationPlayer.playback_speed = 1
|
||||
$DashParticlesLeft.emitting = false
|
||||
$DashParticlesRight.emitting = false
|
||||
_velocity.x = run_speed * _velocity.normalized().x;
|
||||
_is_dashing = false
|
||||
if timed_out: _update_state(States.IN_AIR)
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
|
|
|
@ -836,6 +836,9 @@ collision_mask = 2
|
|||
position = Vector2( 14, -6 )
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="LightBeamInitPoint" type="Position2D" parent="Sprite"]
|
||||
position = Vector2( 14, 2 )
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
autoplay = "idle"
|
||||
anims/attack_left = SubResource( 3 )
|
||||
|
@ -881,5 +884,15 @@ position = Vector2( 0, -8.04107 )
|
|||
enabled = true
|
||||
cast_to = Vector2( -5.2, 0 )
|
||||
collision_mask = 8
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
current = true
|
||||
limit_left = -45
|
||||
limit_smoothed = true
|
||||
drag_margin_h_enabled = true
|
||||
drag_margin_v_enabled = true
|
||||
smoothing_enabled = true
|
||||
drag_margin_left = 0.09
|
||||
drag_margin_right = 0.09
|
||||
[connection signal="body_entered" from="Sprite/SordRange" to="." method="_on_SordRange_body_entered"]
|
||||
[connection signal="timeout" from="DashTimeout" to="." method="_on_DashTimeout_timeout"]
|
||||
|
|
33
src/Actors/WiseOldDude/WiseOldDude.tscn
Normal file
33
src/Actors/WiseOldDude/WiseOldDude.tscn
Normal file
|
@ -0,0 +1,33 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Actors/WiseOldDude/wize_old_dude.png" type="Texture" id=1]
|
||||
|
||||
[sub_resource type="Animation" id=1]
|
||||
resource_name = "idle"
|
||||
length = 0.8
|
||||
loop = true
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("Sprite:frame")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.2, 0.4, 0.6, 0.8 ),
|
||||
"transitions": PoolRealArray( 1, 1, 1, 1, 1 ),
|
||||
"update": 1,
|
||||
"values": [ 17, 18, 19, 20, 21 ]
|
||||
}
|
||||
|
||||
[node name="WiseOldDude" type="Node2D"]
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="."]
|
||||
position = Vector2( 0, -16 )
|
||||
texture = ExtResource( 1 )
|
||||
vframes = 6
|
||||
hframes = 9
|
||||
frame = 18
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
autoplay = "idle"
|
||||
anims/idle = SubResource( 1 )
|
BIN
src/Actors/WiseOldDude/wize_old_dude.png
Normal file
BIN
src/Actors/WiseOldDude/wize_old_dude.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
34
src/Actors/WiseOldDude/wize_old_dude.png.import
Normal file
34
src/Actors/WiseOldDude/wize_old_dude.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/wize_old_dude.png-2d29b22f4c54a0aed9056fec7199f29e.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/Actors/WiseOldDude/wize_old_dude.png"
|
||||
dest_files=[ "res://.import/wize_old_dude.png-2d29b22f4c54a0aed9056fec7199f29e.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=true
|
||||
svg/scale=1.0
|
BIN
src/Actors/ligt_beam.png
Normal file
BIN
src/Actors/ligt_beam.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 788 B |
34
src/Actors/ligt_beam.png.import
Normal file
34
src/Actors/ligt_beam.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ligt_beam.png-10d3dd70473d3611e41e8dbba9e0477b.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/Actors/ligt_beam.png"
|
||||
dest_files=[ "res://.import/ligt_beam.png-10d3dd70473d3611e41e8dbba9e0477b.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=true
|
||||
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=true
|
||||
svg/scale=1.0
|
101
src/CutScenes/ChallengeCutscene.gd
Normal file
101
src/CutScenes/ChallengeCutscene.gd
Normal file
|
@ -0,0 +1,101 @@
|
|||
extends CutScene
|
||||
var _dialog_bubble = load("res://src/CutScenes/DialogBubble/DialogBubble.tscn")
|
||||
var _old_man_dialog = [
|
||||
{
|
||||
"text": "Hi there young one!",
|
||||
"callback": null
|
||||
},
|
||||
{
|
||||
"text": "You do look stupid enough\nfor my challenge...",
|
||||
"callback": null
|
||||
},
|
||||
{
|
||||
"text": "You see that tree over there?",
|
||||
"callback": null
|
||||
},
|
||||
]
|
||||
var _old_man_dialog2 = [
|
||||
{
|
||||
"text": "Oh, yeah - not there...",
|
||||
"callback": null
|
||||
},
|
||||
{
|
||||
"text": "Forgive me, never thought you would really take a look",
|
||||
"callback": null
|
||||
},
|
||||
{
|
||||
"text": "Never mind Bro. See the path ahead? There is a tree in that cave.",
|
||||
"callback": null
|
||||
},
|
||||
]
|
||||
|
||||
func start_scene(camera:Camera2D):
|
||||
_main_camera_ref = camera
|
||||
position = camera.get_global_transform().get_origin()
|
||||
_camera = camera.duplicate()
|
||||
add_child(_camera)
|
||||
_main_camera_ref.current = false
|
||||
_camera.current = true
|
||||
|
||||
$AnimationPlayer.play("start")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
|
||||
yield(get_tree().create_timer(.5), "timeout")
|
||||
|
||||
|
||||
# Dialog 1
|
||||
$AnimationPlayer.play("old_dude_slide_in")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
|
||||
var dialog_bubble:DialogBubble = _dialog_bubble.instance()
|
||||
dialog_bubble.allow_fast_skip = bool(GameState.get_statistics().total_time_played)
|
||||
dialog_bubble.dialog = _old_man_dialog
|
||||
$Overlay.add_child(dialog_bubble)
|
||||
dialog_bubble.start_dialog()
|
||||
yield(dialog_bubble, "dialog_finished")
|
||||
|
||||
$AnimationPlayer.play("old_dude_slide_out")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
|
||||
# pan Camera
|
||||
$Tween.interpolate_property(_camera, "position", _camera.position, Vector2( _camera.position.x - 400, _camera.position.y), 2)
|
||||
$Tween.start()
|
||||
yield($Tween, "tween_completed")
|
||||
|
||||
# wait a bit to get a "haha" timing
|
||||
yield(get_tree().create_timer(2), "timeout")
|
||||
|
||||
#pan back
|
||||
$Tween.interpolate_property(_camera, "position", _camera.position, _camera.get_parent().position, 2, Tween.TRANS_BOUNCE, Tween.EASE_OUT)
|
||||
$Tween.start()
|
||||
yield($Tween, "tween_completed")
|
||||
camera.get_parent()._velocity.y = -100
|
||||
# Dialog 2
|
||||
$AnimationPlayer.play("old_dude_slide_in")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
|
||||
dialog_bubble = _dialog_bubble.instance()
|
||||
dialog_bubble.dialog = _old_man_dialog2
|
||||
$Overlay.add_child(dialog_bubble)
|
||||
dialog_bubble.start_dialog()
|
||||
yield(dialog_bubble, "dialog_finished")
|
||||
|
||||
$AnimationPlayer.play("old_dude_slide_out")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
|
||||
#
|
||||
|
||||
|
||||
_on_scene_exited()
|
||||
pass
|
||||
|
||||
|
||||
|
||||
func _on_scene_exited():
|
||||
$Tween.interpolate_property(_camera, "position", _camera.position, _camera.get_parent().position, 2, Tween.TRANS_BOUNCE, Tween.EASE_OUT)
|
||||
$Tween.start()
|
||||
yield($Tween, "tween_completed")
|
||||
_main_camera_ref.current = true
|
||||
$AnimationPlayer.play_backwards("start")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
end_scene()
|
112
src/CutScenes/ChallengeCutscene.tscn
Normal file
112
src/CutScenes/ChallengeCutscene.tscn
Normal file
|
@ -0,0 +1,112 @@
|
|||
[gd_scene load_steps=6 format=2]
|
||||
|
||||
[ext_resource path="res://src/CutScenes/ChallengeCutscene.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/CutScenes/red-wizzard-large.png" type="Texture" id=2]
|
||||
|
||||
[sub_resource type="Animation" id=1]
|
||||
resource_name = "old_dude_slide_in"
|
||||
length = 0.5
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("Overlay/FigureOldDude:offset")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ Vector2( 900, 50 ), Vector2( 600, 50 ) ]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id=2]
|
||||
resource_name = "old_dude_slide_out"
|
||||
length = 0.5
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("Overlay/FigureOldDude:offset")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ Vector2( 600, 50 ), Vector2( 900, 50 ) ]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id=3]
|
||||
length = 0.2
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("Overlay/ColorRect2:rect_position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.2 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ Vector2( 0, 270 ), Vector2( 0, 245 ) ]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/path = NodePath("Overlay/ColorRect:rect_position")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/keys = {
|
||||
"times": PoolRealArray( 0, 0.2 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ Vector2( 0, -25 ), Vector2( 0, 0 ) ]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/path = NodePath("Overlay/FigureOldDude:offset")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/keys = {
|
||||
"times": PoolRealArray( 0 ),
|
||||
"transitions": PoolRealArray( 1 ),
|
||||
"update": 0,
|
||||
"values": [ Vector2( 900, 50 ) ]
|
||||
}
|
||||
|
||||
[node name="ChallengeCutscene" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Overlay" type="CanvasLayer" parent="."]
|
||||
layer = 2
|
||||
|
||||
[node name="FigureOldDude" type="Sprite" parent="Overlay"]
|
||||
scale = Vector2( 0.533333, 0.533333 )
|
||||
texture = ExtResource( 2 )
|
||||
centered = false
|
||||
offset = Vector2( 600, 50 )
|
||||
flip_h = true
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="Overlay"]
|
||||
margin_top = -25.0
|
||||
margin_right = 480.0
|
||||
color = Color( 0, 0, 0, 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Overlay"]
|
||||
margin_top = 270.0
|
||||
margin_right = 480.0
|
||||
margin_bottom = 295.0
|
||||
color = Color( 0, 0, 0, 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
anims/old_dude_slide_in = SubResource( 1 )
|
||||
anims/old_dude_slide_out = SubResource( 2 )
|
||||
anims/start = SubResource( 3 )
|
||||
|
||||
[node name="Tween" type="Tween" parent="."]
|
49
src/CutScenes/DialogBubble/DialogBubble.gd
Normal file
49
src/CutScenes/DialogBubble/DialogBubble.gd
Normal file
|
@ -0,0 +1,49 @@
|
|||
extends Control
|
||||
class_name DialogBubble
|
||||
signal dialog_finished
|
||||
|
||||
var allow_fast_skip := false
|
||||
|
||||
var dialog = [] # Dictionary[] {text:string, callback:function}[]
|
||||
var _position := 0
|
||||
var _done := false
|
||||
var _paused := false
|
||||
var _started :=false
|
||||
func resume_dialog():
|
||||
_paused = false
|
||||
func start_dialog():
|
||||
$AnimationPlayer.play("slide_in")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
_started = true
|
||||
_show_text()
|
||||
|
||||
func _show_text():
|
||||
if _position >= dialog.size():
|
||||
# we are done
|
||||
_done = true
|
||||
dismiss()
|
||||
return
|
||||
var sentence = dialog[_position]
|
||||
$NinePatchRect/Label.text = sentence.text
|
||||
$AnimationPlayer.play("show_text")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
if sentence.callback != null:
|
||||
sentence.callback()
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if not _started: return
|
||||
if Input.is_action_just_pressed("jump"):
|
||||
if allow_fast_skip: dismiss()
|
||||
else:
|
||||
_position += 1
|
||||
$AnimationPlayer.play_backwards("show_text")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
_show_text()
|
||||
|
||||
|
||||
|
||||
func dismiss():
|
||||
$AnimationPlayer.play_backwards("slide_in")
|
||||
yield($AnimationPlayer, "animation_finished")
|
||||
emit_signal("dialog_finished")
|
||||
queue_free()
|
107
src/CutScenes/DialogBubble/DialogBubble.tscn
Normal file
107
src/CutScenes/DialogBubble/DialogBubble.tscn
Normal file
|
@ -0,0 +1,107 @@
|
|||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource path="res://src/CutScenes/DialogBubble/DialogBubble.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/CutScenes/DialogBubble/hud_stats_bg.png" type="Texture" id=2]
|
||||
[ext_resource path="res://assets/Theme/slkscr.ttf" type="DynamicFontData" id=3]
|
||||
|
||||
[sub_resource type="DynamicFont" id=1]
|
||||
size = 17
|
||||
outline_size = 1
|
||||
outline_color = Color( 0, 0, 0, 1 )
|
||||
font_data = ExtResource( 3 )
|
||||
|
||||
[sub_resource type="Animation" id=2]
|
||||
resource_name = "show_text"
|
||||
length = 0.2
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("NinePatchRect/Label:modulate")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.2 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id=3]
|
||||
length = 0.5
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("NinePatchRect:margin_bottom")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ 135.0, -15.0 ]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/path = NodePath("NinePatchRect:margin_top")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/keys = {
|
||||
"times": PoolRealArray( 0, 0.5 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ 300.0, 150.0 ]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/path = NodePath("NinePatchRect/Label:modulate")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/keys = {
|
||||
"times": PoolRealArray( 0 ),
|
||||
"transitions": PoolRealArray( 1 ),
|
||||
"update": 0,
|
||||
"values": [ Color( 1, 1, 1, 0 ) ]
|
||||
}
|
||||
|
||||
[node name="DialogBubble" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="NinePatchRect" type="NinePatchRect" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 40.0
|
||||
margin_top = 300.0
|
||||
margin_right = -40.0
|
||||
margin_bottom = 135.0
|
||||
texture = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Label" type="Label" parent="NinePatchRect"]
|
||||
modulate = Color( 1, 1, 1, 0 )
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 20.0
|
||||
margin_top = 20.0
|
||||
margin_right = -20.0
|
||||
margin_bottom = -20.0
|
||||
custom_fonts/font = SubResource( 1 )
|
||||
custom_colors/font_color = Color( 1, 1, 1, 0.890196 )
|
||||
text = "Hello there young one!"
|
||||
align = 1
|
||||
autowrap = true
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
anims/show_text = SubResource( 2 )
|
||||
anims/slide_in = SubResource( 3 )
|
BIN
src/CutScenes/DialogBubble/hud_stats_bg.png
Normal file
BIN
src/CutScenes/DialogBubble/hud_stats_bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
34
src/CutScenes/DialogBubble/hud_stats_bg.png.import
Normal file
34
src/CutScenes/DialogBubble/hud_stats_bg.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/hud_stats_bg.png-52f55fa7703387ba6f7baf17aea738e4.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/CutScenes/DialogBubble/hud_stats_bg.png"
|
||||
dest_files=[ "res://.import/hud_stats_bg.png-52f55fa7703387ba6f7baf17aea738e4.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=true
|
||||
svg/scale=1.0
|
BIN
src/CutScenes/red-wizzard-large.png
Normal file
BIN
src/CutScenes/red-wizzard-large.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
34
src/CutScenes/red-wizzard-large.png.import
Normal file
34
src/CutScenes/red-wizzard-large.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/red-wizzard-large.png-bc152bcfbf1b2206bc916eefc4b9a5e6.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/CutScenes/red-wizzard-large.png"
|
||||
dest_files=[ "res://.import/red-wizzard-large.png-bc152bcfbf1b2206bc916eefc4b9a5e6.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=true
|
||||
svg/scale=1.0
|
27
src/GameWorld/GameWorld.gd
Normal file
27
src/GameWorld/GameWorld.gd
Normal file
|
@ -0,0 +1,27 @@
|
|||
extends Node2D
|
||||
|
||||
|
||||
var _Cutscenes = {
|
||||
"old_man_intro": "res://src/CutScenes/ChallengeCutscene.tscn"
|
||||
}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$Player/Camera2D.limit_bottom = 250
|
||||
$Player/Camera2D.limit_left = -45
|
||||
$Player/Camera2D.limit_right = 700
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_OldDudeIntroArea_body_entered(body: Node) -> void:
|
||||
if body.name == 'Player':
|
||||
AudioManager.play_music(AudioManager.Music.Abandon)
|
||||
GameState.start_cutscene()
|
||||
var scene = (load(_Cutscenes.old_man_intro)).instance()
|
||||
add_child(scene)
|
||||
scene.start_scene($Player/Camera2D)
|
||||
yield(scene, "cutscene_finished")
|
||||
GameState.end_cutscene()
|
||||
pass # Replace with function body.
|
121
src/GameWorld/GameWorld.tscn
Normal file
121
src/GameWorld/GameWorld.tscn
Normal file
File diff suppressed because one or more lines are too long
|
@ -16,18 +16,24 @@ func _physics_process(delta: float) -> void:
|
|||
var fresh_data = GameState.get_run_data()
|
||||
for key in fresh_data:
|
||||
if not fresh_data[key] == _data_ref[key]:
|
||||
print("[%s]: %s -> %s" % [str(key), str(_data_ref[key]), str(fresh_data[key])])
|
||||
match(str(key)):
|
||||
"coins":
|
||||
$UI/CoinLabel.text = str(fresh_data.coins)
|
||||
$UI/CoinLabel/AnimationPlayer.seek(0)
|
||||
$UI/CoinLabel/AnimationPlayer.play("updated")
|
||||
_play_update_label_animation($UI/CoinLabel/AnimationPlayer)
|
||||
"deaths":
|
||||
$UI/DeathsLabel.text = str(fresh_data.deaths)
|
||||
_play_update_label_animation($UI/DeathsLabel/AnimationPlayer)
|
||||
"time":
|
||||
var time_remaining = (GameState.GAME_TIMEOUT_MIN * 60) - fresh_data.time
|
||||
$UI/TimeLabel.text = Utils.parse_seconds_to_display_str(time_remaining)
|
||||
|
||||
pass
|
||||
_data_ref = fresh_data
|
||||
|
||||
func _play_update_label_animation(player:AnimationPlayer):
|
||||
player.seek(0)
|
||||
player.play("updated")
|
||||
|
||||
func _handle_pause():
|
||||
if Input.is_action_just_pressed("pause"):
|
||||
if _paused:
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
[gd_scene load_steps=7 format=2]
|
||||
[gd_scene load_steps=9 format=2]
|
||||
|
||||
[ext_resource path="res://src/HUD/HUD.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/Menu/PauseMenu.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://assets/Theme/Theme.tres" type="Theme" id=3]
|
||||
[ext_resource path="res://assets/HUD/coins_hud.png" type="Texture" id=4]
|
||||
[ext_resource path="res://assets/HUD/lifes_icon.png" type="Texture" id=5]
|
||||
[ext_resource path="res://assets/HUD/time_hud.png" type="Texture" id=6]
|
||||
|
||||
[sub_resource type="Animation" id=1]
|
||||
resource_name = "updated"
|
||||
|
@ -22,6 +23,22 @@ tracks/0/keys = {
|
|||
"values": [ Vector2( 2, 2 ), Vector2( 1, 1 ) ]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id=2]
|
||||
resource_name = "updated"
|
||||
length = 0.2
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath(".:rect_scale")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.2 ),
|
||||
"transitions": PoolRealArray( 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ Vector2( 2, 2 ), Vector2( 1, 1 ) ]
|
||||
}
|
||||
|
||||
[node name="HUD" type="CanvasLayer"]
|
||||
script = ExtResource( 1 )
|
||||
PauseMenu = ExtResource( 2 )
|
||||
|
@ -35,10 +52,11 @@ __meta__ = {
|
|||
|
||||
[node name="Coin" type="TextureRect" parent="UI"]
|
||||
margin_left = 18.0
|
||||
margin_top = 13.0
|
||||
margin_right = 27.0
|
||||
margin_top = 8.0
|
||||
margin_right = 32.0
|
||||
margin_bottom = 22.0
|
||||
texture = ExtResource( 4 )
|
||||
expand = true
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
@ -58,18 +76,18 @@ __meta__ = {
|
|||
anims/updated = SubResource( 1 )
|
||||
|
||||
[node name="Deaths" type="TextureRect" parent="UI"]
|
||||
margin_left = 11.0
|
||||
margin_top = 22.0
|
||||
margin_right = 33.0
|
||||
margin_bottom = 44.0
|
||||
margin_left = 80.0
|
||||
margin_top = 4.0
|
||||
margin_right = 102.0
|
||||
margin_bottom = 26.0
|
||||
texture = ExtResource( 5 )
|
||||
expand = true
|
||||
|
||||
[node name="DeathsLabel" type="Label" parent="UI"]
|
||||
margin_left = 38.0
|
||||
margin_top = 30.0
|
||||
margin_right = 78.0
|
||||
margin_bottom = 44.0
|
||||
margin_left = 107.0
|
||||
margin_top = 13.0
|
||||
margin_right = 147.0
|
||||
margin_bottom = 27.0
|
||||
theme = ExtResource( 3 )
|
||||
text = "0"
|
||||
__meta__ = {
|
||||
|
@ -77,3 +95,26 @@ __meta__ = {
|
|||
}
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="UI/DeathsLabel"]
|
||||
anims/updated = SubResource( 2 )
|
||||
|
||||
[node name="Time" type="TextureRect" parent="UI"]
|
||||
margin_left = 152.0
|
||||
margin_top = 8.0
|
||||
margin_right = 167.0
|
||||
margin_bottom = 23.0
|
||||
texture = ExtResource( 6 )
|
||||
expand = true
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="TimeLabel" type="Label" parent="UI"]
|
||||
margin_left = 174.0
|
||||
margin_top = 13.0
|
||||
margin_right = 214.0
|
||||
margin_bottom = 27.0
|
||||
theme = ExtResource( 3 )
|
||||
text = "0"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
|
|
@ -8,27 +8,27 @@
|
|||
[ext_resource path="res://src/Menu/MainMenu.gd" type="Script" id=6]
|
||||
[ext_resource path="res://assets/Theme/menu_font.tres" type="DynamicFont" id=7]
|
||||
|
||||
[sub_resource type="Gradient" id=2]
|
||||
[sub_resource type="Gradient" id=1]
|
||||
colors = PoolColorArray( 0.996094, 0.996094, 0.996094, 1, 1, 1, 1, 0 )
|
||||
|
||||
[sub_resource type="GradientTexture" id=3]
|
||||
gradient = SubResource( 2 )
|
||||
[sub_resource type="GradientTexture" id=2]
|
||||
gradient = SubResource( 1 )
|
||||
|
||||
[sub_resource type="Curve" id=7]
|
||||
[sub_resource type="Curve" id=3]
|
||||
min_value = -200.0
|
||||
max_value = 200.0
|
||||
_data = [ Vector2( 0, 7.83957 ), 0.0, 166.434, 0, 0, Vector2( 1, 44.2032 ), -4.82953, 0.0, 0, 0 ]
|
||||
|
||||
[sub_resource type="CurveTexture" id=8]
|
||||
curve = SubResource( 7 )
|
||||
[sub_resource type="CurveTexture" id=4]
|
||||
curve = SubResource( 3 )
|
||||
|
||||
[sub_resource type="Curve" id=4]
|
||||
[sub_resource type="Curve" id=5]
|
||||
_data = [ Vector2( 0, 0.285227 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 0.0, 0.0, 0, 0 ]
|
||||
|
||||
[sub_resource type="CurveTexture" id=5]
|
||||
curve = SubResource( 4 )
|
||||
[sub_resource type="CurveTexture" id=6]
|
||||
curve = SubResource( 5 )
|
||||
|
||||
[sub_resource type="ParticlesMaterial" id=6]
|
||||
[sub_resource type="ParticlesMaterial" id=7]
|
||||
emission_shape = 2
|
||||
emission_box_extents = Vector3( 10, 1, 1 )
|
||||
flag_disable_z = true
|
||||
|
@ -39,14 +39,13 @@ initial_velocity = 20.0
|
|||
initial_velocity_random = 0.7
|
||||
orbit_velocity = 0.0
|
||||
orbit_velocity_random = 0.0
|
||||
linear_accel_curve = SubResource( 8 )
|
||||
linear_accel_curve = SubResource( 4 )
|
||||
scale = 3.0
|
||||
scale_random = 1.0
|
||||
scale_curve = SubResource( 5 )
|
||||
color_ramp = SubResource( 3 )
|
||||
scale_curve = SubResource( 6 )
|
||||
color_ramp = SubResource( 2 )
|
||||
|
||||
[sub_resource type="Animation" id=1]
|
||||
resource_name = "main"
|
||||
[sub_resource type="Animation" id=8]
|
||||
length = 6.0
|
||||
loop = true
|
||||
step = 1.0
|
||||
|
@ -160,7 +159,7 @@ amount = 50
|
|||
lifetime = 2.5
|
||||
speed_scale = 0.4
|
||||
explosiveness = 0.1
|
||||
process_material = SubResource( 6 )
|
||||
process_material = SubResource( 7 )
|
||||
|
||||
[node name="Sprite3" type="Sprite" parent="Node2D"]
|
||||
light_mask = 4
|
||||
|
@ -170,7 +169,7 @@ centered = false
|
|||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="Node2D"]
|
||||
autoplay = "main"
|
||||
anims/main = SubResource( 1 )
|
||||
anims/main = SubResource( 8 )
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ pause_mode = 2
|
|||
script = ExtResource( 3 )
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
layer = 3
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="CanvasLayer"]
|
||||
self_modulate = Color( 1, 1, 1, 0 )
|
||||
|
|
21
src/Scripts/CutScene.gd
Normal file
21
src/Scripts/CutScene.gd
Normal file
|
@ -0,0 +1,21 @@
|
|||
extends Node2D
|
||||
|
||||
class_name CutScene
|
||||
|
||||
signal cutscene_finished
|
||||
|
||||
export var scene:PackedScene
|
||||
|
||||
var _main_camera_ref:Camera2D
|
||||
var _camera:Camera2D
|
||||
|
||||
|
||||
func start_scene(camera:Camera2D):
|
||||
var scene_inst = scene.instance()
|
||||
add_child(scene_inst)
|
||||
scene_inst.connect("tree_exited", self, "_on_scene_exited")
|
||||
pass
|
||||
|
||||
func end_scene():
|
||||
emit_signal("cutscene_finished")
|
||||
queue_free()
|
|
@ -8,7 +8,7 @@ enum States{
|
|||
GAME,
|
||||
PUSE,
|
||||
STATS,
|
||||
CUT_SCENE,
|
||||
CUTSCENE,
|
||||
}
|
||||
var _SAVE_FILE_PATH = "user://data"
|
||||
# Change key in release
|
||||
|
@ -16,9 +16,11 @@ var _ENCRYPTION_KEY = "fas3uyf076HJsiUDs24dfI9"
|
|||
|
||||
var _SCENES := {
|
||||
States.MAIN_MENU: "res://src/Menu/MainMenu.tscn",
|
||||
States.GAME: "res://src/Levels/LevelTemplate/LevelTemplate.tscn",
|
||||
States.GAME: "res://src/GameWorld/GameWorld.tscn",
|
||||
}
|
||||
|
||||
var GAME_TIMEOUT_MIN = 10
|
||||
|
||||
var _data := {
|
||||
"statistics": {
|
||||
"deaths": 0,
|
||||
|
@ -51,6 +53,11 @@ var _state = States.INTRO
|
|||
func _ready() -> void:
|
||||
load_data()
|
||||
print(get_statistics())
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if _state == States.GAME:
|
||||
_run_data.time += delta
|
||||
_data.statistics.total_time_played += delta
|
||||
|
||||
func load_data():
|
||||
var data_file = File.new()
|
||||
|
@ -77,13 +84,18 @@ func start_new_game():
|
|||
_data.statistics.runs += 1
|
||||
save_data()
|
||||
get_tree().change_scene_to(load(_SCENES[_state]))
|
||||
func start_cutscene():
|
||||
_state = States.CUTSCENE
|
||||
func end_cutscene():
|
||||
_state = States.GAME
|
||||
func get_heigh_score():
|
||||
return _data.heigh_score.duplicate()
|
||||
func get_statistics():
|
||||
return _data.statistics.duplicate()
|
||||
func get_run_data():
|
||||
return _run_data.duplicate()
|
||||
|
||||
func get_state():
|
||||
return int(_state)
|
||||
func go_to_main_menu():
|
||||
_state = States.MAIN_MENU
|
||||
save_data()
|
||||
|
|
13
src/Singletons/Utils.gd
Normal file
13
src/Singletons/Utils.gd
Normal file
|
@ -0,0 +1,13 @@
|
|||
extends Node
|
||||
|
||||
func parse_seconds_to_display_str(_seconds:float, show_hours:bool=false)->String:
|
||||
var rounded_input = int(floor(_seconds))
|
||||
var hours_in_seconds = 3600
|
||||
var minute_in_seconds = 60
|
||||
|
||||
var hours = 0
|
||||
var minutes_seconds_str = "%02d:%02d" % [(rounded_input / minute_in_seconds) % 60, rounded_input % 60]
|
||||
if show_hours:
|
||||
return "%02d:%s" % [floor(rounded_input / hours_in_seconds), minutes_seconds_str]
|
||||
return minutes_seconds_str
|
||||
|
Loading…
Reference in a new issue