Posts: 189
Threads: 22
Joined: Mar 2023
Reputation:
12
I was just messing around with a particle fountain. Sometimes the program runs smoothly, but if I change the _limit a little it can become hurky-jerky. Like the below seems to do great at 60 or 80 FPS, though runs less smoothly at 50 or 70. Is it my laptop? Is smoothness in graphics always a dance between run-speed and the number of pixels that items move per cycle? I'm curious how this could be made to run smoothly at various _limits. Any thoughts or insights appreciated!
Code: (Select All)
OPTION _EXPLICIT
SCREEN _NEWIMAGE(1280, 720, 32)
RANDOMIZE TIMER: _MOUSEHIDE
_DELAY .25: _SCREENMOVE _MIDDLE
TYPE particle
x AS SINGLE
y AS SINGLE
Vx AS SINGLE
Vy AS SINGLE
END TYPE
DIM AS INTEGER c
DIM AS particle p(200)
start:
c = -1
DO '
c = c + 1 ' init particles
p(c).x = _WIDTH / 2
p(c).y = c * -5 - 140
p(c).Vx = 0
p(c).Vy = 3 + (RND - RND) / 4
LOOP UNTIL c = UBOUND(p)
DO
c = -1
CLS
_LIMIT 60
DO ' move em
c = c + 1
p(c).x = p(c).x + p(c).Vx
p(c).y = p(c).y + p(c).Vy
IF p(c).y > 20 AND p(c).y < 26 THEN p(c).Vx = (RND - RND) / 1.75 ' only change em once
IF p(c).y > 14 THEN p(c).Vy = p(c).Vy + .06 ' a little gravity
LOOP UNTIL c = UBOUND(p)
c = -1
DO ' draw em
c = c + 1
PSET (p(c).x, p(c).y), _RGB32(255)
LOOP UNTIL c = UBOUND(p)
_DISPLAY
IF p(200).y > _HEIGHT + 140 THEN GOTO start
LOOP UNTIL _KEYDOWN(27)
SYSTEM
Posts: 3,999
Threads: 180
Joined: Apr 2022
Reputation:
222
10-10-2024, 10:38 PM
(This post was last modified: 10-10-2024, 10:44 PM by bplus.)
That looks smooth, I see or imagine a slight spiral effect when I change pset to circle which magnifies the view.
Hey have you seen my Particle Fountain?
Code: (Select All) _Title "Particle Fountain" 'b+ 2020-08-27
' 2023-08-17 tweaked a number for improved more consistent performance
Const nP = 50000
Type particle
x As Single
y As Single
dx As Single
dy As Single
r As Single
c As _Unsigned Long
End Type
Dim Shared p(1 To nP) As particle
Screen _NewImage(800, 600, 32)
_Delay .25
_ScreenMove _Middle
For i = 1 To nP
new i
Next
Color , &HFF002200
Do
Cls
If lp < nP Then lp = lp + 10
For i = 1 To lp
p(i).dy = p(i).dy + .1
p(i).x = p(i).x + p(i).dx
p(i).y = p(i).y + p(i).dy
If p(i).x < 0 Or p(i).x > _Width Then new i
If p(i).y > _Height And p(i).dy > 0 Then
p(i).dy = -.75 * p(i).dy: p(i).y = _Height - 5
End If
Circle (p(i).x, p(i).y), p(i).r, p(i).c
Next
_Display
_Limit 60
Loop Until _KeyDown(27)
Sub new (i)
p(i).x = _Width / 2 + Rnd * 20 - 10
p(i).y = _Height + Rnd * 5
p(i).dx = Rnd * 1 - .5
p(i).dy = -10
p(i).r = Rnd * 3
p(i).c = _RGB32(50 * Rnd + 165, 50 * Rnd + 165, 255)
End Sub
b = b + ...
Posts: 189
Threads: 22
Joined: Mar 2023
Reputation:
12
Actually I have seen that. Very sweet. Makes me wanna drink champagne.
Posts: 2,710
Threads: 328
Joined: Apr 2022
Reputation:
219
I took a moment to just restructure this a bit, to get rid of that EVIL goto.... (Not that I personally have anything against GOTOs. )
Code: (Select All)
Option _Explicit
Screen _NewImage(1280, 720, 32)
Randomize Timer: _MouseHide
_Delay .25: _ScreenMove _Middle
Type particle: As Single x, y, Vx, Vy: End Type
Dim As Integer c, reset_values
Dim As particle p(200)
reset_values = -1
Do
Cls
For c = 0 To UBound(p)
If reset_values Then
p(c).x = _Width / 2
p(c).y = c * -5 - 140
p(c).Vx = 0
p(c).Vy = 3 + (Rnd - Rnd) / 4
End If
p(c).x = p(c).x + p(c).Vx
p(c).y = p(c).y + p(c).Vy
If p(c).y > 20 And p(c).y < 26 Then p(c).Vx = (Rnd - Rnd) / 1.75 ' only change em once
If p(c).y > 14 Then p(c).Vy = p(c).Vy + .06 ' a little gravity
PSet (p(c).x, p(c).y), _RGB32(255)
Next
_Limit 60
_Display
If p(200).y > _Height + 140 Then reset_values = -1 Else reset_values = 0
Loop Until _KeyDown(27)
System
This runs and moves pretty dang smooth on my PC for me. I was thinking of swapping it over to use _MEM instead of PSET (and maybe swapping it over to just use hardware images instead of software) to see how it'd affect performance, but it doesn't seem necessary. Maybe my PC is just quick enough to run into any bottleneck/issue that you're seeing?
Posts: 189
Threads: 22
Joined: Mar 2023
Reputation:
12
10-11-2024, 05:26 AM
(This post was last modified: 10-11-2024, 05:26 AM by NakedApe.)
Thanks, Steve. I like your version. As for the program jerkiness, I think I'd either had too much coffee or not enough.
Posts: 303
Threads: 10
Joined: Apr 2022
Reputation:
44
`_Limit 60` will give you the smoothest, though you can't get it perfect. The gist of the problem is that the QB64 window is rendered at 60 FPS, and every time you call `_Display` you're queuing another frame to be displayed in the window. If you queue too many frames then some of them have to be dropped and the pixels will skip a spot. If you queue them too slowly then at some point QB64 will have to display the same frame twice and they'll appear to get stuck.
Posts: 3,999
Threads: 180
Joined: Apr 2022
Reputation:
222
I took a moment to overhaul everything and reinsert a GoTo
Code: (Select All) Option _Explicit
_Title "Another Particle Fountain" ' bplus mod Steve mod NakedApe 2024-10-13
Screen _NewImage(600, 600, 32)
_ScreenMove 250, 20
Randomize Timer: _MouseHide
_Delay .25: _ScreenMove _Middle
Type particle
As Single x, y, Vx, Vy
As _Unsigned Long c
As Integer flag
End Type
Dim As Long i, top, j, s
Dim As Single r, g, b
restart:
ReDim As particle p(15000)
r = Rnd * Rnd: g = Rnd * Rnd: b = Rnd * Rnd: top = 1
Do
Cls
For i = 0 To top
If p(i).flag = 0 Then
p(i).x = _Width / 2 + 20 * (Sin(_D2R(i Mod 360)))
p(i).y = _Height - 1
p(i).Vx = 0
p(i).Vy = -7
p(i).flag = 1
p(i).c = _RGB32(127 * 127 * Sin(r * i * .5), 127 * 127 * Sin(g * i * .5), 127 * 127 * Sin(b * i * .5))
End If
p(i).Vy = p(i).Vy + .032
p(i).Vx = p(i).Vx + .1 * Rnd - .1 * Rnd
p(i).x = p(i).x + p(i).Vx
p(i).y = p(i).y + p(i).Vy + 2 * Rnd
If p(i).y > _Height Then p(i).flag = 0
Circle (p(i).x, p(i).y), 2, p(i).c
s = s + 1
If s Mod 100 = 0 Then
If top < UBound(p) Then top = top + 1
End If
Next
_Display
_Limit 60
If s > 20000000 Then
s = 0
GoTo restart
End If
Loop Until _KeyDown(27)
System
b = b + ...
Posts: 189
Threads: 22
Joined: Mar 2023
Reputation:
12
(10-11-2024, 05:29 AM)DSMan195276 Wrote: `_Limit 60` will give you the smoothest, though you can't get it perfect. The gist of the problem is that the QB64 window is rendered at 60 FPS, and every time you call `_Display` you're queuing another frame to be displayed in the window. If you queue too many frames then some of them have to be dropped and the pixels will skip a spot. If you queue them too slowly then at some point QB64 will have to display the same frame twice and they'll appear to get stuck. Thanks, @DSMan195276. That makes sense. So one should use trial and error to find the FPS sweet spot for a given graphic function? Or just go with _limit 60 and call it a day, given that it'll never be perfect? Thnx.
Fancy mod, Bplus!
Posts: 2,710
Threads: 328
Joined: Apr 2022
Reputation:
219
(10-13-2024, 03:57 PM)NakedApe Wrote: (10-11-2024, 05:29 AM)DSMan195276 Wrote: `_Limit 60` will give you the smoothest, though you can't get it perfect. The gist of the problem is that the QB64 window is rendered at 60 FPS, and every time you call `_Display` you're queuing another frame to be displayed in the window. If you queue too many frames then some of them have to be dropped and the pixels will skip a spot. If you queue them too slowly then at some point QB64 will have to display the same frame twice and they'll appear to get stuck. Thanks, @DSMan195276. That makes sense. So one should use trial and error to find the FPS sweet spot for a given graphic function? Or just go with _limit 60 and call it a day, given that it'll never be perfect? Thnx.
Fancy mod, Bplus!
I'd think perfect factors of 60 would work just as well.
For example, with a _LIMIT 30, each frame should stay up for 2 complete tics of the display, without having them suffer from that stray being left over.
Same with _LIMIT 120. Each frame would be up for 1/2 tic of a display, so you'd basically always have the 2nd frame overwrite the 1st, but it'd be a consistent change, making it seem like the ball is just dropping 2 pixels per frame instead of 1. It'd still be smooth, without that odd frame out which would either lag up or jerk ahead to catch up.
Posts: 189
Threads: 22
Joined: Mar 2023
Reputation:
12
OK, that also makes sense. Got it. Thanks, Steve.
|