Posted: 10th Apr 2024 19:09
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.





+ Code Snippet
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
Posted: 11th Apr 2024 21:20
Very sexy interface
Posted: 14th Apr 2024 9:14
Looks great, thanks for sharing.