Skip to content

Instantly share code, notes, and snippets.

@Zertuk
Last active May 10, 2024 06:03
Show Gist options
  • Save Zertuk/4e06e8dc6493789182fc8042694f8d97 to your computer and use it in GitHub Desktop.
Save Zertuk/4e06e8dc6493789182fc8042694f8d97 to your computer and use it in GitHub Desktop.
godot textbox with typewriter effect, shake, wavy, slow, and colored letters
extends Node2D
var timeToShow = 5
var originalPosition
var waveDelay = 0
var isWavy = false
var wavyDirection = 1
var isShakey = false
const SHAKE_DELAY = 0.05
var shakeTimer = SHAKE_DELAY
onready var tween = get_node("Tween")
onready var label = get_node("text-box-label")
func _ready():
originalPosition = position
func shake(delta):
if (shakeTimer > 0):
shakeTimer = shakeTimer - delta
return
shakeTimer = SHAKE_DELAY
var newX = rand_range(originalPosition.x - 0.5, originalPosition.x + 0.5)
var newY = rand_range(originalPosition.y - 1, originalPosition.y + 1)
var offset = Vector2(newX, newY)
tween.interpolate_property(self, "position", position, offset, SHAKE_DELAY / 2, Tween.TRANS_CUBIC, Tween.EASE_IN_OUT)
tween.start()
func startWavy():
var start = position
var end = position
end.y = end.y + 1
doWavyTween(start, end, 0.5)
func restartWavy():
var start = position
var end = position
end.y = end.y - 2 * wavyDirection
wavyDirection = wavyDirection * -1
doWavyTween(start, end, 0.5)
func doWavyTween(start, end, time=1):
tween.interpolate_property(self, "position", start, end, time, Tween.TRANS_CUBIC, Tween.EASE_IN_OUT)
tween.interpolate_callback(self, time, "restartWavy")
tween.start()
func _physics_process(delta):
if (timeToShow > 0):
timeToShow = timeToShow - 1
elif (!label.visible):
label.show()
if (isShakey):
shake(delta)
if (!isWavy):
return
if (waveDelay > 0):
waveDelay = waveDelay - 1
else:
isWavy = false # its still wavy, but set to false so we dont restart the effect
startWavy()
func spawnLabels(textToShow):
# temp override the string for testing
textToShow = "#shake# %color% ^wavy^ @slowww@"
despawnLabels()
var newFontColor = 'd69a4e'
var isWavy = false
var isNewColor = false
var isShakey = false
var isSlow = false
var posX = 0
var posY = 5
var initPos = Vector2(0, 0)
var timeToShow = 0
var delay = 5
var wavyDelay = 0.0
var slowDelay = 15
for letter in textToShow:
if (letter == '#'):
isShakey = !isShakey
continue
if (letter == '@'):
isSlow = !isSlow
continue
if (letter == '%'):
isNewColor = !isNewColor
continue
if (letter == '^'):
isWavy = !isWavy
wavyDelay = 0
continue
var scene = preload("res://scenes/ui/text-box-label-container.tscn")
var node = scene.instance()
node.timeToShow = timeToShow
var innerLabel = node.get_node("text-box-label")
if (isNewColor):
innerLabel.set("custom_colors/font_color", Color('#' + newFontColor))
if (isSlow):
timeToShow = timeToShow + slowDelay
else:
timeToShow = timeToShow + delay
if (isWavy):
node.waveDelay = wavyDelay
wavyDelay = wavyDelay + delay * 2
node.isWavy = true
if (isShakey):
node.isShakey = true
node.shakeTimer = rand_range(0, 0.2)
innerLabel.text = letter
node.position.x = posX
node.position.y = posY - 2
textArea.add_child(node)
posX = posX + innerLabel.rect_size.x
@triptych
Copy link

Thank you this is very useful!

@jimmyjonezz
Copy link

Big thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment