Page 1 of 1
wobble movement, slowly shaking sprite
Posted: Thu Dec 17, 2020 3:07 pm
by TheAutomator
i'm coding movement for an element in my game,
the item has to move smoothly in a slightly rotating way but on average keep straight.
to simplify things, i would like to make a sprite move like a firefly.
here is the perfect example:
https://gifer.com/en/Rx73
does someone know how to do this? i googled it a lot but can only find aftereffects stuff or predefined effects in software..
Code: Select all
If InitSprite() = 0 Or InitKeyboard() = 0
MessageRequester("Error", "Sprite system can't be initialized", 0)
End
EndIf
If OpenScreen(800, 600, 32, "Sprite")
LoadSprite(0, #PB_Compiler_Home + "examples/sources/Data/PureBasic.bmp")
Repeat
FlipBuffers()
ClearScreen(RGB(0,0,0))
ExamineKeyboard()
x + Random(2)-1
y + Random(2)-1
r.f = Random(2)-1
RotateSprite(0, r, #PB_Relative)
DisplaySprite(0, 50+ x, 50+ y)
Until KeyboardPushed(#PB_Key_Escape)
Else
MessageRequester("Error", "Can't open a 800*600 - 32 bit screen !", 0)
EndIf
Re: wobble movement, slowly shaking sprite
Posted: Thu Dec 17, 2020 6:17 pm
by Mijikai
PB only:
Code: Select all
EnableExplicit
Procedure.i Main()
Protected px.f
Protected py.f
Protected fmod.f
Protected fx1.f
Protected fx2.f
If InitSprite()
If OpenWindow(0,0,0,640,400,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
If OpenWindowedScreen(WindowID(0),0,0,640,400,#False,0,0,#PB_Screen_NoSynchronization)
SetFrameRate(60)
LoadSprite(0,#PB_Compiler_Home + "examples/sources/Data/PureBasic.bmp")
px = 320 - (SpriteWidth(0) / 2)
py = 200 - (SpriteHeight(0) / 2)
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
Break 2
Case #Null
Break
EndSelect
ForEver
fmod + 1.4
fx1 = Sin(fmod / 50) * 10
fx2 = Sin(fmod / 80) * 2
ClearScreen(0)
RotateSprite(0,fx2,#PB_Absolute)
DisplaySprite(0,px,py + fx1)
FlipBuffers()
ForEver
EndIf
CloseWindow(0)
EndIf
EndIf
ProcedureReturn #Null
EndProcedure
Main()
End
PB + Nautilus:
Code: Select all
EnableExplicit
XIncludeFile "nautilus.pbi"
Procedure.i Main()
Protected *ne.NAUTILUS_ENGINE
Protected *sp.NAUTILUS_TEXTURE
Protected fmod.f
Protected fx1.f
Protected fx2.f
If nautilusVersion() = #NAUTILUS_VERSION
If OpenWindow(0,0,0,800,600,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
*ne = nautilusEngine(WindowID(0),800,600)
If *ne
*ne\RenderFilter(#True);<- enable bilinear filtering
*ne\RenderVSyncMode(#False);<- disable vsync
*sp = *ne\CreateTexture(#Null,#PB_Compiler_Home + "examples/sources/Data/PureBasic.bmp")
Repeat
Select WaitWindowEvent(16)
Case #PB_Event_CloseWindow
Break
EndSelect
fmod + 1.4
fx1 = Sin(fmod / 30) * 10
fx2 = Sin(fmod / 80) * 2
*ne\RenderBegin()
*sp\DrawMod(400,300 + fx1,500,150,#True,$FF,$FFFFFF,fx2)
*ne\RenderEnd()
ForEver
*ne\Release()
EndIf
CloseWindow(0)
EndIf
EndIf
ProcedureReturn #Null
EndProcedure
Main()
End
Re: wobble movement, slowly shaking sprite
Posted: Thu Dec 17, 2020 10:00 pm
by TheAutomator
did you test "PB only", it just crashes after the image moves very fast and then slows down very hard in framerate..
the second one does the job but needs a whole engine for it?
this is what i came up with in the mean time, there must be a more easy way, like the Sin() function you showed but i need a little randomness in it :)
Code: Select all
InitSprite()
#w = 480
#h = 360
OpenWindow(0, 0, 0, #w, #h, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #w, #h)
LoadSprite(0, "sb-129.bmp")
;--------------------------------------------------------------------------------------------------------
xpos.f = #w / 2
xvel.f = 0
xgo = 0
time = 0
timerandom = 0
ypos.f = #h / 2
yvel.f = 0
ygo = 0
speed.f = 0.025
maxspeed.f = 1
rot.f = 0
rgo.f = 0
rvel.f = 0
rspeed.f = 0.001
rmaxspeed.f = 0.5
rmax.f = 1
Xmid = SpriteWidth(0)/2
ymid = SpriteHeight(0)/2
Wmid = #w/2
Hmid = #h/2
WHmax = 2
Repeat
Repeat
If WindowEvent() = #PB_Event_CloseWindow : End : EndIf
Until Event = 0
FlipBuffers()
ClearScreen(0)
DisplaySprite(0, xpos - Xmid, ypos - ymid)
RotateSprite(0, rot, #PB_Absolute)
If ElapsedMilliseconds() - time > timerandom
xgo = Random(Wmid + WHmax, Wmid - WHmax)
ygo = Random(Hmid + WHmax, Hmid - WHmax)
rgo = Random(rmax)-rmax
time = ElapsedMilliseconds()
timerandom = Random(1000)
;xpos = #w / 2
;ypos = #h / 2
EndIf
If rot < rgo : rvel + rspeed : EndIf
If rot > rgo : rvel - rspeed : EndIf
If rvel > rmaxspeed : rvel = rmaxspeed : EndIf
If rvel < -rmaxspeed : rvel = -rmaxspeed : EndIf
rot + rvel
If xpos < xgo : xvel + speed : EndIf
If xpos > xgo : xvel - speed : EndIf
If xvel > maxspeed : xvel = maxspeed : EndIf
If xvel < -maxspeed : xvel = -maxspeed : EndIf
xpos + xvel
If ypos < ygo : yvel + speed : EndIf
If ypos > ygo : yvel - speed : EndIf
If yvel > maxspeed : yvel = maxspeed : EndIf
If yvel < -maxspeed : yvel = -maxspeed : EndIf
ypos + yvel
ForEver
Re: wobble movement, slowly shaking sprite
Posted: Fri Dec 18, 2020 11:15 pm
by Demivec
You can use easing functions with random input.
I apologize for not having the time to give you an example at the moment.
Re: wobble movement, slowly shaking sprite
Posted: Sat Dec 19, 2020 3:46 pm
by DK_PETER
Eddy did some great easing procedures here:
viewtopic.php?f=12&t=63770&hilit=easing
Re: wobble movement, slowly shaking sprite
Posted: Sat Dec 19, 2020 4:00 pm
by Mijikai
TheAutomator wrote:did you test "PB only", it just crashes after the image moves very fast and then slows down very hard in framerate..
...
I had no issue with the PB code, so i cant tell why it is not working / crashing for you.
Sounds like some internal issue (VSync or timing).
Can you test it with OpenGL as subsystem?
Re: wobble movement, slowly shaking sprite
Posted: Thu Dec 24, 2020 1:18 am
by TheAutomator
Demivec wrote:You can use easing functions with random input.
I apologize for not having the time to give you an example at the moment.
Hey man, no problem!
we all have our lives and now with the upcoming holydays i'm not super active here myself.
no need to apologize

Re: wobble movement, slowly shaking sprite
Posted: Thu Dec 24, 2020 1:26 am
by TheAutomator
Well after some research i seemed to need a Perlin noise algorithm.
Writing that for pb was not really an option for a beginner like me so
i ended up with randomized sin calls actually.
to show you an example i made this screensaver that mimics the SpongeBob titlecard gif
https://www.youtube.com/watch?v=A-WZOA6Fwng
as close as possible, it does the job:
Code: Select all
InitSprite()
InitSound()
InitKeyboard()
;------------------------------------------------
#w = 800
#h = 600
OpenScreen(#w, #h, 32, "SB-129")
LoadSound(0, "loop.wav")
PlaySound(0, #PB_Sound_Loop)
LoadSprite(0, "Titlecard.bmp")
LoadSprite(1, "sb-129.bmp")
;--------------------------------------------------------------------------------------------------------
; ProgramParameter()
; /s = normal start
; /c = configure window
; /p = little preview window
; they can be followed by the windo ID:
; /c:1024
; use WinAPI to display a graphic in the preview window when the 'P' parameter is passed to the program
;--------------------------------------------------------------------------------------------------------
xmid = #w / 2 - SpriteWidth(1) / 2
ymid = #h / 2 - SpriteHeight(1) / 2
;------------------------------------------------
XmaxSpd = 300 ; / 100
XminSpd = 100 ; / 100
XmaxDis = 500 ; / 100
XminDis = 300 ; / 100
YmaxSpd = 300 ; / 100
YminSpd = 200 ; / 100
YmaxDis = 1500 ; / 100
YminDis = 1000 ; / 100
RmaxSpd = 400 ; / 100
RminSpd = 100 ; / 100
RmaxDis = 200 ; / 100
RminDis = 50 ; / 100
;------------------------------------------------
x.f = 0
y.f = 0
r.f = 0
Xdis = XmaxDis ; how far from middle / 100
Ydis = YmaxDis ; how far from middle / 100
Rdis = RmaxDis ; how far from middle / 100
XnewDis = Xdis ; walk to random distance point
YnewDis = Ydis ; walk to random distance point
RnewDis = Rdis ; walk to random distance point
Xdeg.f = 0 ; 1 - 360
Ydeg.f = 0 ; 1 - 360
Rdeg.f = 0 ; 1 - 360
Xspd = XmaxSpd ; how much pixels per frame / 100
Yspd = YmaxSpd ; how much pixels per frame / 100
Rspd = RmaxSpd ; how much pixels per frame / 100
XnewSpd = Xspd ; walk to random speed point
YnewSpd = Yspd ; walk to random speed point
RnewSpd = Rspd ; walk to random speed point
;------------------------------------------------
snip = ElapsedMilliseconds()
time = 1000
duration = SoundLength(0)
;--------------------------------------------------------------------------------------------------------
Repeat
ExamineKeyboard()
FlipBuffers()
;--------------------------------
r = Sin(Radian(Rdeg)) * (Rdis / 100)
If Rdis = Rnewdis
Rnewdis = Random(RmaxDis, RminDis)
ElseIf Rdis < Rnewdis
Rdis + 1
Else
Rdis - 1
EndIf
Rdeg + Rspd / 100
If Rdeg > 360 : Rdeg = 0 : EndIf
If Rspd = Rnewspd
Rnewspd = Random(RmaxSpd, RminSpd)
ElseIf Rspd < Rnewspd
Rspd + 1
Else
Rspd - 1
EndIf
;--------------------------------
x = Sin(Radian(Xdeg)) * (Xdis / 100)
If Xdis = Xnewdis
Xnewdis = Random(XmaxDis, XminDis)
ElseIf Xdis < Xnewdis
Xdis + 1
Else
Xdis - 1
EndIf
Xdeg + Xspd / 100
If Xdeg > 360 : Xdeg = 0 : EndIf
If Xspd = Xnewspd
Xnewspd = Random(XmaxSpd, XminSpd)
ElseIf Xspd < Xnewspd
Xspd + 1
Else
Xspd - 1
EndIf
;--------------------------------
Y = Sin(Radian(Ydeg)) * (Ydis / 100)
If Ydis = Ynewdis
Ynewdis = Random(YmaxDis, YminDis)
ElseIf Ydis < Ynewdis
Ydis + 1
Else
Ydis - 1
EndIf
Ydeg + Yspd / 100
If Ydeg > 360 : Ydeg = 0 : EndIf
If Yspd = Ynewspd
Ynewspd = Random(YmaxSpd, YminSpd)
ElseIf Yspd < Ynewspd
Yspd + 1
Else
Yspd - 1
EndIf
;--------------------------------
If ElapsedMilliseconds() - snip > time
snip = ElapsedMilliseconds()
SetSoundPosition(0, duration - Random(duration))
SetSoundFrequency(0, Random(54100, 34100))
EndIf
;--------------------------------
DisplaySprite(0,0,0)
RotateSprite(1, r, #PB_Absolute)
DisplayTransparentSprite(1, xmid + x, ymid + y)
Until KeyboardInkey()