Lava Lamp

Blitz3D Forums/Blitz3D Beginners Area/Lava Lamp

Does anyone know how to make a virtual lava lamp. I made one but it was just a bunch of circles moving around the screen. I just can't get it to look like a real lava lamp.

Here is the code below. The only picture you need is a 32*32 white circle named ptcl.bmp

Graphics3D 640,480,0,2

lit=CreateLight()
SeedRnd(MilliSecs())

AppTitle "Lava Lamp Particles"

cam=Createcamera()
CameraRange cam,.1,1000
PositionEntity cam,0,0,-10
pl=CreatePlane(1,cam)
PositionEntity pl,0,0,.15
RotateEntity pl,-90,0,0
EntityAlpha pl,0
EntityPickMode pl,2

Global drag = true

Type pt
	Field x#,y#,dx#,dy#,temp#,ent
End Type
num = Input("Please enter the number of particles you want to have. ")
For i = 1 To num
	p.pt = New pt
	p\x# = Rnd#(0,640)
	p\y# = Rnd#(0,480)
	p\ent = LoadSprite("ptcl.bmp")
	p\temp = 0
Next
SetBuffer BackBuffer()
While Not KeyDown(1)
Cls
If KeyHit(57) Then drag = Not drag

For p.pt = Each pt
p\x# = p\x# + p\dx#
p\y# = p\y# + p\dy#

EntityColor p\ent,p\temp,(-p\temp)+255,0
sprite2d(cam,p\ent,p\x#,p\y#,30,0,1)
p\dy# = p\dy# + ((-p\temp#/255)+1)/10 - .05

If p\temp# > 0 Then p\temp# = p\temp# - .1

If p\y# > 480 Then
	p\dy# = -p\dy#/2
	p\y# = 479
EndIf
If p\x# > 640 Then
	p\dx# = -p\dx#/2
	p\x# = 639
EndIf
If p\x# < 0 Then
	p\dx# = -p\dx#/2
	p\x# = 1
EndIf
If p\y# < 0 Then
	p\dy# = -p\dy#/2
	p\y# = 1
EndIf

If drag Then
	If MouseDown(1) Then
		dist# = Sqr((p\x#-MouseX())^2+(p\y#-MouseY())^2)
		If dist# < 50 Then
			If p\temp# < 255 Then p\temp# = p\temp# + 30*(-dist# + 50)/50
		EndIf
	ElseIf MouseDown(2)
		dist# = Sqr((p\x#-MouseX())^2+(p\y#-MouseY())^2)
		If dist# < 50 Then
			If p\temp# > 0 Then p\temp# = p\temp# - 30*(-dist# + 50)/50
		EndIf
	EndIf
Else
	If MouseDown(1) Then
		dist# = Sqr((p\x#-MouseX())^2+(p\y#-MouseY())^2)
		If dist# < 50 Then
			p\x# = MouseX()
			p\y# = MouseY()
			p\dx# = 0
			p\dy# = 0
		EndIf
	EndIf
EndIf
For g.pt = Each pt
	If g\x# <> p\x# Or g\y# <> p\y# Then
		dist# = Sqr((p\x#-g\x#)^2+(p\y#-g\y#)^2)
		If dist# < 20 Then
			If p\temp# > g\temp# Then
				p\temp# = p\temp# - 10
				g\temp# = g\temp# + 10
			ElseIf p\temp# < g\temp# Then
				p\temp# = p\temp# + 10
				g\temp# = g\temp# - 10
			EndIf
			dx# = p\x# - g\x#
			dy# = p\y# - g\y#
			dx# = dx#*(dist#/20)
			dy# = dy#*(dist#/20)
			p\x# = p\x# + dx#/5
			p\y# = p\y# + dy#/5
			p\dx# = -p\dx#/3+Rnd(-.01,.01)
			p\dy# = -p\dy#/3+Rnd(-.01,.01)
			
		EndIf
	EndIf
Next

Next

UpdateWorld()
RenderWorld()
Flip
Wend
End

Function Sprite2D(cam,sprite,x#,y#,size#,ang#,alpha#)
	ent=CameraPick(cam,x,y)
	If ent Then 
		PositionEntity sprite,PickedX(),PickedY(),PickedZ()
		ScaleSprite sprite,size/2560,size/2560
		RotateSprite sprite,ang
		EntityAlpha sprite,alpha
	End If
End Function


Just click the circles to heat them up and right click them to cool them down.

Please give me any suggestions you have on how to make this look more realistic.

P.S. I recommend 100 particles.

Could someone please help me with this.

Your code isn't working here and I don't have time to look through it, but here is a lavaball effect I did a few years ago.

Edit: you will need an image to make this work. Use the code in the next post to make it.


Const ScreenWidth = 320
Const ScreenHeight = 240

Graphics3D ScreenWidth,ScreenHeight,0,2
SetBuffer BackBuffer()

Dim image(screenwidth,screenheight)

Global tx#,ty#

Type vector2
	Field x#
	Field y#
End Type

Type particle
	Field entity 
	Field pos.vector2
	Field vel.vector2
	Field mass#
	Field force.vector2
End Type

blobtex = LoadTexture ("blob.bmp")

For loop = 1 To 50
	a.particle = New particle
	a\entity = CreateSprite ()
	a\pos = New vector2
	a\pos\x = Rnd(-30,30)
	a\pos\y = Rnd(-30,30)
	a\vel = New vector2
	a\vel\x = Rnd(-0.20,0.20)
	a\vel\y = Rnd(-0.20,0.20)
	a\mass = Rnd(3,10)

	ScaleSprite a\entity,a\mass,a\mass
	EntityTexture a\entity,blobtex
	EntityFX a\entity,1 ; full bright
	EntityBlend a\entity,3 ;additive mix
Next

cam = CreateCamera ()
PositionEntity cam,0,20,0
TurnEntity cam,90,0,0

CameraClsColor cam,0,79,174
ClsColor 0,79,174

While Not KeyHit(1)	
	updateblobs()
	MoveEntity cam,0,0,MouseZSpeed () *2
	;UpdateWorld()
	RenderWorld()

	drawblobs() ;draw the screen using a threshold
	;drawblobs2() ;draw the screen using a threshold (one color version)

	Flip 	
Wend

End

Function 	updateblobs()
	For p.particle = Each particle
		p\pos\x = p\pos\x + p\vel\x
		p\pos\y = p\pos\y + p\vel\y

		If p\pos\x  > 32 Or  p\pos\x  < -32 p\vel\x = -p\vel\x
		If p\pos\y  > 32 Or  p\pos\y  < -32 p\vel\y = -p\vel\y

		PositionEntity p\entity,p\pos\x,0,p\pos\y	
	Next
End Function

Function drawblobs2()	;make blobs
	LockBuffer BackBuffer()
		For x = 0 To ScreenWidth -1
			For y = 0 To ScreenHeight -1
				argb=ReadPixelFast(x,y);ImageBuffer(image_name))
				gotr=(ARGB Shr 16) And $ff 
				;gotg=(ARGB Shr 8) And $ff 
				;gotb=ARGB And $ff
				If gotr > 128
					WritePixelFast x,y,$0080FF
				Else
					WritePixelFast x,y,$004FC6
				EndIf 
			Next
		Next
	UnlockBuffer BackBuffer()
End Function

Function drawblobs()	;make blobs
	LockBuffer BackBuffer()
		For x = 0 To ScreenWidth -1 
			For y = 0 To ScreenHeight -1 
				argb=ReadPixelFast(x,y)
				r=(ARGB Shr 16) And $ff 
				If r > 105
					WritePixelFast x,y,$000000;$0080FF
				ElseIf r > 64
					WritePixelFast x,y,$ffffff
				Else 

				EndIf 
			Next
		Next

	UnlockBuffer BackBuffer()
End Function





Can't post an image at the moment, but you will need an image for the code above. Use this code to generate a simple gradient image,... then use it in the code above.



;Load image : blob2.png
Restore IMAGE_DATAS_blob2_png
Read imgW%
Read imgH%
img=CreateImage(imgW,imgH)
SetBuffer ImageBuffer(img)
LockBuffer ImageBuffer(img)
For x=0 To imgW-1
	For y=0 To imgH-1
		Read rgb%
		WritePixelFast x,y,rgb%
	Next
Next
UnlockBuffer ImageBuffer(img)
SetBuffer BackBuffer()

SaveImage(img,"blob.bmp")

;blob2.png (32x32)
.IMAGE_DATAS_blob2_png
Data 32
Data 32
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $010101, $010101, $020202, $020202
Data $020202, $020202, $020202, $010101, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $010101, $030303, $050505, $060606, $070707, $080808
Data $080808, $070707, $070707, $060606, $040404, $030303, $010101, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $010101, $030303, $060606, $090909, $0C0C0C, $0E0E0E, $101010, $101010
Data $111111, $111111, $0F0F0F, $0D0D0D, $0B0B0B, $080808, $060606, $030303
Data $010101, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $030303
Data $050505, $090909, $0D0D0D, $111111, $151515, $181818, $1B1B1B, $1C1C1C
Data $1D1D1D, $1C1C1C, $1B1B1B, $181818, $151515, $101010, $0C0C0C, $090909
Data $050505, $020202, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $030303, $070707
Data $0C0C0C, $111111, $171717, $1C1C1C, $222222, $262626, $292929, $2A2A2A
Data $2B2B2B, $2B2B2B, $282828, $252525, $212121, $1B1B1B, $161616, $101010
Data $0B0B0B, $060606, $030303, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $030303, $070707, $0D0D0D
Data $131313, $1A1A1A, $222222, $292929, $2F2F2F, $353535, $393939, $3C3C3C
Data $3C3C3C, $3B3B3B, $383838, $343434, $2E2E2E, $282828, $202020, $191919
Data $121212, $0C0C0C, $060606, $030303, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $030303, $070707, $0D0D0D, $141414
Data $1D1D1D, $262626, $2F2F2F, $373737, $404040, $464646, $4B4B4B, $4E4E4E
Data $4F4F4F, $4E4E4E, $4B4B4B, $454545, $3F3F3F, $363636, $2D2D2D, $242424
Data $1B1B1B, $131313, $0C0C0C, $060606, $020202, $000000, $000000, $000000
Data $000000, $000000, $000000, $010101, $050505, $0C0C0C, $131313, $1D1D1D
Data $272727, $323232, $3E3E3E, $474747, $515151, $595959, $5F5F5F, $636363
Data $646464, $636363, $5E5E5E, $575757, $4F4F4F, $454545, $3B3B3B, $303030
Data $252525, $1B1B1B, $121212, $0A0A0A, $050505, $010101, $000000, $000000
Data $000000, $000000, $000000, $030303, $090909, $111111, $1B1B1B, $262626
Data $323232, $3F3F3F, $4C4C4C, $585858, $636363, $6D6D6D, $757575, $797979
Data $7A7A7A, $787878, $737373, $6C6C6C, $606060, $565656, $4A4A4A, $3C3C3C
Data $2F2F2F, $232323, $181818, $0F0F0F, $080808, $030303, $000000, $000000
Data $000000, $000000, $010101, $060606, $0D0D0D, $171717, $222222, $2E2E2E
Data $3E3E3E, $4C4C4C, $5A5A5A, $6A6A6A, $767676, $828282, $898989, $8F8F8F
Data $919191, $8E8E8E, $898989, $808080, $737373, $676767, $575757, $494949
Data $3A3A3A, $2D2D2D, $1F1F1F, $151515, $0C0C0C, $050505, $010101, $000000
Data $000000, $000000, $030303, $090909, $111111, $1C1C1C, $292929, $383838
Data $474747, $585858, $6A6A6A, $7A7A7A, $898989, $969696, $9F9F9F, $A5A5A5
Data $A7A7A7, $A5A5A5, $9E9E9E, $939393, $878787, $767676, $676767, $555555
Data $444444, $353535, $272727, $1A1A1A, $0F0F0F, $070707, $020202, $000000
Data $000000, $010101, $050505, $0C0C0C, $161616, $222222, $2F2F2F, $404040
Data $515151, $646464, $767676, $898989, $9A9A9A, $A9A9A9, $B4B4B4, $BABABA
Data $BDBDBD, $BABABA, $B1B1B1, $A6A6A6, $969696, $868686, $737373, $5F5F5F
Data $4D4D4D, $3C3C3C, $2D2D2D, $1F1F1F, $131313, $0A0A0A, $030303, $000000
Data $000000, $010101, $060606, $0E0E0E, $181818, $262626, $353535, $464646
Data $595959, $6D6D6D, $818181, $969696, $A9A9A9, $B8B8B8, $C6C6C6, $CECECE
Data $D1D1D1, $CECECE, $C4C4C4, $B6B6B6, $A5A5A5, $919191, $7E7E7E, $6A6A6A
Data $555555, $424242, $323232, $232323, $161616, $0C0C0C, $050505, $010101
Data $000000, $020202, $070707, $101010, $1B1B1B, $292929, $393939, $4B4B4B
Data $5F5F5F, $757575, $898989, $9F9F9F, $B4B4B4, $C6C6C6, $D5D5D5, $E1E1E1
Data $E5E5E5, $E0E0E0, $D3D3D3, $C4C4C4, $B0B0B0, $9A9A9A, $868686, $707070
Data $5B5B5B, $474747, $353535, $262626, $181818, $0E0E0E, $060606, $010101
Data $000000, $020202, $070707, $101010, $1C1C1C, $2B2B2B, $3C3C3C, $4E4E4E
Data $636363, $797979, $8F8F8F, $A5A5A5, $BBBBBB, $CFCFCF, $E1E1E1, $EFEFEF
Data $F3F3F3, $EDEDED, $DDDDDD, $CBCBCB, $B7B7B7, $A1A1A1, $8B8B8B, $757575
Data $5F5F5F, $4B4B4B, $383838, $282828, $1A1A1A, $0F0F0F, $070707, $010101
Data $000000, $020202, $080808, $111111, $1D1D1D, $2B2B2B, $3C3C3C, $4F4F4F
Data $646464, $7A7A7A, $919191, $A7A7A7, $BDBDBD, $D1D1D1, $E5E5E5, $F3F3F3
Data $FEFEFE, $F0F0F0, $E0E0E0, $CECECE, $BABABA, $A3A3A3, $8C8C8C, $767676
Data $606060, $4B4B4B, $383838, $282828, $1B1B1B, $0F0F0F, $060606, $010101
Data $000000, $020202, $080808, $111111, $1C1C1C, $2B2B2B, $3B3B3B, $4E4E4E
Data $636363, $787878, $8F8F8F, $A4A4A4, $BABABA, $CECECE, $E0E0E0, $EDEDED
Data $F0F0F0, $EAEAEA, $DCDCDC, $CBCBCB, $B6B6B6, $A0A0A0, $8A8A8A, $747474
Data $5E5E5E, $4A4A4A, $383838, $272727, $1A1A1A, $0E0E0E, $060606, $010101
Data $000000, $020202, $070707, $0F0F0F, $1B1B1B, $282828, $383838, $4A4A4A
Data $5E5E5E, $737373, $888888, $9E9E9E, $B2B2B2, $C4C4C4, $D3D3D3, $DEDEDE
Data $E0E0E0, $DCDCDC, $D0D0D0, $C0C0C0, $AFAFAF, $999999, $848484, $6F6F6F
Data $5A5A5A, $474747, $353535, $262626, $181818, $0D0D0D, $060606, $010101
Data $000000, $010101, $060606, $0D0D0D, $181818, $252525, $343434, $454545
Data $575757, $6C6C6C, $808080, $939393, $A6A6A6, $B6B6B6, $C2C2C2, $CBCBCB
Data $CECECE, $CBCBCB, $C1C1C1, $B2B2B2, $A3A3A3, $909090, $7B7B7B, $686868
Data $535353, $414141, $313131, $222222, $161616, $0C0C0C, $050505, $010101
Data $000000, $000000, $040404, $0B0B0B, $151515, $212121, $2E2E2E, $3F3F3F
Data $4F4F4F, $626262, $747474, $878787, $969696, $A5A5A5, $AFAFAF, $B7B7B7
Data $BABABA, $B5B5B5, $AFAFAF, $A3A3A3, $939393, $838383, $707070, $5E5E5E
Data $4C4C4C, $3B3B3B, $2C2C2C, $1E1E1E, $131313, $0A0A0A, $030303, $000000
Data $000000, $000000, $030303, $080808, $101010, $1B1B1B, $282828, $363636
Data $454545, $565656, $676767, $757575, $868686, $929292, $9C9C9C, $A0A0A0
Data $A3A3A3, $A0A0A0, $999999, $909090, $838383, $737373, $646464, $535353
Data $424242, $333333, $262626, $191919, $0F0F0F, $070707, $020202, $000000
Data $000000, $000000, $010101, $060606, $0C0C0C, $161616, $212121, $2D2D2D
Data $3B3B3B, $4A4A4A, $585858, $676767, $727272, $7E7E7E, $868686, $8B8B8B
Data $8C8C8C, $8A8A8A, $848484, $7B7B7B, $707070, $646464, $565656, $464646
Data $383838, $2B2B2B, $1F1F1F, $141414, $0B0B0B, $050505, $010101, $000000
Data $000000, $000000, $000000, $030303, $090909, $101010, $191919, $232323
Data $2F2F2F, $3C3C3C, $494949, $555555, $606060, $696969, $707070, $757575
Data $767676, $747474, $6F6F6F, $686868, $5E5E5E, $535353, $454545, $3A3A3A
Data $2D2D2D, $222222, $181818, $0E0E0E, $070707, $020202, $000000, $000000
Data $000000, $000000, $000000, $010101, $050505, $0B0B0B, $121212, $1B1B1B
Data $252525, $2F2F2F, $3B3B3B, $434343, $4D4D4D, $565656, $5B5B5B, $5F5F5F
Data $606060, $5E5E5E, $5A5A5A, $545454, $4C4C4C, $414141, $373737, $2D2D2D
Data $232323, $191919, $111111, $0A0A0A, $040404, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $020202, $060606, $0C0C0C, $131313
Data $1B1B1B, $232323, $2D2D2D, $353535, $3C3C3C, $434343, $484848, $4B4B4B
Data $4B4B4B, $4A4A4A, $474747, $424242, $3B3B3B, $343434, $2B2B2B, $222222
Data $191919, $111111, $0B0B0B, $050505, $010101, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $030303, $060606, $0C0C0C
Data $121212, $181818, $1F1F1F, $272727, $2D2D2D, $323232, $353535, $383838
Data $383838, $383838, $353535, $313131, $2C2C2C, $262626, $1F1F1F, $181818
Data $111111, $0B0B0B, $050505, $020202, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $030303, $060606
Data $0A0A0A, $0F0F0F, $141414, $191919, $1F1F1F, $232323, $262626, $282828
Data $282828, $282828, $262626, $222222, $1E1E1E, $191919, $141414, $0F0F0F
Data $0A0A0A, $050505, $020202, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $020202
Data $040404, $080808, $0C0C0C, $101010, $131313, $161616, $181818, $1A1A1A
Data $1B1B1B, $1A1A1A, $181818, $161616, $131313, $0F0F0F, $0B0B0B, $070707
Data $040404, $010101, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $010101, $030303, $050505, $070707, $0A0A0A, $0C0C0C, $0E0E0E, $0F0F0F
Data $0F0F0F, $0E0E0E, $0D0D0D, $0C0C0C, $090909, $070707, $050505, $020202
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $010101, $020202, $030303, $050505, $060606, $070707
Data $060606, $060606, $060606, $050505, $030303, $020202, $010101, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $010101, $010101, $010101
Data $010101, $010101, $010101, $010101, $000000, $000000, $000000, $000000
Data $000000, $000000, $000000, $000000, $000000, $000000, $000000, $000000

 


Wow. I don't get how you did that but that isn't the effect I was looking for. Could you explain how it works anyway?

What error did you get when you tried to run my program?
Maybe if you get my program to work then you will get what I am asking about. :)

To see how it works, disable the command DrawBlobs(). There is also a DrawBlobs2() that you can try out.

What I do is move a bunch of soft-edged gradients around on the screen,... then I do a simple check with a threshold to make the image use just a few colors.

Unfortunately, pixel operations are really slow, so I need to keep this effect relatively small, and I used 3d so that I could use the additive blending mode for the initial blobs before the threshold.

Ahh,... my mistake.

Your code was fine. I just screwed up when I assigned a different image to it.

Here is another version that makes the blobs look shaded

Function drawblobs3()	;make blobs
	LockBuffer BackBuffer()
		For x = 0 To ScreenWidth -1
			For y = 0 To ScreenHeight -1
				argb=ReadPixelFast(x,y);ImageBuffer(image_name))
				gotr=(ARGB Shr 16) And $ff 
				;gotg=(ARGB Shr 8) And $ff 
				;gotb=ARGB And $ff
				If gotr > 128
					;WritePixelFast x,y,$0080FF
				Else
					WritePixelFast x,y,$000000
				EndIf 
			Next
		Next
	UnlockBuffer BackBuffer()
End Function


Thanks

I modified my own version to look more like lava. It really looks like a liquid!

Graphics3D 640,480,0,2

lit=CreateLight()
SeedRnd(MilliSecs())

AppTitle "Lava Lamp Particles"

cam=CreateCamera()
CameraRange cam,.1,1000
PositionEntity cam,0,0,-10
pl=CreatePlane(1,cam)
PositionEntity pl,0,0,.15
RotateEntity pl,-90,0,0
EntityAlpha pl,0
EntityPickMode pl,2

Global drag = True

Type pt
	Field x#,y#,dx#,dy#,temp#,ent
End Type
num = Input("Please enter the number of particles you want to have. ")
For i = 1 To num
	p.pt = New pt
	p\x# = Rnd#(0,640)
	p\y# = Rnd#(0,480)
	tex = LoadTexture("blob.bmp")
	p\ent = CreateSprite()
	EntityTexture p\ent,tex
	p\temp = 0
	EntityBlend p\ent,3
	EntityFX p\ent,1
Next
SetBuffer BackBuffer()
While Not KeyDown(1)
Cls
If KeyHit(57) Then drag = Not drag

For p.pt = Each pt
p\x# = p\x# + p\dx#
p\y# = p\y# + p\dy#

EntityColor p\ent,p\temp,(-p\temp)+255,0
sprite2d(cam,p\ent,p\x#,p\y#,80,0,1)
p\dy# = p\dy# + ((-p\temp#/255)+1)/10 - .05

If p\temp# > 0 Then p\temp# = p\temp# - .1

If p\y# > 480 Then
	p\dy# = -p\dy#/2
	p\y# = 479
EndIf
If p\x# > 640 Then
	p\dx# = -p\dx#/2
	p\x# = 639
EndIf
If p\x# < 0 Then
	p\dx# = -p\dx#/2
	p\x# = 1
EndIf
If p\y# < 0 Then
	p\dy# = -p\dy#/2
	p\y# = 1
EndIf

If drag Then
	If MouseDown(1) Then
		dist# = Sqr((p\x#-MouseX())^2+(p\y#-MouseY())^2)
		If dist# < 50 Then
			If p\temp# < 255 Then p\temp# = p\temp# + 30*(-dist# + 50)/50
		EndIf
	ElseIf MouseDown(2)
		dist# = Sqr((p\x#-MouseX())^2+(p\y#-MouseY())^2)
		If dist# < 50 Then
			If p\temp# > 0 Then p\temp# = p\temp# - 30*(-dist# + 50)/50
		EndIf
	EndIf
Else
	If MouseDown(1) Then
		dist# = Sqr((p\x#-MouseX())^2+(p\y#-MouseY())^2)
		If dist# < 50 Then
			p\x# = MouseX()
			p\y# = MouseY()
			p\dx# = 0
			p\dy# = 0
		EndIf
	EndIf
EndIf
For g.pt = Each pt
	If g\x# <> p\x# Or g\y# <> p\y# Then
		dist# = Sqr((p\x#-g\x#)^2+(p\y#-g\y#)^2)
		If dist# < 20 Then
			If p\temp# > g\temp# Then
				p\temp# = p\temp# - 10
				g\temp# = g\temp# + 10
			ElseIf p\temp# < g\temp# Then
				p\temp# = p\temp# + 10
				g\temp# = g\temp# - 10
			EndIf
			dx# = p\x# - g\x#
			dy# = p\y# - g\y#
			dx# = dx#*(dist#/20)
			dy# = dy#*(dist#/20)
			p\x# = p\x# + dx#/5
			p\y# = p\y# + dy#/5
			p\dx# = -p\dx#/3+Rnd(-.01,.01)
			p\dy# = -p\dy#/3+Rnd(-.01,.01)
			
		EndIf
	EndIf
Next

Next

UpdateWorld()
RenderWorld()
Flip
Wend
End

Function Sprite2D(cam,sprite,x#,y#,size#,ang#,alpha#)
	ent=CameraPick(cam,x,y)
	If ent Then 
		PositionEntity sprite,PickedX(),PickedY(),PickedZ()
		ScaleSprite sprite,size/2560,size/2560
		RotateSprite sprite,ang
		EntityAlpha sprite,alpha
	End If
End Function


It uses your blob image and effects to make it look a lot better. Thanks!!!

Hmmm... Might have a go at making my own lava lamp

I really like the way this small project turned out. Thanks Pongo.
Here is a program I call Interactive Amoeba. It uses blob.bmp again.
Click to make more blobs and right click in the middle of a big one to explode it!

Graphics3D 800,600,0,2
SeedRnd(MilliSecs())
SetBuffer BackBuffer()

lit=CreateLight()
SeedRnd(MilliSecs())

AppTitle "Lava Lamp Particles"

cam=CreateCamera()
CameraRange cam,.1,1000
PositionEntity cam,0,0,-10
pl=CreatePlane(1,cam)
PositionEntity pl,0,0,.15
RotateEntity pl,-90,0,0
EntityAlpha pl,0
EntityPickMode pl,2

Type pnt
	Field x#,y#
	Field dx#,dy#
	Field ent
End Type

p.pnt = New pnt
p\x = 400
p\y = 300
tex = LoadTexture("blob.bmp")
p\ent = CreateSprite()
EntityTexture p\ent,tex
EntityFX p\ent,1
EntityBlend p\ent,3
EntityColor p\ent,0,0,255



While Not KeyDown(1)
Cls

If MouseHit(1) Then
	p.pnt = New pnt
	p\x# = MouseX()
	p\y# = MouseY()
	tex = LoadTexture("blob.bmp")
	p\ent = CreateSprite()
	EntityTexture p\ent,tex
	EntityFX p\ent,1
	EntityBlend p\ent,3
	EntityColor p\ent,0,0,255
EndIf

For p.pnt = Each pnt

	sprite2d(cam,p\ent,p\x#,p\y#,60,0,1)
;	If KeyDown(57) Then p\dy# = p\dy# + .05
	
	
	If MouseDown(2) Then
		dist# = Sqr((p\x#-MouseX())^2+(p\y#-MouseY())^2)
		If dist# < 20 Then
			dx# = p\x# - MouseX()
			dy# = p\y# - MouseY()
			p\dx# = p\dx# + dx#/5
			p\dy# = p\dy# + dy#/5
		EndIf
	EndIf
	
	For g.pnt = Each pnt
		If p\x# <> g\x# And p\y# <> g\y# Then
			dist# = Sqr((p\x#-g\x#)^2+(p\y#-g\y#)^2)
			If dist < 60 Then
				If dist < 40 Then
					dx# = p\x# - g\x#
					dy# = p\y# - g\y#
					p\dx# = p\dx# + dx#/4000
					p\dy# = p\dy# + dy#/4000
				Else
					dx# = p\x# - g\x#
					dy# = p\y# - g\y#
					p\dx# = p\dx# - dx#/4000
					p\dy# = p\dy# - dy#/4000
				EndIf
			EndIf
		EndIf
	Next
;	If p\y# > 600 And KeyDown(57) Then
;		p\y# = 600
;		p\dy# = -p\dy#/2
;	EndIf
Next

For p.pnt = Each pnt
	p\x# = p\x# + p\dx#
	p\y# = p\y# + p\dy#
Next

UpdateWorld()
RenderWorld()
Flip
Wend
End



Function Sprite2D(cam,sprite,x#,y#,size#,ang#,alpha#)
	ent=CameraPick(cam,x,y)
	If ent Then 
		PositionEntity sprite,PickedX(),PickedY(),PickedZ()
		ScaleSprite sprite,size/2560,size/2560
		RotateSprite sprite,ang
		EntityAlpha sprite,alpha
	End If
End Function