Code archives/3D Graphics - Misc/slidingdoor + trigger + animation (movement)
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
This shows how to create a slidingdoor and update its state and animation (movement) depending on if a character is on the trigger or not | |||||
Graphics3D(1000,625,32,2) SeedRnd(MilliSecs()) ;PREMADE MESHES TEXTURES ANIMATIONS SOUNDS FONTS Global XCharacter_Body = CreateCube() ScaleMesh(XCharacter_Body,0.5/2,1.75/2,0.25/2) PositionMesh(XCharacter_Body,0,1.75/2,0) HideEntity(XCharacter_Body) Global XCharacter_Collidable = CreateCylinder(16) ScaleMesh(XCharacter_Collidable,0.5/2,1.75/2,0.5/2) PositionMesh(XCharacter_Collidable,0,1.75/2,0) HideEntity(XCharacter_Collidable) Global XSlidingDoor_Wall = CreateMesh() TPart = CreateCube() ScaleMesh(TPart,1.0/2,3.0/2,0.01/2) PositionMesh(TPart,-1.0/2,3.0/2,0) AddMesh(TPart,XSlidingDoor_Wall) FreeEntity(TPart) TPart = CreateCube() ScaleMesh(TPart,1.0/2,3.0/2,0.01/2) PositionMesh(TPart,1.0/2+1.0,3.0/2,0) AddMesh(TPart,XSlidingDoor_Wall) FreeEntity(TPart) TPart = CreateCube() ScaleMesh(TPart,1.0/2,1.0/2,0.01/2) PositionMesh(TPart,1.0/2,1.0/2+2.0,0) AddMesh(TPart,XSlidingDoor_Wall) FreeEntity(TPart) EntityColor(XSlidingDoor_Wall,200,200,200) HideEntity(XSlidingDoor_Wall) Global XSlidingDoor_Door = CreateMesh() TPart = CreateCube() ScaleMesh(TPart,1.0/2,2.0/2,0.01/2) PositionMesh(TPart,1.0/2,2.0/2.0,0) AddMesh(TPart,XSlidingDoor_Door) FreeEntity(TPart) EntityColor(XSlidingDoor_Door,150,150,150) HideEntity(XSlidingDoor_Door) Global XSlidingDoor_Trigger = CreateMesh() TPart = CreateCube() ScaleMesh(TPart,1.0/2,0.1/2,2.0/2) PositionMesh(TPart,1.0/2,0.1/2,0) AddMesh(TPart,XSlidingDoor_Trigger) FreeEntity(TPart) EntityColor(XSlidingDoor_Trigger,255,255,000) HideEntity(XSlidingDoor_Trigger) Origine = CreateCube() ScaleMesh(Origine,0.01/2,0.01/2,0.01/2) EntityColor(Origine,255,000,255) EntityFX(Origine,1) Global Camera = CreateCamera() CameraRange(Camera,0.1,100) CameraClsColor(Camera,000,000,000) SLight = CreateLight(1) LightColor(SLight,224,224,224) PositionEntity(SLight,50,1000,-1000,True) RotateEntity(SLight,45,0,0,True) AmbientLight(064,064,064) Global TempsCount% Dim TempI%(100) Global Ground BuildGround() Global SlidingDoorsCount% Dim SlidingDoor_Root(100) Dim SlidingDoor_Wall(100) Dim SlidingDoor_Door(100) Dim SlidingDoor_Trigger(100) Dim SlidingDoor_State%(100) ;IsOpening, IsOpened, IsClosing, IsClosed Const CIsOpening% = 1 Const CIsOpen% = 2 Const CIsClosing% = 3 Const CIsClose% = 4 BuildSlidingDoors() Global CharactersCount% Dim Character_Root(10) Dim Character_Eyes(10) Dim Character_Body(10) Dim Character_Collidable(10) Dim Character_State%(10) BuildCharacters() Global PlayerI% = 1 ;Rand(1,10) Global D2DMsTime% Global MIMsTime% Main() End() Function Main() Repeat If( KeyHit(57)=1 ) PlayerI% = Rand(1,10) EndIf UpdatePlayer() UpdateAI() UpdateSlidingDoors() I% = PlayerI PositionRotateEntityLikeOtherEntity(Camera,Character_Eyes(I)) TurnEntity(Camera,22.5,0,0) MoveEntity(Camera,0,0,-3) Wireframe(False) If( KeyDown(2)=1 ) Wireframe(True) EndIf SetBuffer(BackBuffer()) RenderWorld() CText("D2DMsTime = "+Str(D2DMsTime),0,0) CText("MIMsTime = "+Str(MIMsTime),0,15) Flip(1) Until( KeyDown(1)=1 ) End Function Function CText(TextStr$,PX%,PY%) Text(PX,PY,TextStr,False,False) End Function Function PositionEntityLikeOtherEntity(Entity,OEntity) PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True) End Function Function RotateEntityLikeOtherEntity(Entity,OEntity) RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True) End Function Function PositionRotateEntityLikeOtherEntity(Entity,OEntity) PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True) RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True) End Function Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#) VX# = PBX - PAX VZ# = PBZ - PAZ Distance2D# = Sqr((VX*VX)+(VZ*VZ)) Return Distance2D End Function Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#) VX# = PBX - PAX VY# = PBY - PAY VZ# = PBZ - PAZ Distance3D# = Sqr((VX*VX)+(VY*VY)+(VZ*VZ)) Return Distance3D End Function Function Diag#(SideLength#) Diag# = Sqr( (SideLength * SideLength) + (SideLength * SideLength) ) Return Diag End Function Function BuildGround() Ground = CreateMesh() Surface = CreateSurface(Ground) AddVertex( Surface, 0.0, 0.0, 100.0 ) AddVertex( Surface, 100.0, 0.0, 100.0 ) AddVertex( Surface, 0.0, 0.0, 0.0 ) AddVertex( Surface, 100.0, 0.0, 0.0 ) AddTriangle( Surface, 0, 1, 2 ) AddTriangle( Surface, 2, 1, 3 ) EntityColor(Ground,128,128,128) End Function Function BuildSlidingDoors() TRoot = CreatePivot() LoopState = True Repeat ChooseSlidingDoorPositionTries% = 0 .LineChooseSlidingDoorPosition ChooseSlidingDoorPositionTries = ChooseSlidingDoorPositionTries + 1 ;choose the position of the temporary slidingdoor TX# = Rand(0+1.5,100.0-1.5) ;TY# = 0 TZ# = Rand(0+1.5,100.0-1.5) ;.LineChooseSlidingDoorOrientation ;choose the orientation of a temporary slidingdoor ;TPitch# = 0 TYaw# = Rnd(-180,180.0) ;TRoll# = 0 ;check if there is enough empty space to create the temporary slidingdoor PositionEntity(TRoot,TX,0,TZ,True) IsThereEnoughEmptySpaceState% = True For OI% = 1 To SlidingDoorsCount Step 1 D# = Distance2D(TX,TZ,EntityX(SlidingDoor_Root(OI),True),EntityZ(SlidingDoor_Root(OI),True)) If( D >= 2+2+1.0 ) ; Else IsThereEnoughEmptySpaceState = False Exit EndIf Next ;if yes If( IsThereEnoughEmptySpaceState = True ) ;create the slidingdoor at this position with this orientation SlidingDoorsCount = SlidingDoorsCount + 1 I% = SlidingDoorsCount SlidingDoor_Root(I) = CreatePivot() SlidingDoor_Wall(I) = CopyEntity(XSlidingDoor_Wall) EntityParent(SlidingDoor_Wall(I),SlidingDoor_Root(I),True) SlidingDoor_Door(I) = CopyEntity(XSlidingDoor_Door) MoveEntity(SlidingDoor_Door(I),0,0,-0.005-0.001) EntityParent(SlidingDoor_Door(I),SlidingDoor_Root(I),True) SlidingDoor_Trigger(I) = CopyEntity(XSlidingDoor_Trigger) EntityParent(SlidingDoor_Trigger(I),SlidingDoor_Root(I),True) EntityAlpha(SlidingDoor_Trigger(I),0.25) SlidingDoor_State(I) = CIsClose PositionEntity(SlidingDoor_Root(I),TX,0,TZ,True) RotateEntity(SlidingDoor_Root(I),0,TYaw,0,True) ;else if no Else If( IsThereEnoughEmptySpaceState = False ) ;if triescount inferior or equal to 100 If( ChooseSlidingDoorPositionTries <= 100 ) ;try to choose another position Goto LineChooseSlidingDoorPosition ;else if triescount superior to 100 Else If( ChooseSlidingDoorPositionTries > 100 ) ;exit LoopState = False EndIf EndIf Until( SlidingDoorsCount% = 100 Or LoopState = False ) FreeEntity(TRoot) End Function Function BuildCharacters() For n% = 1 To 10 Step 1 CharactersCount = CharactersCount + 1 I% = CharactersCount Character_Root(I) = CreatePivot() Character_Eyes(I) = CreatePivot() PositionEntity(Character_Eyes(I),0,1.65,0,True) EntityParent(Character_Eyes(I),Character_Root(I),True) Character_Body(I) = CopyEntity(XCharacter_Body) EntityColor(Character_Body(I),Rand(025,255),Rand(025,255),Rand(025,255)) EntityParent(Character_Body(I),Character_Root(I),True) Character_Collidable(I) = CopyEntity(XCharacter_Collidable) EntityColor(Character_Collidable(I),255,255,255) EntityAlpha(Character_Collidable(I),0.5) EntityParent(Character_Collidable(I),Character_Root(I),True) PositionEntity(Character_Root(I),Rnd(0+0.25,100.0-0.25),0,Rnd(0+0.25,100.0-0.25),True) RotateEntity(Character_Root(I),0,0,0,True) Next End Function Function UpdatePlayer() I% = PlayerI If( KeyDown(30)=1 ) TurnEntity(Character_Root(I),0,3,0) Else If( KeyDown(32)=1 ) TurnEntity(Character_Root(I),0,-3,0) EndIf If( KeyDown(17)=1 ) MoveEntity(Character_Root(I),0,0,0.05) Else If( KeyDown(31)=1 ) MoveEntity(Character_Root(I),0,0,-0.05) EndIf End Function Function UpdateAI() For I% = 1 To CharactersCount Step 1 If( I <> PlayerI ) EndIf Next End Function Function UpdateSlidingDoors() For I% = 1 To SlidingDoorsCount Step 1 ;check if some characters are near enough to be considered TriggerState% = False D2DMsStart% = MilliSecs() TempsCount = 0 For OI% = 1 To CharactersCount Step 1 D# = Distance2D(EntityX(SlidingDoor_Root(I),True),EntityZ(SlidingDoor_Root(I),True),EntityX(Character_Root(OI),True),EntityZ(Character_Root(OI),True)) If( D <= Diag(1.0) + 0.25 + 1.0 ) TempsCount = TempsCount + 1 TI% = TempsCount TempI(TI) = OI EndIf Next D2DMsTime% = MilliSecs() - D2DMsStart ;if yes MIMsStart% = MilliSecs() If( TempsCount > 0 ) ;check if one of the considered characters (near enough) intersects with the trigger For TI% = 1 To TempsCount Step 1 OI% = TempI(TI) ;if yes If( MeshesIntersect(Character_Collidable(OI),SlidingDoor_Trigger(I))=True ) TriggerState = True Exit EndIf Next EndIf MIMsTime% = MilliSecs() - MIMsStart ;depending on slidingdoor state, turnmove the slidingdoor If( SlidingDoor_State(I) = CIsOpening ) If( TriggerState = False ) SlidingDoor_State(I) = CIsOpening Else If( TriggerState = True ) SlidingDoor_State(I) = CIsOpening EndIf D# = Distance2D(EntityX(SlidingDoor_Door(I),True),EntityZ(SlidingDoor_Door(I),True),EntityX(SlidingDoor_Root(I),True),EntityZ(SlidingDoor_Root(I),True)) If( D < 0.9 ) MoveEntity(SlidingDoor_Door(I),-0.01,0,0) Else If( D >= 0.9 ) SlidingDoor_State(I) = CIsOpen EndIf Else If( SlidingDoor_State(I) = CIsOpen ) If( TriggerState = False ) SlidingDoor_State(I) = CIsClosing Else If( TriggerState = True ) SlidingDoor_State(I) = CIsOpen EndIf Else If( SlidingDoor_State(I) = CIsClosing ) If( TriggerState = False ) SlidingDoor_State(I) = CIsClosing Else If( TriggerState = True ) SlidingDoor_State(I) = CIsOpening EndIf D# = Distance2D(EntityX(SlidingDoor_Door(I),True),EntityZ(SlidingDoor_Door(I),True),EntityX(SlidingDoor_Root(I),True),EntityZ(SlidingDoor_Root(I),True)) If( D < 0.01 ) SlidingDoor_State(I) = CIsClose Else If( D >= 0.01 ) MoveEntity(SlidingDoor_Door(I),0.01,0,0) EndIf Else If( SlidingDoor_State(I) = CIsClose ) If( TriggerState = False ) SlidingDoor_State(I) = CIsClose Else If( TriggerState = True ) SlidingDoor_State(I) = CIsOpening EndIf EndIf Next End Function |
Comments
| ||
Really nice stuff, while maybe too complex for triggering doors ... but nice stuff anyway ps : Diagonal of a square is just the side*Sqr(2) Function Diag#(SideLength#) Return SideLength * Sqr_2 End Function |
| ||
I think what Bobysait means is that since Sqr(2) is constant, you can replace it with the literal: Const SQUARE_ROOT_2# = 1.414213562373095 Function diag#( sideLength# ) Return sideLength * SQUARE_ROOT_2 End Function EDIT: That value was taken from a NASA page that calculated it up to 1 mil. digits. I guess it's an infinite number like Pi. |
| ||
My point exactly :) I was just too lazzy to write the value ^_^ |
| ||
Nice one RemiD |
| ||
This is great work RemiD, thanks for sharing. |
Code Archives Forum