Log In  


Cart #ball_effects-0 | 2019-10-14 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
30

Made this cart to test some distortion effects for future projects.

A lot of people got interested in a tweet I made with it so I'm posting here in case anyone wants to see the code or use it on a project.

Move with the mouse;
Z/X (O/X) to change size;
Left mouse click to switch effect.

30


1

Omy ! number 5 is just like a real glass ball. Superb graphics ! Star for you.


1

Great job ! I was curious to see if it could be accelerated with some tricks I discovered recently and I get a 14% bonus on first effect. I was happy with this and try to increase radius, but it actually allow +2 before going >100% :'( It costs more token, is difficult to read and allow 2 pixels more on radius :D

It could be accelerated a bit more, using poke2 or poke4 but I didn't try.

for science :

function ef_vac(r)
  local r=r
  local rr=r*r
  for j=-r,r do
    for i=-r,r,2 do
      local s=i*i+j*j
      if s<rr then

        --vacuum
        local ss=1+(s/r-2*sqrt(s))/r
        local px,py=i+x,j+y
        local sidx=
        bor(band(shr(i+r,1),0x3f),
        shl(band(j+r,0x3f),6))
        --				sset(i+r,j+r,
        --				pget(
        --				flr(px+i*ss),
        --				flr(py+j*ss)
        --				)
        --				)
        --    local c1=
        -- pget(flr(px+i*ss),flr(py+j*ss))
        local of7=
        bor(band(px+i*ss,0x7f),
        shl(band(py+j*ss,0x7f),7))
        local c1=band(shr(
        peek(0x6000+of7/2)
        ,of7%2*4) ,0xf)
        i+=1
        px=i+x
        s=i*i+j*j
        ss=1+(s/r-2*sqrt(s))/r
        --    local c2=
        -- pget(flr(px+i*ss),flr(py+j*ss))
        of7=
        bor(band(px+i*ss,0x7f),
        shl(band(py+j*ss,0x7f),7))
        local c2=band(shr(
        peek(0x6000+of7/2)
        ,of7%2*4),0xf)
        poke(sidx,
        bor(shl(c2,4),c1))
        --     sset(i+r-1,j+r,c1)
        --     sset(i+r,j+r,c2)
      end
    end
  end

  circfill(x,y,r-2,0)
  sspr(0,0,r*2,r*2,x-r,y-r)
end

I think a good approach to make it less cpu intensive would be to mirror the effect in 4 quadrants since most effects are mirrored vertically and horizontally.

Another way could be to make a offset mask and save it on the spr memory, though this one only works if you don't indend to change the effect size/time at runtime.

It really depends on what it will be used for in the game :)


Commentated version of one of the effects:

function ef_mirr(r)
 --r = radius
 local rr=r*r
 --i,j = iterates every pixel in a square that will contain the circle
	for i=-r,r do
		for j=-r,r do
		 --s = hypotenuse - it will calculate the distance from the center (0=center; 1=border)
		 --sometimes will use "s=(i*i+j*j)/rr" instead to change s from a linear to a parabolic funtion
			s=sqrt(i*i+j*j)/r
			--s<1 will ensure you only draw in the circle and note the entire rectangle
			if s<1 then

			 --ss is where the magic happens, each effect will distort s into ss using a different function
			 --you can try to experiment other effects by changing how s and ss are calculated
	   --mirror ball
	   ss=-1/s

    --px and py are the actual pixel coordinates on the screen
				local px,py=i+x,j+y
				--sset will draw the effect on the sprite sheet
				sset(i+r,j+r,

				--pget will copy a pixel elswhere on the screen draw it inside the circle
				--you can replace this with "s*16" or "ss*16" to get a rough idea of how the pixel offset affects the final result
				--in some cases the sine/cosine effect will be used here
				pget(
				flr(px+i*ss),
				flr(py+j*ss)
				)

				)
			end
		end
 end

 --draw a black circle to erase the background inside the circle
 circfill(x,y,r-1,0)
 --copy the circle from the background to the screen
 sspr(0,0,r*2,r*2,x-r,y-r)
end


[Please log in to post a comment]