Been playing a lot of Ark lately, and if you haven't played the game they have a radial menu system. I won't get into how terrible their menu system is (or the vast number of game-stopping bugs that still exist after 10 years) but thought I'd have a go at creating something like it. The menu needs a minimum 4 segments to work, but that was just to reduce the amount of drawing needed. Could technically ditch that limitation since when writing this I changed it to use sprites.
SetErrorMode(2)
SetWindowSize(1024, 768, 0)
SetWindowAllowResize(1)
SetVirtualResolution(1024, 768)
SetSyncRate(60, 0)
UseNewDefaultFonts(1)
#constant pieces = 13 // number of segments in wheel (must be at least 4)
Type objItem
spr as integer
scale as float
EndType
items as objItem[pieces]
c0 = makeColor(23,181,230)
c2 = makeColor(0,255,0)
black = makeColor(0,0,0)
createsprite(loadImage("flowers.jpg"))
// radial segment angle
ang# = (360.0 / pieces)
// center of wheel
cx = getVirtualWidth()/2
cy = getVirtualHeight()/2
outerRad = 300 // outer radius of wheel
innerRad = 100 // inner radius of wheel
spacing = 4 // small gap between segments
// Draw a single wheel segment
for x = cx+spacing to cx+outerRad
for y = cy-outerRad to cy
ax = abs(cx-x)
ay = abs(cy-y)
r2 = (ax*ax + ay*ay)
if r2 > innerRad^2 and r2 < outerRad^2
if atanfull(x-cx,y-cy) <= ang#
c = black
if r2 < (innerRad+10)^2 then c = c0
drawBox(x,y,x+1,y+1,c,c,c,c,1)
endif
endif
next y
next x
// Grab image of wheel segment and create first sprite
items[0].spr = createSprite(getImage(cx, cy-outerRad, outerRad, outerRad))
setSpriteOffset(items[0].spr, 0, outerRad)
setSpritePositionByOffset(items[0].spr, cx, cy)
setSpriteColorAlpha(items[0].spr, 200)
items[0].scale = 1
// Create remaining sprites of wheel
for i = 1 to pieces-1
items[i].spr = cloneSprite(items[0].spr)
setSpriteAngle(items[i].spr, i*ang#)
items[i].scale = 1
next i
do
mx = getRawMouseX()
my = getRawMouseY()
// Get menu item mouse is over
r2 = (abs(mx-cx)^2 + abs(my-cy)^2)
segment = -1 // no menu item selected
if r2 > innerRad^2 and r2 < outerRad^2
a# = atanfull(mx-cx, my-cy)
segment = floor(a# / ang#)
endif
// Loop over menu items (basically just for subtle animations)
for i = 0 to pieces-1
if i = segment
if items[i].scale < 1.1 then items[i].scale = items[i].scale + 0.02
else
if items[i].scale > 1 then items[i].scale = items[i].scale - 0.02
endif
setSpriteScaleByOffset(items[i].spr, items[i].scale, items[i].scale)
next i
print(screenfps())
Sync()
loop