I have a question
I would like to add a sprite blur effect, when the object is moving. The higher the speed, the bigger the blur. Is it possible to achieve this programmatically ?
Youd have to search and learn about render targets. Although im not the best person to give aid about, for i have tried in the past making something similar but didnt quite achieve it. But i think that for something like that there might be an already existing extension.
Hi @FredZX !
What you want to achieve is most probably a motion blur. I once adapted an implementation of motion blur from shadertoy (Shader - Shadertoy BETA) as a fragment program for a sprite to Defold:
You probably want it rather to be aplied to everything on your screen, so you might render your scene to a render target (a separate, internal buffer/texture) and then perform this motion blur as a postprocessing when drawing this render target to a quad (simplest plane, a geometry to which you assign a texture) and this quad will fill the screen. This is the most common post-processing pipeline in Defold, let us know if this is understandable to you or you need more explanations ![]()
You might get to know how to draw to an offset buffer / render target and to quad filling the screen after watchin my video:
or reading official Defold example:
After understading how to make post-processing with this technique - let us know how are you familiar with GLSL and if you can adapt the motion blur example to your needs ![]()
I’m not familiar with this technique, but I’m going to try it ![]()
I will be experimenting with this, maybe I will come with some solution, but please don’t rely on me, it could be that I will get it done quickly or after ages, as I rarely have time for such experiments, sorry! 
But if you will try and get stuck on anything, let us know and we will try to help 
Did you find a solution? I made a trail.
--[[
Estela Simple con go.animate() y Delay por Segmento - v21 (Cabeza Animada)
- CORRECCIÓN: La cabeza AHORA TAMBIÉN se mueve con go.animate().
- Al hacer clic:
- La 'cabeza' (este GO) inicia una animación go.animate() hacia el punto de clic (delay 0).
- TODOS los segmentos inician una animación go.animate() hacia el MISMO punto de clic.
- Cada segmento inicia su animación con un DELAY diferente y configurable.
- Usa go.EASING_OUTELASTIC para TODO.
- SIN seguimiento continuo, SIN Lerp manual para segmentos.
Asegúrate de que 'anim_duration' sea suficientemente largo para apreciar el rebote elástico.
]]
-- Propiedades Necesarias --
go.property("numero_segmentos", 10)
go.property("url_fabrica_segmento", msg.url("#trail_factory")) -- Fábrica para los segmentos
go.property("anim_duration", 0.8) -- Duración de la animación de CADA objeto (cabeza y segmentos)
-- ¡Prueba valores ALTOS (0.6+) para ver el rebote!
go.property("segment_delay_step", 0.05) -- Delay ADICIONAL por cada segmento (segundos)
-- INIT: Crear los segmentos
function init(self)
msg.post(".", "acquire_input_focus")
-- Validar propiedades
self.numero_segmentos = math.max(0, self.numero_segmentos)
self.anim_duration = math.max(0.01, self.anim_duration)
self.segment_delay_step = math.max(0.0, self.segment_delay_step)
self.segments_id = {} -- Tabla para guardar los IDs
-- Crear los segmentos iniciales
local initial_pos = go.get_position()
for i = 1, self.numero_segmentos do
local id = factory.create(self.url_fabrica_segmento, initial_pos)
if id then
table.insert(self.segments_id, id)
else
print("ERROR: No se pudo crear segmento", i, "desde", self.url_fabrica_segmento)
end
end
print("Estela Simple v21 lista (Cabeza Animada). Segmentos:", self.numero_segmentos)
print("Anim Duration:", self.anim_duration, "s | Delay Step:", self.segment_delay_step, "s")
print("Haz clic para mover la estela con Easing OUTELASTIC y delay.")
end
-- ON_INPUT: Detectar clic y lanzar TODAS las animaciones (incluida la cabeza)
function on_input(self, action_id, action)
if (action_id == hash("touch") or action_id == hash("click")) and action.pressed then
-- 1. Determinar la posición objetivo final (el clic)
local target_pos = vmath.vector3(action.x, action.y, 0)
local current_head_pos = go.get_position() -- Posición actual antes de animar
target_pos.z = current_head_pos.z
print("Clic -> Animando cabeza y segmentos hacia", target_pos)
-- 2. *** CAMBIO CLAVE: Animar la CABEZA en lugar de moverla instantáneamente ***
-- Cancelar animación previa de la cabeza
go.cancel_animations(".", "position")
-- Animar la cabeza hacia el target con delay 0
go.animate(
".", -- Este GO (la cabeza)
"position",
go.PLAYBACK_ONCE_FORWARD,
target_pos, -- El destino del clic
go.EASING_OUTELASTIC,
self.anim_duration, -- Misma duración que los segmentos
0 -- Sin delay para la cabeza
)
-- Ya NO usamos: go.set_position(target_pos, ".")
-- 3. Iterar sobre TODOS los segmentos y lanzar su animación con su delay
for i, segment_id in ipairs(self.segments_id) do
local segment_exists = pcall(function() return go.exists(segment_id) end)
if segment_exists then
-- Calcular el delay para ESTE segmento
-- (El delay ahora es relativo al inicio de la animación de la cabeza)
local delay = i * self.segment_delay_step -- Ajuste: el primero (i=1) tiene step*1 de delay
-- Si quieres que el primero siga pegado a la cabeza, usa (i-1) * step
-- Cancelar animación de posición anterior para este segmento
go.cancel_animations(segment_id, "position")
-- Iniciar la animación para ESTE segmento hacia el MISMO target_pos
go.animate(
segment_id,
"position",
go.PLAYBACK_ONCE_FORWARD,
target_pos, -- Mismo destino que la cabeza
go.EASING_OUTELASTIC,
self.anim_duration,
delay -- El delay calculado
)
end
end
end
end
-- FINAL: Limpiar los segmentos creados
function final(self)
msg.post(".", "release_input_focus")
for _, segment_id in ipairs(self.segments_id) do
pcall(function()
if go.exists(segment_id) then
go.cancel_animations(segment_id)
go.delete(segment_id)
end
end)
end
self.segments_id = {}
end
-- UPDATE: No necesario
-- function update(self, dt)
-- end
If you’re looking for a trail fx, there’s a great one: