FB Gfx lib:
Code: Select all
'Coded by UEZ build 2024-04-10
#include "fbgfx.bi"
Using FB
Function Rnd2(min As Double, max As Double = &hFFFFFFFF) As Double
Dim As Double Rand = Rnd()
If max = &hFFFFFFFF Then Return Rand * min
If min > max Then Swap min, max
Return Rand * (max - min) + min
End Function
Const w = 1920
Const h = Int(w * 9 / 16)
Const h2 = h Shr 1
Const _t = 1 / 60
ScreenRes w, h, 32, 2, GFX_ALPHA_PRIMITIVES Or GFX_NO_SWITCH Or GFX_NO_FRAME
ScreenSet 1, 0
Color &hFF, &hFFFFFFFF
Randomize, 5
Type vecBalls
As Double x, y, vx, vy, d, r, m
As ULong c
End Type
Dim As ULong iFPS, cfps = 0, iBalls = 40
Dim As Double fTimer = Timer, dx, dy, dist, nx, ny, rvx, rvy, rvdotn, impulse, overlap, mx, my, t1, t2
Dim As Long i, j, nr = Sqr(iBalls), nc = iBalls \ nr, cw = w \ nc, ch = h \ nr, _row, _col
Dim As vecBalls aBalls(iBalls - 1)
For i = 0 To iBalls - 1
With aBalls(i)
.vx = Rnd() * 10 - 5
.vy = Rnd() * 10 - 5
.r = 50 + Rnd() * 64 - 32
.d = 2 * .r
'ordered position to avoid overlapping of balls
_col = i Mod nc
_row = Int(i / nc)
.x = Rnd2(_col * cw + .r, (_col + 1) * cw - .r)
.y = Rnd2(_row * ch + .r, (_row + 1) * ch - .r)
.c = &hFF000000 Or Int(Rnd() * &hFFFFFF)
.m = 1 + Rnd() * 50
End With
Next
Function _Dist(x1 As Double, y1 As Double, r1 As Double, x2 As Double, y2 As Double, r2 As Double) As Boolean
Return Sqr((x2 - x1) ^ 2 + (y2 - y1) ^ 2) < (r1 + r2)
End Function
Do
Cls
For i = 0 To iBalls - 1
With aBalls(i)
'move the ball
.x += .vx
.y += .vy
'check for collision with gui edges
If .x > w - 1 - .r Then .vx = -.vx : .x = w - 1 - .r
If .x < .r Then .vx = -.vx : .x = .r
If .y > h - 1 - .r Then .vy = -.vy : .y = h - 1 - .r
If .y < .r Then .vy = -.vy : .y = .r
'check for collision between balls
For j = i + 1 To iBalls - 1
If _Dist(.x, .y, .r, aBalls(j).x, aBalls(j).y, aBalls(j).r) Then
'balls distance To each other
dx = aBalls(j).x - .x
dy = aBalls(j).y - .y
dist = Sqr(dx * dx + dy * dy)
'normalize collision vector
nx = dx / dist
ny = dy / dist
'calculate relative velocity
rvx = aBalls(j).vx - .vx
rvy = aBalls(j).vy - .vy
rvdotn = rvx * nx + rvy * ny
'calculate impulse scalar
impulse = 2 * rvdotn / (.m + aBalls(j).m)
'update velocities
t1 = impulse * aBalls(j).m
.vx += t1 * nx
.vy += t1 * ny
t2 = impulse * .m
aBalls(j).vx -= t2 * nx
aBalls(j).vy -= t2 * ny
'avoid overlapped balls (satelitte effect)
overlap = (.r + aBalls(j).r) - dist
t1 = overlap / dist
mx = dx * t1
my = dy * t1
t1 = mx / 2
t2 = my / 2
.x -= t1
.y -= t2
aBalls(j).x += t1
aBalls(j).y += t2
End If
Next
'draw ball
Circle (.x, .y), .r, .c, , , , F
Draw String (.x - 40 / Len(Int(.m)), .y - 4), Str(Int(.m)), &hFF000000 Or ((&h00FFFFFF And .c) Xor &hBFBFBF)
End With
Next
Draw String(4, 4), iFPS & " fps", &hFF000000
Flip
cfps += 1
If Timer - fTimer > 0.99 Then
iFPS = cfps
cfps = 0
fTimer = Timer
End If
Sleep (1)
Loop Until Len(Inkey())
Code: Select all
#include "cairo/cairo.bi"
#include "fbgfx.bi"
Using FB
#define _2pi (6.283185307179586)
Function Rnd2(min As Double, max As Double = &hFFFFFFFF) As Double '...'
Dim As Double Rand = Rnd()
If max = &hFFFFFFFF Then Return Rand * min
If min > max Then Swap min, max
Return Rand * (max - min) + min
End Function
Function _Dist(x1 As Double, y1 As Double, r1 As Double, x2 As Double, y2 As Double, r2 As Double) As Boolean '...'
Return Sqr((x2 - x1) ^ 2 + (y2 - y1) ^ 2) < (r1 + r2)
End Function
Dim As Long w = 1920, h = Int(w * 9 / 16)
ScreenRes w, h, 32, , GFX_ALPHA_PRIMITIVES Or GFX_NO_SWITCH Or GFX_NO_FRAME
Dim As Any Ptr pImage = ImageCreate(w, h)
Dim As Any Ptr imgData
ImageInfo(pImage, w, h, , , imgData)
Dim As Long stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w)
Dim As cairo_surface_t Ptr cs = cairo_image_surface_create_for_data(imgData, CAIRO_FORMAT_ARGB32, w, h, stride)
Dim As cairo_t Ptr cr = cairo_create(cs)
Randomize, 5
Type vecBalls
As Double x, y, vx, vy, d, r, m
As Double cr, cg, cb
End Type
Dim As ULong iFPS, cfps = 0, iBalls = 40
Dim As Double fTimer = Timer, dx, dy, dist, nx, ny, rvx, rvy, rvdotn, impulse, overlap, mx, my, t1, t2
Dim As Long i, j, nr = Sqr(iBalls), nc = iBalls \ nr, cw = w \ nc, ch = h \ nr, _row, _col
Dim As vecBalls aBalls(iBalls - 1)
For i = 0 To iBalls - 1
With aBalls(i)
.vx = Rnd() * 10 - 5
.vy = Rnd() * 10 - 5
.r = 50 + Rnd() * 64 - 32
.d = 2 * .r
'ordered position to avoid overlapping of balls
_col = i Mod nc
_row = Int(i / nc)
.x = Rnd2(_col * cw + .r, (_col + 1) * cw - .r)
.y = Rnd2(_row * ch + .r, (_row + 1) * ch - .r)
.cr = Rnd()
.cg = Rnd()
.cb = Rnd()
.m = 1 + Rnd() * 50
End With
Next
Do
cairo_set_source_rgb(cr, 1, 1, 1)
cairo_paint(cr)
For i = 0 To iBalls - 1
With aBalls(i)
'move the ball
.x += .vx
.y += .vy
'check for collision with gui edges
If .x > w - 1 - .r Then .vx = -.vx : .x = w - 1 - .r
If .x < .r Then .vx = -.vx : .x = .r
If .y > h - 1 - .r Then .vy = -.vy : .y = h - 1 - .r
If .y < .r Then .vy = -.vy : .y = .r
'check for collision between balls
For j = i + 1 To iBalls - 1
If _Dist(.x, .y, .r, aBalls(j).x, aBalls(j).y, aBalls(j).r) Then
'balls distance To each other
dx = aBalls(j).x - .x
dy = aBalls(j).y - .y
dist = Sqr(dx * dx + dy * dy)
'normalize collision vector
nx = dx / dist
ny = dy / dist
'calculate relative velocity
rvx = aBalls(j).vx - .vx
rvy = aBalls(j).vy - .vy
rvdotn = rvx * nx + rvy * ny
'calculate impulse scalar
impulse = 2 * rvdotn / (.m + aBalls(j).m)
'update velocities
t1 = impulse * aBalls(j).m
.vx += t1 * nx
.vy += t1 * ny
t2 = impulse * .m
aBalls(j).vx -= t2 * nx
aBalls(j).vy -= t2 * ny
'avoid overlapping balls (satelitte effect)
overlap = (.r + aBalls(j).r) - dist
t1 = overlap / dist
mx = dx * t1
my = dy * t1
t1 = mx / 2
t2 = my / 2
.x -= t1
.y -= t2
aBalls(j).x += t1
aBalls(j).y += t2
End If
Next
'draw ball
cairo_arc(cr, .x, .y, .r, 0, _2pi)
cairo_set_source_rgba(cr, .cr, .cg, .cb, 1)
cairo_fill(cr)
End With
Next
cairo_move_to(cr, 4, 12)
cairo_set_source_rgba(cr, 0, 0, 0, 1)
cairo_show_text(cr, Str(iFPS) & " fps")
ScreenLock
Put (0, 0), pImage, PSet
ScreenUnlock
cfps += 1
If Timer - fTimer > 0.99 Then
iFPS = cfps
cfps = 0
fTimer = Timer
End If
Sleep 1
Loop Until Len(Inkey)
cairo_destroy(cr)
cairo_surface_destroy(cs)
ImageDestroy(pImage)