190 lines
5.3 KiB
GDScript
190 lines
5.3 KiB
GDScript
extends "res://objects/characters/character.gd"
|
|
|
|
const SPEED = 400
|
|
const JUMP_HEIGHT = 1000
|
|
const STRIKED_HEIGHT = 400
|
|
export var background_scene : Resource
|
|
|
|
onready var level = get_parent()
|
|
onready var main = level.get_parent()
|
|
|
|
const ANIMATIONS = {
|
|
"idle": {
|
|
"animation": "idle",
|
|
"transistion": "idle",
|
|
"blocks": []
|
|
},
|
|
"run": {
|
|
"animation": "run",
|
|
"transistion": "run",
|
|
"blocks": []
|
|
},
|
|
"jump_start": {
|
|
"animation": "jump_start",
|
|
"transistion": "jump",
|
|
"blocks": ["idle", "run", "fall_start", "fall", "fall_end"]
|
|
},
|
|
"jump": {
|
|
"animation": "jump",
|
|
"transistion": "jump",
|
|
"blocks": ["idle", "run", "fall_start", "fall", "fall_end", "jump_start"]
|
|
},
|
|
"jump_end": {
|
|
"animation": "jump_end",
|
|
"transistion": "idle",
|
|
"blocks": ["idle", "run", "fall_start", "fall", "fall_end", "jump"]
|
|
},
|
|
"fall_start": {
|
|
"animation": "fall_start",
|
|
"transistion": "fall",
|
|
"blocks": ["idle", "run", "fall", "fall_end", "jump_start", "jump", "jump_end"]
|
|
},
|
|
"fall": {
|
|
"animation": "fall",
|
|
"transistion": "fall",
|
|
"blocks": ["idle", "run", "fall_start", "jump_start", "jump", "jump_end"]
|
|
},
|
|
"fall_end": {
|
|
"animation": "fall_end",
|
|
"transistion": "idle",
|
|
"blocks": ["idle", "run", "fall_start", "fall", "jump_start", "jump", "jump_end"]
|
|
},
|
|
"striked_start": {
|
|
"animation": "jump_start",
|
|
"transistion": "striked",
|
|
"blocks": ["idle", "run", "fall_start", "fall", "fall_end", "jump_start", "jump", "jump_end"]
|
|
},
|
|
"striked": {
|
|
"animation": "jump",
|
|
"transistion": "striked_end",
|
|
"blocks": ["idle", "run", "fall_start", "fall", "fall_end", "jump_start", "jump", "jump_end"]
|
|
},
|
|
"striked_end": {
|
|
"animation": "hurt",
|
|
"transistion": "idle",
|
|
"blocks": ["idle", "run", "fall_start", "fall", "fall_end", "jump_start", "jump", "jump_end"]
|
|
}
|
|
}
|
|
var player_state = "idle"
|
|
var invincible_hit = false
|
|
|
|
var score = 0
|
|
|
|
func _ready():
|
|
$Camera2D.add_child(background_scene.instance())
|
|
$Sprite.connect("animation_finished", self, "_next_player_state")
|
|
$Sprite.animation = ANIMATIONS[player_state]['animation']
|
|
$Camera2D.limit_left = level.camera_limit_left
|
|
$Camera2D.limit_right = level.camera_limit_right
|
|
$Camera2D.limit_top = level.camera_limit_top
|
|
$Camera2D.limit_bottom = level.camera_limit_bottom
|
|
yield(get_tree().create_timer(0.5), "timeout")
|
|
$Camera2D.smoothing_enabled = true
|
|
|
|
func _physics_process(delta):
|
|
# out-of-screen checking
|
|
if position.y > level.camera_limit_bottom and health > 0:
|
|
_add_damage(100)
|
|
|
|
# Fall animation if not on floor
|
|
if velocity.y > 1 and not is_on_floor():
|
|
_set_player_state("fall_start")
|
|
|
|
# Movement
|
|
if Input.is_action_pressed("move_left") and not Input.is_action_pressed("move_right") \
|
|
and not player_state in ["striked_start", "striked", "striked_end"]:
|
|
move_left(SPEED)
|
|
elif Input.is_action_pressed("move_right") and not Input.is_action_pressed("move_left") \
|
|
and not player_state in ["striked_start", "striked", "striked_end"]:
|
|
move_right(SPEED)
|
|
elif player_state in ["idle", "run", "jump", "jump_end", "fall_end", "striked_end"]:
|
|
move_stop()
|
|
|
|
# On floor detection
|
|
if is_on_floor() and not player_state in ["striked", "striked_start"]:
|
|
snap = SNAP
|
|
_end_animation()
|
|
|
|
# Jump
|
|
if Input.is_action_just_pressed("jump"):
|
|
if $RayBottomLeft.is_colliding() or $RayBottomRight.is_colliding() or $RayBottomCenter.is_colliding():
|
|
jump()
|
|
|
|
func _next_player_state():
|
|
player_state = ANIMATIONS[player_state]["transistion"]
|
|
$Sprite.animation = ANIMATIONS[player_state]['animation']
|
|
|
|
func _set_player_state(new_state):
|
|
if not new_state in ANIMATIONS[player_state]["blocks"]:
|
|
player_state = new_state
|
|
$Sprite.animation = ANIMATIONS[player_state]['animation']
|
|
return true
|
|
return false
|
|
|
|
func move_right(delta):
|
|
_set_player_state("run")
|
|
get_node("Sprite").set_flip_h(false)
|
|
if position.x < level.camera_limit_right:
|
|
velocity.x = delta
|
|
else:
|
|
velocity.x = 0
|
|
|
|
func move_left(delta):
|
|
_set_player_state("run")
|
|
get_node("Sprite").set_flip_h(true)
|
|
if position.x > level.camera_limit_left:
|
|
velocity.x = -delta
|
|
else:
|
|
velocity.x = 0
|
|
|
|
func move_stop():
|
|
_set_player_state("idle")
|
|
velocity.x = 0
|
|
|
|
func jump():
|
|
if _set_player_state("jump_start"):
|
|
snap = Vector2.ZERO
|
|
position.y += get_floor_velocity().y * get_physics_process_delta_time() \
|
|
- GRAVITY * get_physics_process_delta_time() - 3
|
|
velocity.y -= JUMP_HEIGHT
|
|
|
|
func _on_GroundCheck_body_entered(body):
|
|
_end_animation()
|
|
|
|
func _end_animation():
|
|
if velocity.y > 0 and player_state in ["jump_start", "jump"]:
|
|
_set_player_state("jump_end")
|
|
if velocity.y > 0 and player_state in ["fall_start", "fall"]:
|
|
_set_player_state("fall_end")
|
|
if velocity.y > 0 and player_state in ["striked_start", "striked"]:
|
|
_set_player_state("striked_end")
|
|
|
|
func monster_hit(direction : int, damage: int):
|
|
if not invincible_hit:
|
|
invincible_hit = true
|
|
$HurtSound.play()
|
|
_set_player_state("striked_start")
|
|
_add_damage(damage)
|
|
snap = Vector2.ZERO
|
|
velocity.y = -300
|
|
velocity.x = direction * 5
|
|
yield(get_tree().create_timer(1.0), "timeout")
|
|
invincible_hit = false
|
|
|
|
func _on_Enemy_Entered(body):
|
|
body.stomped_on_head()
|
|
_set_player_state("jump")
|
|
|
|
func coin_collected(value):
|
|
main.add_score(value)
|
|
|
|
func _add_damage(value):
|
|
health -= value
|
|
GlobalState.health = health
|
|
if health <= 0:
|
|
main.player_died()
|
|
|
|
func _on_screen_exited():
|
|
print("exited")
|
|
print($VisibilityNotifier2D.is_on_screen())
|
|
_add_damage(100)
|