Log In  


Okay so I'm looking to make an orb animation like this: https://jsfiddle.net/aycn3fzd/
I'm not really sure if the solution is within that post or not, I'm having a hard time converting it.
Regardless, I'll explain what I have and the issue I'm having with completing this task.
Here's what I have atm:

I want an orb that will fill/unfill based on the percent of something left. So the generic red hp orb for example. A player has x hp. That hp as a percent x/100 will influence the percent of which the orb is filled from bottom to top red. You can see in the gif above I have this working for 'part' of the circle. The problem is the other sections.

My method for drawing the circle in this example is drawing the 0->15degrees side arc using sin/cos and reflecting it 8x...I posted earlier 3-4 other circle drawing methods, but I'm using the cos()/sin() one here for accuracy's sake. To fill in the circle I am using the line() method and extending it to the other side so I only need 4 instances. I don't fully understand the rect() method and have had issues getting it to look right (I assume u draw a square right center of the circle but the corners usually stickout and look off...maybe that assumption is the problem).

Anyways, drawing the lines for every y value of the circle I endup with the inverted version of the red picture there, which when reflected again gets the yellow version of itself there. Each of these shapes and their inverted version, when positioned properly will create a nice circfill() mimick:

So the red one is working in the first gif. The problem is the orange ones...when I apply the method they shrink width-wise and i need them shrinking height-wise. Looking at how I derive them, its clear why they are doing that, its cause I'm deriving everything from the original 0->12.5 degree segment and I draw that segment with horizontal lines. One solution might be to redraw it with vertical lines and use that for 2 of the sections and the horizontal for the other 2...but I have no idea how to do that and from my testing question if that is possible. Here we see the problem below:

The effect worked above by deleting the red lines....making it go up/down. If we delete the brown lines we affect the width when we want to affect the height. Maybe I could draw ellipse halves at the top and bottom and draw those using the elipsefill() builtin thing and dynamically change the radius...it would be cheating sorta, but might work.

The third issue is how to determine 'when' one section should be shrinking and the others should be statically fully displayed or fully cleared from the screen. I prefer the idea of doing this with 1 circle such that when the orb is drained...u can see the gameplay behind rather than a second fully displayed 'background' circfill().

percent=100 --how full the circle/orb is as a percent
function _draw()cls()
	if percent>0 then percent-=1 end --orb draining from full
	orbfill(63,63,30,8)
end
function orbfill(cx,cy,r,c,q)
poke(0x5f25,c) --set color
q=q or (r>15 and .005 or .01) --pixels per arc, .01 default
	for i=0,.125,q do --angle runs from 0->.125 then reflects this arc 8x
		local x,y=r*cos(i),r*sin(i)
		--circ() method
		pset(cx+x,cy+y)
		pset(cx-y,cy-x)--miry=x .5
		pset(cx-y,cy+x)--mir .75
		pset(cx+y,cy-x)--mir .25
		pset(cx+y,cy+x)--mir .625
		pset(cx+x,cy-y) --x flip
		pset(cx-x,cy+y) --y flip
		pset(cx-x,cy-y) --xy flip
		--circfill() method
		-- line(cx-x,cy-y,cx+x,cy-y)
		-- line(cx-x,cy+y,cx+x,cy+y)
		-- line(cx+y,cy-x,cx+y,cy+x)
		-- line(cx-y,cy-x,cx-y,cy+x)
	end
--[[So the above is just the normal circ()/circfill() function. 
My method for the animation is the idea we have zones that activate based on the 'percent' var. 
Then we take a percent of a percent when we are in each section to run through 0 to var*12.5 degrees of arc
....where the var will drain that 12.5 to 0 based on the percentages...which decreases the number of 
horizontal line stacks. This presents problems already as to how to get this working nicely. 
The above loop is just to show the starting point, it can be removed.
--diameter is 2*r=60; r=30
--heights of segments: 8.7868 top; upper 21.2132; lower 21.2132; low is 8.7868
--21.2132*2+8.7868*2=60 --ttl height of circle with r=30

21.2132/60 --0.35355333333333333
8.7868/60 --0.14644666666666667
--lets say its 15%+35%+35%+15%
percent==100
--top segment decreases
==85
--upper mid decreases
==50
--lower mid decreases
==15
--lower segment decreases

If percent is above a tier, then that tier would need to remain fully displayed at 100%.
@percent==100 all four tiers and segments are 100%.; percent==90 the bottom 3 are full, top 1 draining
]]

--outline for method:
if percent>85 then
	for i=0,k,q do --0->.125 then reflects
		local x,y=r*cos(i),r*sin(i)
--		line(cx-x,cy+y,cx+x,cy+y) --upper mid
--		line(cx-x,cy-y,cx+x,cy-y) --lower mid
	end
--the first gif works based on this:
elseif percent<=85 then--(21.2132*2+8.7868)/60 then --0.8535533333333334
	local rat=(percent-50)/35 
--a percent of a percent: percent=85%->50% transposed on i=0->12.5 degrees
--we make that 30% section of percent into a 100% segment and use to determine the deg out of 12.5
	for i=0,k*rat,q do 
		local x,y=r*cos(i),r*sin(i)
		line(cx-x,cy+y,cx+x,cy+y)
	end
end

end


1

looks like clip() + regular circfill would be a much simpler path:

Cart #ganarohado-0 | 2022-04-03 | Code ▽ | Embed ▽ | No License


That's hilarious actually. I was given the method below which is clean, but about 5x 'more costly' than what I was working on. But what you provided is literally 5x 'less costly' than what I was working on. Sooo I think I'll go with what you provided, much thanks.

--orb_anim(63,63,30,8,pc_hp)
function orb_anim(cx,cy,r,c,pct)poke(0x5f25,c) 
   for h=1,pct do --pct=[0,100]
      local y=r*(2*h/100-1) 
      local x=sqrt(r^2-y^2) 
      line(cx-x,cy-y,cx+x,cy-y,8)

good (note that sqrt solution could still be useful to mask a sprite, say to display some bubles in the mana)


One problem I'm having with the code is that it always shows that last bottom line of the circle even at pct=0. I'd like to have pct=0 show nothing, and pct=100% show everything. It actually seems to be considering that bottom line as the 0 point, since when I'm @ pct=.03, something super small, its showing an extra line...so 2 in total. In other words, any pct value will show at least 2 lines. I'm not understanding why I can't fix this, I've been tinkering with the clip() area...but is it the relationship with h and rounding error that isn't allowing this to work or is there a fix? The only fix I can think of is to hide the circ() at pct=0....but that's not accurate. The top part of the circle, by contrast, when its near pct=100% its displaying 100% of the circle rather than automatically clipping at least one line, which is what I want.

function manafill(x0,y0,r,pct)
 local h=2*pct*r
 clip(x0-r,y0+r-h,2*r,h+1+1) --added another +1 to deal with that weird flickering
 circfill(x0,y0,r,12)
 clip()
end


[Please log in to post a comment]