managems/entities/gem.gd

111 lines
2.7 KiB
GDScript

extends Control
class_name Gem
signal position_reached()
# Gem type enum
enum Type { Thermic, Optic, Kinetic, Electromagnetic, Acoustic, Biologic, Chemic } #, Skull }
# Gem effect enum
enum Effect { ManaNegative, ManaPositive, EffectNegative, EffectPositive }
const effect_distribution = {
Effect.ManaNegative: 45,
Effect.ManaPositive: 45,
Effect.EffectNegative: 5,
Effect.EffectPositive: 5
}
# Variables
const unscaled_size = 128
export(Type) var type = Type.Thermic
export(Effect) var effect = Effect.ManaNegative
# Indicate if animation are played
var animate = false
# For removing
var matched: bool = false
var bonus: int = 0
# For moving
var next_i: int = 0
var next_j: int = 0
var current_i: int = 0
var current_j: int = 0
var move_dist: float = 0.0
var move_inc: float = 0.0
var moving: bool = false
# Called when the node enters the scene tree for the first time.
func _ready():
update_sprite()
# Called periodically
func _process(delta):
if moving:
move_inc += 4*delta
if (move_inc >= move_dist) or ((current_i == next_i) and (current_j == next_j)):
reach_position()
else:
var pos = size() * lerp(Vector2(current_i, current_j), Vector2(next_i, next_j), move_inc / move_dist)
set_position(pos)
# Randomize a gem
func randomize(rnd: Random):
type = rnd.pick_from_array(Type.values())
effect = rnd.pick_from_distribution(effect_distribution)
update_sprite()
# Update the sprite from its type and effect
func update_sprite():
$Sprite.region_rect.position.x = unscaled_size * (type % Type.size())
$Sprite.region_rect.position.y = unscaled_size * (effect % Effect.size())
# Used for movement and position
func size():
return $Sprite.transform.get_scale().x * unscaled_size
# Match a gem
func set_matched():
if !matched:
matched = true
if animate:
$Sprite.hide()
$ParticlesMatch.emitting = true
$ParticlesTimer.start()
else:
queue_free()
# Bonus value
func set_bonus():
bonus += 1
# Enable animations and particles
func enable_animations():
animate = true
# Set the position on the grid
func set_grid_position(i, j):
next_i = i
next_j = j
current_i = i
current_j = j
set_position(size() * Vector2(i,j))
# Move to grid position
func move_to_position(i, j):
next_i = i
next_j = j
move_dist = Vector2(current_i, current_j).distance_to(Vector2(next_i, next_j))
func update_position():
if animate:
moving = true
else:
reach_position()
func reach_position():
move_inc = 0.0
moving = false
current_i = next_i
current_j = next_j
set_position(size() * Vector2(next_i, next_j))
if animate:
emit_signal("position_reached")