Code archives/3D Graphics - Misc/insect crawling demo!

This code has been declared by its author to be Public Domain code.

Download source code

insect crawling demo! by Rob
(Posted 23 years ago)
uses normals to hug surfaces. Updated slightly so you don't need media to run it.

Have fun!
;insect crawling demo
;rob@redflame.net

;definitions
Const c_insect=1,c_level=2
Const pedelength=20

 ; number of segments

Global camera,worldpivot
Global campitch#,camyaw#,mvx#,mvy#,mvz#,temp#,vx#,vy#,vz#

Global ball,pivot,level,txt$

Type pede
	Field ent[pedelength],pickpivot
	Field speed#,dist#
	Field misc
End Type


;setup graphics
Graphics3D 640,480,16,2
HidePointer

camera=CreateCamera()
PositionEntity camera,0,20,0

light=CreateLight(2)
PositionEntity light,0,20,0
LightRange light,20

;load level
;level=LoadMesh("level.b3d")
level=CreateLevel()

EntityAlpha level,0.4
EntityType level,c_level
EntityPickMode level,2

;make a few pedes
For n=0 To 5
	a.pede=New pede
	a\speed=.2
	a\dist=2.1
	
	;head
	a\ent[0]=CreateSphere(4)
	EntityColor a\ent[0],255,0,0
	EntityShininess a\ent[0],1
	ScaleEntity a\ent[0],.8,.8,1.2
	EntityType a\ent[0],c_insect
	EntityRadius a\ent[0],1
	PositionEntity a\ent[0],Rnd(-50,50),2,Rnd(-50,50)
	
	;body segs
	For i=1 To pedelength
		a\ent[i]=CreateSphere(4)
		EntityColor a\ent[i],255,0,0
		EntityShininess a\ent[i],1
		ScaleEntity a\ent[i],.8,.8,1.2
	Next
	
Next

Collisions c_insect,c_level,2,2

;mainloop
While Not KeyHit(1)
	UpdateWorld
	freelook()
	updategame()
	RenderWorld
	Flip 
Wend
End

;update game
Function updategame()
	Local nx#,ny#,nz#
	For a.pede=Each pede
	
		;calculate angle and stick to wall
		TurnEntity a\ent[0],5,0,0
		nx#=0:ny#=0:nz#=0	
		coll=EntityCollided(a\ent[0],c_level)
		If coll
			numcollisions = CountCollisions(a\ent[0])
			If numcollisions>0
				For i=1 To numcollisions
					nx=nx+CollisionNX(a\ent[0],i)
					ny=ny+CollisionNY(a\ent[0],i)
					nz=nz+CollisionNZ(a\ent[0],i)
				Next
				nx=nx/numcollisions
				ny=ny/numcollisions
				nz=nz/numcollisions
				AlignToVector a\ent[0],nx,ny,nz,2,.25
			EndIf ;numcollisions
		EndIf ;coll
		
		;the usual ai and stuff to do with speed and direction here
		If Rand(30)=1 TurnEntity a\ent[0],0,Rnd(-30,30),0
		MoveEntity a\ent[0],0,0,a\speed
	
		;update body segs
		For i=1 To pedelength	
			d#=EntityDistance(a\ent[i],a\ent[i-1])
			If d#>a\dist
				PointEntity a\ent[i],a\ent[i-1]
				MoveEntity a\ent[i],0,0,a\speed+d#-a\dist
			Else
				MoveEntity a\ent[i],0,0,a\speed+d#-a\dist
			EndIf
		Next

	Next
End Function

;camera freelook
Function freelook()
	mxspd#=MouseXSpeed()*0.25
	myspd#=MouseYSpeed()*0.25
	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
	campitch=campitch+myspd
	If campitch<-85 Then campitch=-85
	If campitch>85 Then campitch=85
	RotateEntity camera,campitch,EntityYaw(camera)-mxspd,0
	If KeyDown(203) Then mvx=mvx-.3
	If KeyDown(205) Then mvx=mvx+.3
	If KeyDown(200) Then mvz=mvz+.3
	If KeyDown(208) Then mvz=mvz-.3
	If KeyDown(30) Then mvx=mvx-.3
	If KeyDown(32) Then mvx=mvx+.3
	If KeyDown(17) Then mvz=mvz+.3
	If KeyDown(31) Then mvz=mvz-.3
	mvx#=mvx*.8
	mvy#=mvy*.8
	mvz#=mvz*.8
	MoveEntity camera,mvx,mvy,mvz
End Function

;create a test level
Function CreateLeveL()
	mesh=CreateMesh()
	
	box=CreateCube()
	FlipMesh box
	ScaleMesh box,40,23,32
	PositionMesh box,0,23,0
	AddMesh box,mesh
	
	box=CreateCube()
	ScaleMesh box,10,3,10
	PositionMesh box,22,3,-3
	AddMesh box,mesh

	box=CreateCube()
	ScaleMesh box,8,7,10
	PositionMesh box,-34,7,-22
	AddMesh box,mesh

	box=CreateCube()
	ScaleMesh box,8,6,13
	PositionMesh box,32,40,-10
	AddMesh box,mesh

	box=CreateCube()
	ScaleMesh box,16,6,4
	PositionMesh box,-12,40,4
	AddMesh box,mesh

	Return mesh
End Function

Comments

CyberHeater
(Posted 23 years ago)
That's a keeper.

Actually Rob. This is more like a tutorial 'cause it really neatly demonstrates some of Blitz's key features:-

1/ types
2/ Loading a level
3/ Collisions with levels
4/ Camera movement

It's really good. Thanks.

churchaxe
(Posted 22 years ago)
very nice and nasty, UUUAAAAHHHH!!! Thanx alot.

RGR
(Posted 21 years ago)
This is superb, Rob!!!

I made some minor changes. Hope you like it.
One stops the effect that the snake body moves through the cubes
Another is, that they do not move through each other anymore.
And finally ... well, just take a look ...

; ID: 1069
; Author: Rob [deleted]
; Date: 2004-06-04 16:42:05
; Title: insect crawling demo!
; Description: ewwwww! they crawl everywhere!
; minor AddOns: RaGR 2006-05-17

;insect crawling demo
;rob@...

;definitions
Const c_insect=1,c_level=2

Const pedelength=20

 ; number of segments

Global camera,worldpivot
Global campitch#,camyaw#,mvx#,mvy#,mvz#,temp#,vx#,vy#,vz#

Global ball,pivot,level,txt$

Type pede
	Field ent[pedelength]
	Field between[pedelength]
	Field pickpivot
	Field speed#,dist#
	Field misc
	Field fr,fl
	Field er,el
	Field eri,eli
End Type

SeedRnd MilliSecs()
;setup graphics
Graphics3D 1024,768,32,1
HidePointer

camera=CreateCamera()
PositionEntity camera,0,20,-20

light=CreateLight(2)
PositionEntity light,0,20,0
LightRange light,20

;load level
;level=LoadMesh("level.b3d")
level=CreateLevel()

EntityAlpha level,0.4
EntityType level,c_level
EntityPickMode level,2

;make a few pedes
For n=0 To 5
	a.pede=New pede
	a\speed=.2
	a\dist=2.4
	
	;head
	a\ent[0]=CreateSphere(4)
	EntityColor a\ent[0],0,222,0
	EntityShininess a\ent[0],1
	ScaleEntity a\ent[0],.95,.95,1.2
	EntityType a\ent[0],c_insect
	EntityRadius a\ent[0],1
	PositionEntity a\ent[0],Rnd(-50,50),2,Rnd(-50,50)

	a\fr=CreateCone(8,True,a\ent[0])
	EntityColor a\fr,255,0,255
	ScaleEntity a\fr,.3, 1, .3
	PositionEntity a\fr,EntityX(a\ent[0],True)-0.4,EntityY(a\ent[0],True)+1,EntityZ(a\ent[0],True)+0.6,True
	RotateEntity a\fr,20,0,-150,True
	a\fl=CreateCone(8,True,a\ent[0])
	EntityColor a\fl,255,0,255
	ScaleEntity a\fl,.3, 1, .3
	PositionEntity a\fl,EntityX(a\ent[0],True)+0.4,EntityY(a\ent[0],True)+1,EntityZ(a\ent[0],True)+0.6,True
	RotateEntity a\fl,20,0,150,True

	a\er=CreateSphere(8,a\ent[0])
	EntityColor a\er,0,127,255
	ScaleEntity a\er,.3, .3, .2
	EntityShininess a\er,1
	PositionEntity a\er,EntityX(a\ent[0],True)-0.5,EntityY(a\ent[0],True)+0.3,EntityZ(a\ent[0],True)+0.7,True
	a\eri=CreateSphere(8,a\ent[0])
	EntityColor a\eri,40,40,63
	ScaleEntity a\eri,.26, .26, .22
	EntityShininess a\eri,1
	PositionEntity a\eri,EntityX(a\ent[0],True)-0.52,EntityY(a\ent[0],True)+0.3,EntityZ(a\ent[0],True)+0.75,True
	a\el=CreateSphere(8,a\ent[0])
	EntityColor a\el,0,127,255
	EntityShininess a\el,1
	ScaleEntity a\el,.3, .3, .2
	PositionEntity a\el,EntityX(a\ent[0],True)+0.5,EntityY(a\ent[0],True)+0.3,EntityZ(a\ent[0],True)+0.7,True
	a\eli=CreateSphere(8,a\ent[0])
	EntityColor a\eli,40,40,63
	EntityShininess a\eli,1
	ScaleEntity a\eli,.26, .26, .22
	PositionEntity a\eli,EntityX(a\ent[0],True)+0.52,EntityY(a\ent[0],True)+0.3,EntityZ(a\ent[0],True)+0.75,True
	
	;body segs
	For i=1 To pedelength
		a\ent[i]=CreateSphere(4)
		EntityColor a\ent[i],i*10,255,i*3
		EntityShininess a\ent[i],1
		EntityType a\ent[i],c_insect	;add this line to prevent them going through cubes
		ScaleEntity a\ent[i],.8,.8,1.2
		a\between[i]=CreateCylinder(8)
		ScaleEntity a\between[i],.5,.5,.5
		RotateMesh a\between[i],90,0,0
		EntityColor a\between[i],255,i*3,i*3
	Next
	
Next

Collisions c_insect,c_level,2,2
Collisions c_insect,c_insect,1,3	;added to prevent them going through each other

;mainloop
While Not KeyHit(1)
	UpdateWorld
	freelook()
	If KeyHit(57) Stopp=1-Stopp
	If Stopp=0 updategame()
	RenderWorld
	Flip 
Wend
End

;update game
Function updategame()
	Local nx#,ny#,nz#
	For a.pede=Each pede
	
		;calculate angle and stick to wall
		TurnEntity a\ent[0],5,0,0
		nx#=0:ny#=0:nz#=0	
		coll=EntityCollided(a\ent[0],c_level)
		coll2=EntityCollided(a\ent[0],c_insect)	;added to prevent head hanging in a loop with no way out
		If coll Or coll2
			numcollisions = CountCollisions(a\ent[0])
			If numcollisions>0
				For i=1 To numcollisions
					nx=nx+CollisionNX(a\ent[0],i)
					ny=ny+CollisionNY(a\ent[0],i)
					nz=nz+CollisionNZ(a\ent[0],i)
				Next
				nx=nx/numcollisions
				ny=ny/numcollisions
				nz=nz/numcollisions
				AlignToVector a\ent[0],nx,ny,nz,2,.25
			EndIf ;numcollisions
		EndIf ;coll
		
		;the usual ai and stuff to do with speed and direction here
		If Rand(30)=1 TurnEntity a\ent[0],0,Rnd(-30,30),0
		MoveEntity a\ent[0],0,0,a\speed

		;update body segs
		For i=1 To pedelength	
			d#=EntityDistance(a\ent[i],a\ent[i-1])
			If d#>a\dist
				PointEntity a\ent[i],a\ent[i-1]
				MoveEntity a\ent[i],0,0,a\speed+d#-a\dist
				PositionEntity a\between[i],EntityX(a\ent[i],True),EntityY(a\ent[i],True),EntityZ(a\ent[i],True),True
				PointEntity a\between[i],a\ent[i-1]
				MoveEntity a\between[i],0,0,1.2
			Else
				MoveEntity a\ent[i],0,0,a\speed+d#-a\dist
				PositionEntity a\between[i],EntityX(a\ent[i],True),EntityY(a\ent[i],True),EntityZ(a\ent[i],True),True
				PointEntity a\between[i],a\ent[i-1]
				MoveEntity a\between[i],0,0,1.2
			EndIf
		Next

	Next
End Function

;camera freelook
Function freelook()
	mxspd#=MouseXSpeed()*0.25
	myspd#=MouseYSpeed()*0.25
	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
	campitch=campitch+myspd
	If campitch<-89 Then campitch=-89
	If campitch>89 Then campitch=89
	RotateEntity camera,campitch,EntityYaw(camera)-mxspd,0
	If KeyDown(203) Then mvx=mvx-.3
	If KeyDown(205) Then mvx=mvx+.3
	If KeyDown(200) Then mvz=mvz+.3
	If KeyDown(208) Then mvz=mvz-.3
	If KeyDown(30) Then mvx=mvx-.3
	If KeyDown(32) Then mvx=mvx+.3
	If KeyDown(17) Then mvz=mvz+.3
	If KeyDown(31) Then mvz=mvz-.3
	mvx#=mvx*.8
	mvy#=mvy*.8
	mvz#=mvz*.8
	MoveEntity camera,mvx,mvy,mvz
End Function

;create a test level
Function CreateLeveL()
	mesh=CreateMesh()
	
	box=CreateCube()
	FlipMesh box
	ScaleMesh box,40,23,32
	PositionMesh box,0,23,0
	AddMesh box,mesh
	
	box=CreateCube()
	ScaleMesh box,10,3,10
	PositionMesh box,22,3,-3
	AddMesh box,mesh

	box=CreateCube()
	ScaleMesh box,8,7,10
	PositionMesh box,-34,7,-22
	AddMesh box,mesh

	box=CreateCylinder(18)
	ScaleMesh box,8,6,13
	PositionMesh box,30,40,-10
	AddMesh box,mesh

	box=CreateCube()
	ScaleMesh box,16,6,4
	PositionMesh box,-12,40,4
	AddMesh box,mesh

	Return mesh
End Function

Updated 2006-05-18 00:10 MESZ

Boiled Sweets
(Posted 21 years ago)
A can feel a screen saver coming on :-)

Cygnus
(Posted 21 years ago)
Oh Noes!

Rob Cummings
(Posted 21 years ago)
Glad you like it lads!

IKG
(Posted 21 years ago)
Is this part the actual "crawl on wall" code:

		;calculate angle and stick to wall
		TurnEntity a\ent[0],5,0,0
		nx#=0:ny#=0:nz#=0	
		coll=EntityCollided(a\ent[0],c_level)
		If coll
			numcollisions = CountCollisions(a\ent[0])
			If numcollisions>0
				For i=1 To numcollisions
					nx=nx+CollisionNX(a\ent[0],i)
					ny=ny+CollisionNY(a\ent[0],i)
					nz=nz+CollisionNZ(a\ent[0],i)
				Next
				nx=nx/numcollisions
				ny=ny/numcollisions
				nz=nz/numcollisions
				AlignToVector a\ent[0],nx,ny,nz,2,.25
			EndIf ;numcollisions
		EndIf ;coll


Looks like it. This will definently come in handy. Thanks so much Rob!

Code Archives Forum