just a simple but "real" liquid or slime simulator
the map is a grid where the yellower parts a higher up.
press space to place the liquid at your mouse
press the mousekeys to rise/lower the terrain
the program will crash if the liquid gets outside the screen.
i suggest running it in 1680x1050
Rem Project: liquid3
Rem Created: Tuesday, January 10, 2012
Rem ***** Main Source File *****
sync on : w = screen width() : h = screen height() : sync rate 60 : a2setlineaa 0
gs = 25
a = w/gs
b = h/gs
dim x#(a,b) : dim y#(a,b) : dim z#(a,b) : dim c(a,b) as dword : dim nx#(a,b) : dim ny#(a,b)
dim vec(w,h) as UDTvector3
for i = 1 to a : for ii = 1 to b
x#(i,ii) = i*gs : y#(i,ii) = ii*gs : z#(i,ii) = max((sin(i*24)*sin(ii*3)+sin(ii*22)*sin(i*5+40))/2*510+510,100) : c(i,ii) = rgb(z#(i,ii)*0.2,z#(i,ii)*0.2,100)
NEXT : next
for i = 1 to 4 : n = make vector3(i) : next
for i = 2 to a-1 : for ii = 2 to b-1
set vector3 1,-1,0,z#(i-1,ii)-z#(i,ii) : set vector3 2,0,-1,z#(i,ii-1)-z#(i,ii) : set vector3 3,1,0,z#(i+1,ii)-z#(i,ii) : set vector3 4,0,1,z#(i,ii+1)-z#(i,ii)
cross product vector3 1,1,2 : normalize vector3 1,1 : if z vector3(1) < 0 then multiply vector3 1,-1
cross product vector3 2,3,4 : normalize vector3 2,2 : if z vector3(2) < 0 then multiply vector3 2,-1
add vector3 1,1,2 : normalize vector3 1,1
vec(i,ii).x# = x vector3(1) : vec(i,ii).y# = y vector3(1) : vec(i,ii).z# = z vector3(1)
NEXT : next
wc = 100
dim w(wc) as UDTWATER
vec1 = createvector()
for i = 1 to wc : w(i).vec = createvector() : next
friction# = 0.5
ener# = 50.1
miner# = 3
visc# = 1000
seldist# = 80000
modify# = 55000.0
a2setblendmode 2,1,1
do
mx# = mousex()
my# = mousey()
if spacekey()
for i = 1 to wc
w(i).x# = mx#+rnd(100) : w(i).y# = my#+rnd(100)
set vector2 w(i).vec,0,0
NEXT
endif
a2setblendmode 2,1,1
mz# = z#(int(mx#/gs+0.5),int(my#/gs+0.5))
a2startlinebatch a*b*2
for i = 1 to a : for j = 1 to b
z# = atanfull(mx#-x#(i,j),my#-y#(i,j))+180
nx#(i,j) = perspectivex(x#(i,j),z#,z#(i,j),mz#) : ny#(i,j) = perspectivey(y#(i,j),z#,z#(i,j),mz#)
a2line nx#(i,j),ny#(i,j),nx#(i-1,j),ny#(i-1,j),c(i,j),c(i-1,j)
a2line nx#(i,j),ny#(i,j),nx#(i,j-1),ny#(i,j-1),c(i,j),c(i,j-1)
md# = squaredist(mx#,my#,nx#(i,j),ny#(i,j))
if md# < seldist#
if mouseclick() = 1
z#(i,j) = minmax(z#(i,j)+min(modify#/(md#+40),5),0,1050) : c(i,j) = rgb(z#(i,j)*0.2,z#(i,j)*0.2,100)
modf = 1
endif
if mouseclick() = 2
z#(i,j) = minmax(z#(i,j)-min(modify#/(md#+40),5),0,1050) : c(i,j) = rgb(z#(i,j)*0.2,z#(i,j)*0.2,100)
modf = 1
endif
endif
NEXT : next
a2endbatch
if modf = 1
for i = 2 to a-1 : for j = 2 to b-1
set vector3 1,-1,0,z#(i-1,j)-z#(i,j) : set vector3 2,0,-1,z#(i,j-1)-z#(i,j) : set vector3 3,1,0,z#(i+1,j)-z#(i,j) : set vector3 4,0,1,z#(i,j+1)-z#(i,j)
cross product vector3 1,1,2 : normalize vector3 1,1 : if z vector3(1) < 0 then multiply vector3 1,-1
cross product vector3 2,3,4 : normalize vector3 2,2 : if z vector3(2) < 0 then multiply vector3 2,-1
add vector3 1,1,2 : normalize vector3 1,1
vec(i,j).x# = x vector3(1) : vec(i,j).y# = y vector3(1) : vec(i,j).z# = z vector3(1)
modf = 0
next : next
endif
for i = 1 to wc
w(i).gx = int(w(i).x#/gs+0.5) : w(i).gy = int(w(i).y#/gs+0.5)
set vector2 w(i).vec,(x vector2(w(i).vec)+vec(w(i).gx,w(i).gy).x#*0.1)*friction#,(y vector2(w(i).vec)+vec(w(i).gx,w(i).gy).y#*0.1)*friction#,
w(i).x# = w(i).x#+x vector2(w(i).vec) : w(i).y# = w(i).y#+y vector2(w(i).vec)
for j = 1 to wc
if j <> i and squaredist(w(i).x#,w(i).y#,w(j).x#,w(j).y#) < visc#
set vector2 vec1,w(i).x#-w(j).x#,w(i).y#-w(j).y#
len# = length vector2(vec1)
lenvec(vec1,(ener#)/(len#+miner#)*0.01)
rem if len# >= visc# then lenvec(vec1,-(len#-visc#)*0.001)
add vector2 w(i).vec,w(i).vec,vec1
ENDIF
w(i).x# = w(i).x#+x vector2(w(i).vec)*0.8 : w(i).y# = w(i).y#+y vector2(w(i).vec)*0.8
next
z# = atanfull(mx#-w(i).x#,my#-w(i).y#)+180
w(i).nx# = perspectivex(w(i).x#,z#,z#(w(i).gx,w(i).gy),mz#) : w(i).ny# = perspectivey(w(i).y#,z#,z#(w(i).gx,w(i).gy),mz#)
rem a2fillcircle w(i).nx#,w(i).ny#,2,rgb(20,40,80)
rem text w(i).nx#,w(i).ny#,str$(i)
NEXT
a2starttrianglebatch amount
a2setblendmode 2,1,1
amount = 0
for i = 1 to wc
done = 0
for j = 1 to wc
if squaredist(w(i).x#,w(i).y#,w(j).x#,w(j).y#) < 2500
if done = 1 then a2filltriangle w(i).nx#,w(i).ny#,w(j).nx#,w(j).y#,ox#,oy#,rgb(11,90,140) : inc amount
ox# = w(j).nx# : oy# = w(j).ny# : done = 1
rem a2line w(i).nx#,w(i).ny#,w(j).nx#,w(j).ny#,rgb(5,15,35)
rem a2dot w(i).nx#,w(i).ny#,rgb(255,255,255)
rem a2circle w(i).nx#,w(i).ny#,7,rgb(25,25,55)
rem a2fillcircle w(i).x#,w(i).y#,30,rgb(10,30,150)
endif
NEXT : next
a2endbatch
sync
cls
rem dimscreen(rgb(10,10,10))
LOOP
function perspectivex(x#,a#,z#,cz#)
x# = newxvalue(x#,a#,(z#/(cz#+40))*15.0)
endfunction x#
function perspectivey(y#,a#,z#,cz#)
y# = newzvalue(y#,a#,(z#/(cz#+40))*15.0)
endfunction y#
type UDTvector3
x# : y# : z#
endtype
type UDTWATER
x# : y# : z#
xs# : ys#
gx : gy
c as dword
vec
nx# : ny#
endtype
function dimscreen(dimness as dword)
a2setblendmode 2,2,3
a2fillbox 0,0,screen width(),screen height(),dimness
a2setblendmode 2,2,1 : a2dot 1,-10,0
ENDFUNCTION
function getbox(x#,w10)
x = x#/w10
endfunction x
function lenvec(vec,len#)
normalize vector2 vec,vec
multiply vector2 vec,len#
ENDFUNCTION
function createvector()
num = find free vector()
null = make vector2(num)
ENDFUNCTION num
function minmax(variable#,vmin#,vmax#)
if variable# < vmin# then variable# = vmin#
if variable# > vmax# then variable# = vmax#
endfunction variable#
function minmaxy(vec,variable#,vmin#,vmax#,b#)
if variable# < vmin# then variable# = vmin# : set vector2 vec,x vector2(vec)*b#,-y vector2(vec)*b#
if variable# > vmax# then variable# = vmax# : set vector2 vec,x vector2(vec)*b#,-y vector2(vec)*b#
endfunction variable#
function minmaxx(vec,variable#,vmin#,vmax#,b#)
if variable# < vmin# then variable# = vmin# : set vector2 vec,-x vector2(vec)*b#,y vector2(vec)*b#
if variable# > vmax# then variable# = vmax# : set vector2 vec,-x vector2(vec)*b#,y vector2(vec)*b#
endfunction variable#
function normangle(z1#,z2#)
if z1#-z2# < -180 then z1# = z1#+360
if z1#-z2# > 180 then z1# = z1#-360
endfunction z1#
function squaredist(x1#,y1#,x2#,y2#)
d# = (x1#-x2#)^2+(y1#-y2#)^2
ENDFUNCTION d#
function dist(x1#,y1#,x2#,y2#)
d# = sqrt((x1#-x2#)^2+(y1#-y2#)^2)
ENDFUNCTION d#