Log In  


Cart #53250 | 2018-06-04 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
7

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!

7



[Please log in to post a comment]