如何实现一个水面

August 13, 2017

如何在2d游戏中实现一个水面?

水如何影响被水淹没的物体的颜色?

被水淹没的物体改变了颜色,这里处于水面以下的物体经过了一层映射,处于水面的物体经过了两层映射。颜色的映射存储在sprite-sheet中。

水下颜色的映射关系

通过一段简单的代码获取颜色的映射关系。

function dr_image()
	for i=0, 15 do
		local x = i * 8
		rectfill(x, 40, x+8, 48, i)
		rectfill(x, 50, x+8, 58, sget(48+i, 2))
	end
end

因为要表现的是绿色的水,所以大部分颜色都映射成了绿色,以及黄色。

水表面颜色的映射关系

映射代码,注意两次sget实现了颜色的两次映射:

function dr_image()
	for i=0, 15 do
		local x = i * 8
		rectfill(x, 40, x+8, 48, i)
		local pix=sget(48+i,1)	
		rectfill(x, 50, x+8, 58, sget(48+pix, 2))
	end
end

这次大部分的颜色都被映射成了浅绿色和黄色,这就是水表面的颜色。

如何让水面波动起来?

水面的波形很像cos,sin的函数图像。还记得高中的三角函数知识么?

具体绘制函数

通过遍历x轴的每一个像素,计算当前x对应的y坐标,波浪是通过三角函数计算所得。

通过first变量存储水面的厚度,这些像素会存在两次要颜色转换。

 -- ocean
 for x=0,127 do

  first=2			--水面同色层的厚度
  by=gwy(x)			--获取高度
  for y=by,128 do
   pix=pget(x,y)	--获取屏幕上需要绘制点的原始颜色
   if first>0 then
    for i=1,first do
     pix=sget(48+pix,1)	--获取spritesheet上(48+pix, 1)位置的颜色,一次颜色映射
    end
    first-=1
   end
   pset(x,y,sget(48+pix,2))	--获取spritesheet上(48+pix, 2)位置的颜色, 一次颜色映射
  end
 end

让它平静如水

给循环中获取高度的地方传递一个固定的值,让水面的y值固定下来,就能获得一个平静的水面了。

by=90

让水面变厚实一些

first=5			--水面同色层的厚度

让水面波动更加明显些

给一个三角函数乘上一个值,让它y值范围增加。

 local n=cos((cmx*1+x)/48)*cos(t/40)*7 

总结一下本次实现一个水面的要素

颜色转换水表面颜色的特殊处理主要体现了水的物理材质特性,想不想喝一口呢:)

comments powered by Disqus