Code archives/3D Graphics - Mesh/Doors 101 - Simple multiple door system

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

Download source code

Doors 101 - Simple multiple door system by D4NM4N
(Posted 20 years ago)
Very simple "Multi-Door" system for beginners with speedup and slam.

It works by using a simple 4 state 'latch' with a single trigger.

Helpful for learning the following techniques:
Functions, types and simple triggers, latches.

It can be modified easily to incorporate SFX(see comments) and you can change the behavior to slide etc.

Note: if using render tweening (if you dont know what this is then you probably aren't) you will need to adjust the speed appropriately.

CODE:
Graphics3D 640,480
SetBuffer BackBuffer()

light=CreateLight(2)
MoveEntity light,-5,5,-5


;make a camera 
cam=CreateCamera()
MoveEntity cam,4,2,-5


;create cutom type add what you like to the fields like "key numbers" etc
Type doormesh
  Field door,activate,doorstate,speed#
End Type

;Create 2 doors, ideally this needs to be 'functionized' as it would be less messy and 
could eliminate the need for d1, d2 etc.
;for example: function CreateDoor.doormesh(px,py,pz,rx,ry,rz,sz,sy,sz)

;create first door object
d1.doormesh= New doormesh
d1\activate=0
d1\doorstate=0
d1\door=CreateCube()
PositionMesh d1\door,1,0,0
ScaleEntity d1\door,1,2,.1
EntityColor d1\door,255,0,0

;create a second door object
d2.doormesh= New doormesh
d2\activate=0
d2\doorstate=0
d2\door=CopyEntity (d1\door)
MoveEntity d2\door,-2,0,0
EntityColor d1\door,0,255,0


;point camera at door just so we can see whats going on
PointEntity cam,d1\door



;main loop
Repeat

	If KeyHit(2) D1\ACTIVATE=1
	If KeyHit(3) D2\ACTIVATE=1

	
	;do world updates
	UpdateAllDoors()

        ;Render 3d to backbuffer
	RenderWorld
	
	;display instructions on bbuffer
	Text 0,0,"Press '1' or '2' To open/close doors"

        ;flip the visible screen
	Flip


Until KeyHit(1)




;------------------------End of main code--------------------------------------------




Function UpdateAllDoors()  ;gets called every loop
For d.doormesh=Each doormesh
   Select d\doorstate
      Case 0 ;if standing shut
        If d\activate         ;this is your initial trigger
           d\activate=0       ;reset trigger
           d\doorstate=2        ;door is shut so set open trigger to beginon Next loop
          ;playsound (CREAK)
       EndIf

     Case 1  ; if standing open
       If d\activate
          d\activate=0
          d\doorstate=3
          ;playsound (CREAK)
       EndIf

     Case 2  ;if opening door
      If EntityYaw(d\door)<90 d\speed=d\speed+0.02 Else d\doorstate=1
	  If EntityYaw(d\door)>90 d\speed=0.00: RotateEntity d\door,0,90,0
	

     Case 3 ;if closing door
      If EntityYaw(d\door)>0 d\speed=d\speed-0.02 Else d\doorstate=0
	  If EntityYaw(d\door)<0 
	     d\speed=0.00: 
	     RotateEntity d\door,0,0,0:
	     ;playsound (SLAM)
	  endif

   End Select

   TurnEntity d\door,0,d\speed,0
	
Next
End Function

Comments

Blitzplotter
(Posted 19 years ago)
Cool...

D4NM4N
(Posted 19 years ago)
Thx :)

-----------------Update------------------------
You can modify it to use camerapick to open them with a small mod:
Where pickedmesh is the picked entity handle:

MOUSECLICK CODE:
;NOTE! for this to work you need to set:
;entitypickmode d\door,2
;when creating the door!!!

;replace the lines:
;	If KeyHit(2) D1\ACTIVATE=1
;	If KeyHit(3) D2\ACTIVATE=1
;with the following:
pickedmesh=camerapick(cam,mousex(),mousey())
Updatedoors(pickedmesh)


;then add this to door func to functions area (or for the more advanced, incorporate it into upddatealldoors!):
Function updatedoors(pickedmesh)
For d.doormesh=Each doormesh
   if pickedmesh=d\door ;was door clicked on?
       if entitydistance (hero,d\door) < 50 ;so you gotta be close
           ;you could always but another condition in here for if player has d\key (for example) ;)
           d\activate=1
           exit
       endif 
   endif 
next
end function

job done!

nrasool
(Posted 19 years ago)
Hey Dan, this is for the latter mod, the mouseclick mod, there is a mistake, eg camerapick should include the camera :-)

However I can't get the camerapick to work, here is your code in full, so you can copy and paste it:

Graphics3D 640,480
SetBuffer BackBuffer()

light=CreateLight(2)
MoveEntity light,-5,5,-5


;make a camera 
cam=CreateCamera()
MoveEntity cam,4,2,-5


;create cutom type add what you like to the fields like "key numbers" etc
Type doormesh
  Field door,activate,doorstate,speed#
End Type

;Create 2 doors, ideally this needs to be 'functionized' as it would be less messy and 
;could eliminate the need For d1, d2 etc.
;for example: function CreateDoor.doormesh(px,py,pz,rx,ry,rz,sz,sy,sz)

;create first door object
d1.doormesh= New doormesh
d1\activate=0
d1\doorstate=0
d1\door=CreateCube()
PositionMesh d1\door,1,0,0
ScaleEntity d1\door,1,2,.1
EntityColor d1\door,255,0,0
EntityPickMode d1\door,2


;create a second door object
d2.doormesh= New doormesh
d2\activate=0
d2\doorstate=0
d2\door=CopyEntity (d1\door)
MoveEntity d2\door,-2,0,0
EntityColor d2\door,0,255,0
EntityPickMode d2\door,2



;point camera at door just so we can see whats going on
PointEntity cam,d1\door



;main loop
Repeat

	pickedmesh=CameraPick(cam,MouseX(),MouseY())
	;do world updates
	UpdateAllDoors()

        ;Render 3d to backbuffer
	RenderWorld
	
        ;flip the visible screen
	Flip


Until KeyHit(1)




;------------------------End of main code--------------------------------------------




Function UpdateAllDoors()  ;gets called every loop
For d.doormesh=Each doormesh


		If pickedmesh=d\door ;was door clicked on?
    	;   If EntityDistance (hero,d\door) < 50 ;so you gotta be close
        	   ;you could always but another condition in here for if player has d\key (for example) ;)
           	d\activate=1
           Exit
     ;  EndIf 
   EndIf 


   Select d\doorstate
      Case 0 ;if standing shut
        If d\activate         ;this is your initial trigger
           d\activate=0       ;reset trigger
           d\doorstate=2        ;door is shut so set open trigger to beginon Next loop
          ;playsound (CREAK)
       EndIf

     Case 1  ; if standing open
       If d\activate
          d\activate=0
          d\doorstate=3
          ;playsound (CREAK)
       EndIf

     Case 2  ;if opening door
      If EntityYaw(d\door)<90 d\speed=d\speed+0.02 Else d\doorstate=1
	  If EntityYaw(d\door)>90 d\speed=0.00: RotateEntity d\door,0,90,0
	

     Case 3 ;if closing door
      If EntityYaw(d\door)>0 d\speed=d\speed-0.02 Else d\doorstate=0
	  If EntityYaw(d\door)<0 
	     d\speed=0.00: 
	     RotateEntity d\door,0,0,0:
	     ;playsound (SLAM)
	  EndIf

   End Select

   TurnEntity d\door,0,d\speed,0
	
Next
End Function


D4NM4N
(Posted 19 years ago)
ok thanks nadeem ill look into it :)

at first glance without trying it i think you missed out the parameter:

Function UpdateAllDoors(pickedmesh)

Argh i wish b3D had stricts!

I wrote the update above out of my head and forgot to test it sorry :(

nrasool
(Posted 19 years ago)
Ahh nice one Dan, yes you are right, the functions needs arguments, however now only one door opens if you using mousehit

Here is the updated code:

Graphics3D 640,480
SetBuffer BackBuffer()

light=CreateLight(2)
MoveEntity light,-5,5,-5


;make a camera 
cam=CreateCamera()
MoveEntity cam,4,2,-5


;create cutom type add what you like to the fields like "key numbers" etc
Type doormesh
  Field door,activate,doorstate,speed#
End Type

;Create 2 doors, ideally this needs to be 'functionized' as it would be less messy and 
;could eliminate the need For d1, d2 etc.
;for example: function CreateDoor.doormesh(px,py,pz,rx,ry,rz,sz,sy,sz)

;create first door object
d1.doormesh= New doormesh
d1\activate=0
d1\doorstate=0
d1\door=CreateCube()
PositionMesh d1\door,1,0,0
ScaleEntity d1\door,1,2,.1
EntityColor d1\door,255,0,0
EntityPickMode d1\door,2


;create a second door object
d2.doormesh= New doormesh
d2\activate=0
d2\doorstate=0
d2\door=CopyEntity (d1\door)
MoveEntity d2\door,-2,0,0
EntityColor d2\door,0,255,0
EntityPickMode d2\door,2



;point camera at door just so we can see whats going on
PointEntity cam,d1\door



;main loop
Repeat

	pickedmesh=CameraPick(cam,MouseX(),MouseY())
	;do world updates
	UpdateAllDoors(pickedmesh)

        ;Render 3d to backbuffer
	RenderWorld
	
        ;flip the visible screen
	Flip


Until KeyHit(1)




;------------------------End of main code--------------------------------------------




Function UpdateAllDoors(pickedmesh)  ;gets called every loop

For d.doormesh=Each doormesh

If MouseHit(1)
		If pickedmesh=d\door ;was door clicked on?
		
    	;   If EntityDistance (hero,d\door) < 50 ;so you gotta be close
        	   ;you could always but another condition in here for if player has d\key (for example) ;)
           	d\activate=1
           Exit
     ;  EndIf 
	EndIf
EndIf
	


   Select d\doorstate
      Case 0 ;if standing shut
        If d\activate         ;this is your initial trigger
           d\activate=0       ;reset trigger
           d\doorstate=2        ;door is shut so set open trigger to beginon Next loop
          ;playsound (CREAK)
       EndIf

     Case 1  ; if standing open
       If d\activate
          d\activate=0
          d\doorstate=3
          ;playsound (CREAK)
       EndIf

     Case 2  ;if opening door
      If EntityYaw(d\door)<90 d\speed=d\speed+0.02 Else d\doorstate=1
	  If EntityYaw(d\door)>90 d\speed=0.00: RotateEntity d\door,0,90,0
	

     Case 3 ;if closing door
      If EntityYaw(d\door)>0 d\speed=d\speed-0.02 Else d\doorstate=0
	  If EntityYaw(d\door)<0 
	     d\speed=0.00: 
	     RotateEntity d\door,0,0,0:
	     ;playsound (SLAM)
	  EndIf

   End Select

   TurnEntity d\door,0,d\speed,0
	
Next

End Function


If you are using IDEal IDE, that has strict built in :-)

Rodjoe
(Posted 18 years ago)
The code of nrasool doesn't work ,only one door(red) open when I click

Code Archives Forum