Edit: Euh. Just realized. What I mean is: how can I move 2D sprites smoothly over a WINDOWED screen, without resorting to WinApi?
Edit 2: Euh... just sprites in general are driving me totally bonkers! I want to do this properly, or not at all...

sprites move smoothly, when opening a fullscreen and using the monitor's native refreshrate.how can I move sprites smoothly over the screen
Code: Select all
Enumeration
#w_main
#i_vectoid
#i_rock
#spr_player
#spr_rock
;
#f_exit
#f_none
EndEnumeration
;
Structure object
x.l
y.l
w.l
h.l
dx.l
dy.l
sprite_nr.l
EndStructure
;
Global NewList objects.object()
;
screen_w.l = 1280
screen_h.l = 1024
;
InitSprite()
InitKeyboard()
OpenScreen(screen_w,screen_h,16,"Test")
;
i_vectoid_h = CreateImage(#i_vectoid,64,64,32)
StartDrawing(ImageOutput(#i_vectoid))
Box(0,0,63,63,RGB(0,0,0))
FrontColor(RGB(0,255,0))
LineXY(4,60,32,4)
LineXY(32,4,60,60)
LineXY(60,60,32,16)
LineXY(32,16,4,60)
StopDrawing()
;
i_rock_h = CreateImage(#i_rock,64,64,32)
StartDrawing(ImageOutput(#i_rock))
Box(0,0,63,63,RGB(0,0,0))
FrontColor(RGB(255,255,255))
LineXY(4,60,32,4)
LineXY(32,4,60,60)
LineXY(60,60,38,16)
LineXY(38,16,54,6)
LineXY(54,6,43,34)
LineXY(43,34,60,60)
LineXY(60,60,10,35)
LineXY(10,35,4,60)
StopDrawing()
;
CreateSprite(#spr_player,64,64)
CreateSprite(#spr_rock,64,64)
;
StartDrawing(SpriteOutput(#spr_player))
DrawImage(i_vectoid_h,0,0)
StopDrawing()
StartDrawing(SpriteOutput(#spr_rock))
DrawImage(i_rock_h,0,0)
StopDrawing()
;
AddElement(objects())
With objects()
\x = Random(screen_w)
\y = Random(screen_h)
\w = 64
\h = 64
\dx = 1+Random(5)
\dy = 1+Random(5)
\sprite_nr = #spr_player
EndWith
For n = 1 To 5
AddElement(objects())
With objects()
\x = Random(screen_w)
\y = Random(screen_h)
\w = 64
\h = 64
\dx = -1-Random(5)
\dy = -1-Random(5)
\sprite_nr = #spr_rock
EndWith
Next n
;
SetFrameRate(60)
action = #f_none
Repeat
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
action = #f_exit
EndIf
;
ClearScreen(0)
;
For n = 0 To 5
SelectElement(objects(),n)
With objects()
If \x > screen_w - \w
\dx = -1-Random(5)
EndIf
If \x < 0
\dx = 1+Random(5)
EndIf
If \y > screen_h - \h
\dy = -1-Random(5)
EndIf
If \y < 0
\dy = 1+Random(5)
EndIf
\x = \x + \dx
\y = \y + \dy
DisplayTransparentSprite( \sprite_nr, \x , \y )
EndWith
Next n
FlipBuffers(#PB_Screen_SmartSynchronization)
Until action = #f_exit
CloseScreen()
Code: Select all
Enumeration
#w_main
#i_vectoid
#i_rock
#spr_player
#spr_rock
;
#f_exit
#f_none
EndEnumeration
;
Structure object
x.l
y.l
w.l
h.l
dx.l
dy.l
sprite_nr.l
EndStructure
;
Global NewList objects.object()
;
InitSprite()
InitKeyboard()
;
; screen_w.l = 640
; screen_h.l = 480
; w_main_h = OpenWindow(#w_main,0,0,screen_w,screen_h,"Test",#PB_Window_ScreenCentered)
; OpenWindowedScreen(w_main_h,0,0,screen_w,screen_h,0,0,0)
;
screen_w.l = 1280
screen_h.l = 1024
OpenScreen(screen_w,screen_h,16,"Test")
;
i_vectoid_h = CreateImage(#i_vectoid,64,64,32)
StartDrawing(ImageOutput(#i_vectoid))
Box(0,0,63,63,RGB(0,0,0))
FrontColor(RGB(0,255,0))
LineXY(4,60,32,4)
LineXY(32,4,60,60)
LineXY(60,60,32,16)
LineXY(32,16,4,60)
StopDrawing()
;
i_rock_h = CreateImage(#i_rock,64,64,32)
StartDrawing(ImageOutput(#i_rock))
Box(0,0,63,63,RGB(0,0,0))
FrontColor(RGB(255,255,255))
LineXY(4,60,32,4)
LineXY(32,4,60,60)
LineXY(60,60,38,16)
LineXY(38,16,54,6)
LineXY(54,6,43,34)
LineXY(43,34,60,60)
LineXY(60,60,10,35)
LineXY(10,35,4,60)
StopDrawing()
;
CreateSprite(#spr_player,64,64,#PB_Sprite_Memory)
CreateSprite(#spr_rock,64,64,#PB_Sprite_Memory)
;
; CreateSprite(#spr_player,64,64)
; CreateSprite(#spr_rock,64,64)
;
StartDrawing(SpriteOutput(#spr_player))
DrawImage(i_vectoid_h,0,0)
StopDrawing()
StartDrawing(SpriteOutput(#spr_rock))
DrawImage(i_rock_h,0,0)
StopDrawing()
;
AddElement(objects())
With objects()
\x = Random(screen_w)
\y = Random(screen_h)
\w = 64
\h = 64
\dx = 1+Random(5)
\dy = 1+Random(5)
\sprite_nr = #spr_player
EndWith
For n = 1 To 5
AddElement(objects())
With objects()
\x = Random(screen_w)
\y = Random(screen_h)
\w = 64
\h = 64
\dx = -1-Random(5)
\dy = -1-Random(5)
\sprite_nr = #spr_rock
EndWith
Next n
;
SetFrameRate(60)
;
action = #f_none
Repeat
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
action = #f_exit
EndIf
;
;
StartSpecialFX()
;
ClearScreen(0)
For n = 0 To 5
SelectElement(objects(),n)
With objects()
If \x > screen_w - \w
\dx = -1-Random(5)
EndIf
If \x < 0
\dx = 1+Random(5)
EndIf
If \y > screen_h - \h
\dy = -1-Random(5)
EndIf
If \y < 0
\dy = 1+Random(5)
EndIf
\x = \x + \dx
\y = \y + \dy
;
; DisplaySprite( \sprite_nr, \x , \y )
;
DisplayTranslucentSprite( \sprite_nr, \x, \y, 128)
EndWith
Next n
;
StopSpecialFX()
;
FlipBuffers(#PB_Screen_SmartSynchronization)
;
Until action = #f_exit
CloseScreen()
Code: Select all
Enumeration
#w_main
#i_vectoid
#i_rock
#spr_player
#spr_rock
;
#f_exit
#f_none
EndEnumeration
;
Structure object
x.l
y.l
w.l
h.l
dx.l
dy.l
sprite_nr.l
EndStructure
;
Global NewList objects.object()
;
screen_w.l = 1280
screen_h.l = 1024
;
InitSprite()
InitKeyboard()
OpenScreen(screen_w,screen_h,16,"Test")
;
i_vectoid_h = CreateImage(#i_vectoid,64,64,32)
StartDrawing(ImageOutput(#i_vectoid))
Box(0,0,63,63,RGB(0,0,0))
FrontColor(RGB(0,255,0))
LineXY(4,60,32,4)
LineXY(32,4,60,60)
LineXY(60,60,32,16)
LineXY(32,16,4,60)
StopDrawing()
;
i_rock_h = CreateImage(#i_rock,64,64,32)
StartDrawing(ImageOutput(#i_rock))
Box(0,0,63,63,RGB(0,0,0))
FrontColor(RGB(255,255,255))
LineXY(4,60,32,4)
LineXY(32,4,60,60)
LineXY(60,60,38,16)
LineXY(38,16,54,6)
LineXY(54,6,43,34)
LineXY(43,34,60,60)
LineXY(60,60,10,35)
LineXY(10,35,4,60)
StopDrawing()
;
CreateSprite(#spr_player,64,64)
CreateSprite(#spr_rock,64,64)
;
StartDrawing(SpriteOutput(#spr_player))
DrawImage(i_vectoid_h,0,0)
StopDrawing()
StartDrawing(SpriteOutput(#spr_rock))
DrawImage(i_rock_h,0,0)
StopDrawing()
;
AddElement(objects())
With objects()
\x = Random(screen_w)
\y = Random(screen_h)
\w = 64
\h = 64
\dx = 1+Random(5)
\dy = 1+Random(5)
\sprite_nr = #spr_player
EndWith
For n = 1 To 5
AddElement(objects())
With objects()
\x = Random(screen_w)
\y = Random(screen_h)
\w = 64
\h = 64
\dx = -1-Random(5)
\dy = -1-Random(5)
\sprite_nr = #spr_rock
EndWith
Next n
;
SetFrameRate(60)
action = #f_none
s1=Second(Date())
Repeat
s2=Second(Date())
If s2<>S1
s3+1
If s3=10
syncmode+1
s3=0
EndIf
s1=s2
EndIf
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
action = #f_exit
EndIf
If KeyboardPushed(#PB_Key_Space)
syncmode+1
Delay(300)
EndIf
If syncmode>3
StartSpecialFX()
EndIf
ClearScreen(0)
;
For n = 0 To 5
SelectElement(objects(),n)
With objects()
If \x > screen_w - \w
\dx = -1-Random(5)
EndIf
If \x < 0
\dx = 1+Random(5)
EndIf
If \y > screen_h - \h
\dy = -1-Random(5)
EndIf
If \y < 0
\dy = 1+Random(5)
EndIf
\x = \x + \dx
\y = \y + \dy
If syncmode<4
DisplayTransparentSprite( \sprite_nr, \x , \y )
Else
DisplayTranslucentSprite( \sprite_nr, \x, \y, 128)
EndIf
EndWith
Next n
If syncmode>3
StopSpecialFX()
EndIf
StartDrawing(ScreenOutput())
DrawText(1,1,Str(syncmode))
CompilerIf Subsystem("OpenGL")
DrawText(30,1,"OpenGL Subsystem")
CompilerEndIf
CompilerIf Subsystem("DirectX9")
DrawText(30,1,"DirectX9 Subsystem")
CompilerEndIf
CompilerIf Subsystem("DirectX7")
DrawText(30,1,"DirectX7 Subsystem")
CompilerEndIf
CompilerIf Subsystem("NT4")
DrawText(30,1,"NT4 Subsystem")
CompilerEndIf
Select syncmode
Case 0,4
DrawText(1,20,"FlipBuffers()")
Case 1,5
DrawText(1,20,"FlipBuffers( #PB_Screen_NoSynchronization )")
Case 2,6
DrawText(1,20,"FlipBuffers(#PB_Screen_SmartSynchronization) ")
Case 3,7
DrawText(1,20,"FlipBuffers( #PB_Screen_WaitSynchronization)")
EndSelect
If syncmode>3
DrawText(1,40,"DisplayTranslucentSprite()")
Else
DrawText(1,40,"DisplayTransparentSprite()")
EndIf
StopDrawing()
Select syncmode
Case 0
FlipBuffers()
Case 1
FlipBuffers( #PB_Screen_NoSynchronization )
Case 2
FlipBuffers(#PB_Screen_SmartSynchronization)
Case 3
FlipBuffers( #PB_Screen_WaitSynchronization)
Case 4
FlipBuffers()
Case 5
FlipBuffers( #PB_Screen_NoSynchronization )
Case 6
FlipBuffers(#PB_Screen_SmartSynchronization)
Case 7
FlipBuffers( #PB_Screen_WaitSynchronization)
Default
action = #f_exit
EndSelect
;
Until action = #f_exit
CloseScreen() No, you don't have to do that. You just have to separate the graphical update, and the main logic. Then, you can do the main logic several times, and the graphical refresh only once.blueznl wrote: 4. The fractional solution.
Assume a player object should move 'n' pixels per second, then you could deduct how many pixels it should move per frame. Let's say the framerate = refreshrate = 60 / second, then:
speedperframe = speedpersecond / 60
Your engine would thus, each frame, have to calculate the movement of your object, adjusting it's position with speedperframe distance. To avoid fractions / roundings you should store coordinates in floats then, not in ints.
