This is a short snippet showing how the water reflection effect is implemented in Pilot8.
Here is the code:
local g_rnd=nil local g_clk=0 function _init() init_rnd() end function init_rnd() g_rnd={} for i=1,64 do add(g_rnd,flr(rnd(32))) end end function _update() g_clk+=1 end function render_water(water_y) local addr_w=0x6000+64*water_y local addr_r=addr_w local rip_c=0x11 memset(addr_w,rip_c,64) for y=water_y+1,127 do addr_w+=64 addr_r-=(y%2)*64 local offset=1+(flr(g_clk/4)+y)%#g_rnd local prand=g_rnd[offset] if 0~=band(prand,30) then memcpy(addr_w,addr_r+prand%2*64,64) else memset(addr_w,rip_c,64) end end end function _draw() cls(0) map(0,0) print("pilot8 water effect", band(g_clk,127),88,7) render_water(96) end |
Quick summary: I pre-generate some pseudo-random numbers on _init() because I want to use the same sequence every frame, shifted by the clock (to give continuity to the water animation, rather than make it random at every frame). Then, in render_water(), it's just a matter of starting at the water horizon line (water_y) and copying rows from above water to the area below the water line, one by one. Except that I move the "read" position only once every 2 frames to make the reflection "stretched", and use the pseudo-random number to vary the read position to get the "wavy" effect. Also, once in while, instead of drawing the reflection I draw a solid blue ripple line.
Feel free to reuse this code in any way you like!
[Please log in to post a comment]