Airlock Demo Object oriented state machine by Anonymous Coder29th Apr 2009 2:23
|
---|
Summary Airlock Demo is an example that utilizes object oriented programming techniques along with state machine dynamics to create autonomous behavior in game objects. In this case a airl Description The airlock demo generates a fully functional airlock object that is state machine based and can be replicated all over the game. Each airlock object will react independently of each other. Once spawned the only function that needs to be called is the PROCESS_AIRLOCK(I) function which will determine if the player is in range and then determine which state to place the airlock in. The code could be modified for any type of autonomous behaviour for any type of character. An elevator, a escalator, bullets, bombs, trapdoors, HALO style gun caddys. The possibilities are endless. Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com REM ********************************************************************************************** REM A I R - L O C K D O O R DEMO Version 1.00 REM REM This is a simple yet elegantly written airlock door demo. It uses the a user defined REM data type to define an air lock door object. The air lock door object incorporates a REM a simple state machine in which there are only four states; CLOSED, OPENING, OPEN, and REM CLOSING. The door is activated whenever the camera (First Person) get within the REM distance defined by AIRLOCK_ACTIVE_DISTANCE variable. To execute the state machine REM a single function call to PROCESS_AIRLOCK(airlock_index) will first test the distance to REM the character before any processing will occur. If the character is out of range, it REM will ensure the door is either in the CLOSED state or the CLOSING state. If the character REM is in range it will ensure that the door is in the OPEN state or OPENING state. REM I plan to use this same frame work for all my objects or cast members in my future game REM developement. Next I will tackle a HALO style weapons locker that will open and present weapons REM as the character passes. REM REM Written by: Christopher Williams REM Date: April 29,2009 12:54 AM REM Email: cobra6romeo@yahoo.com REM REM *********************************************************************************************** REM ------------------------------ ERRATA ---------------------------------------------------------- REM REM 1. THERE IS NO MEANS TO ROTATE THE AIRLOCK STRUCTURE I WILL WORK ON THIS NEXT AND ADD IT SOON REM 2. WHERES THE STAR TREK SWISH DOOR SOUND? REM ------------------------------------------------------------------------------------------------ REM AIRLOCK data type TYPE AIR_LOCK_TYPE X AS FLOAT :REM X LOCATION IN WORLD MAP Y AS FLOAT :REM Y LOCATION IN WORLD MAP Z AS FLOAT :REM Z LOCATION IN WORLD MAP N AS INTEGER :REM 1ST OBJECT NUMBER USED IN THIS ASSEMBLY STATE AS INTEGER :REM CURRENT STATE ; CLOSED, OPENING, OPEN, OR CLOSING ENDTYPE GOSUB INIT_VARIABLES GOSUB LOAD_TEXTURES GOSUB LOAD_OBJECTS GOSUB SETUP_CAMERA REM START MAIN LOOP DO REM STANDARD MOVE AROUND CODE IF UPKEY()=1 THEN MOVE CAMERA 5 IF DOWNKEY()=1 THEN MOVE CAMERA -5 IF LEFTKEY()=1 THEN TURN CAMERA LEFT 5 IF RIGHTKEY()=1 THEN TURN CAMERA RIGHT 5 REM PROCESS AIRLOCK OBJECTS FOR I = 1 TO 9 PROCESS_AIRLOCK(I) NEXT I SYNC LOOP REM CREATE AND INSTALL AIRLOCK OBJECTS LOAD_OBJECTS: OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,-800,200,0) OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,0,200,0) OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,800,200,0) OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,-800,200,800) OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,0,200,800) OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,800,200,800) OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,-800,200,-800) OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,0,200,-800) OBJECT_INDEX = MAKE_AIRLOCK(OBJECT_INDEX,AIRLOCK_INDEX,800,200,800) RETURN REM SETUP FIRST PERSON CAMERA SETUP_CAMERA: POSITION CAMERA 0,200,-500 POINT CAMERA 0,200,0 RETURN REM LOAD ALL TEXTURES, NOTE NOT ALL ARE USED LOAD_TEXTURES: LOAD IMAGE "TN1300.JPG",1 LOAD IMAGE "TN1298.JPG",2 LOAD IMAGE "TN1297.JPG",3 LOAD IMAGE "TN1296.JPG",4 LOAD IMAGE "TN1295.JPG",5 LOAD IMAGE "TN1294.JPG",6 LOAD IMAGE "TN748.JPG",7 LOAD IMAGE "TN747.JPG",8 LOAD IMAGE "TN592.JPG",9 LOAD IMAGE "TN194.JPG",10 LOAD IMAGE "TN046.JPG",11 LOAD IMAGE "METAL028.JPG",12 RETURN REM INITIALIZE GLOBAL VARIABLES INIT_VARIABLES: GLOBAL DIM AIRLOCK(100) AS AIR_LOCK_TYPE :REM DECLARE AN ARRAY OF AIRLOCKS GLOBAL AIRLOCK_INDEX = 1 :REM AIRLOCK POIINTER GLOBAL OBJECT_INDEX = 1 :REM OBJECT POINTER GLOBAL CLOSED = 0 :REM DEFINE STATES GLOBAL OPENING = 1 GLOBAL OPEN = 2 GLOBAL CLOSING = 3 GLOBAL AIRLOCK_ACTIVATE_DISTANCE = 400 :REM THIS IS THE ACTIVATION DISTANCE RETURN REM THIS FUNCTION IS CALLED IF THE AIRLOCK IS IN THE OPENING STATE REM IT WILL GRADUALLY OPEN THE AIRLOCK UNTILIT IS FULLY OPEN THEN IT REM WILL CHANGE THE AIRLOCK STATE TO OPEN FUNCTION OPEN_AIRLOCK(I) D1 = AIRLOCK(I).N+1 :REM GET OBJECT NUMBER OF DOOR 1 D2 = AIRLOCK(I).N+2 :REM GET OBJECT NUMBER OF DOOR 2 X = AIRLOCK(I).X :REM GET AIRLOCK X POSITION REM IF DOOR IS NOT FULLY OPEN KEEP GOING IF OBJECT POSITION X(D1)>(X-300) THEN MOVE OBJECT LEFT D1,5 REM IF DOOR 2 IS NOT FULLY OPEN KEEP GOING IF OBJECT POSITION X(D2)<(X+300) THEN MOVE OBJECT RIGHT D2,5 REM IF DOOR NUMBER 1 IS IN OPEN POSITION STOP SWITCH TO OPEN STATE IF OBJECT POSITION X(D1)=(X-300) AIRLOCK(I).STATE = OPEN TEXTURE OBJECT AIRLOCK(I).N+3,7 :REM CHANGE CONTROL PANEL TO SHOW OPEN DOOR SET OBJECT EMISSIVE AIRLOCK(I).N+3,RGB(255,255,255) TEXTURE OBJECT AIRLOCK(I).N+4,7 :REM CHANGE CONTROL PANEL TO SHOW OPEN DOOR SET OBJECT EMISSIVE AIRLOCK(I).N+4,RGB(255,255,255) ENDIF ENDFUNCTION REM THIS FUNCTION IS CALLED WHEN THE AIRLOCK IS IN THE CLOSING STATE REM IT WILL GRADUALLY CLOSE THE AIRLOCK UNTIL IT IS FULLY CLOSED REM AT WHICH IT WILL THEN SET THE AIRLOCK DOOR STATE TO CLOSED FUNCTION CLOSE_AIRLOCK(I) D1 = AIRLOCK(I).N+1 :REM GET OBJECT NUMBER OF DOOR 1 D2 = AIRLOCK(I).N+2 :REM GET OBJECT NUMBER OF DOOR 2 X = AIRLOCK(I).X :REM GET AIRLOCK X POSITION COORDINATE REM IF DOOR 1 IS NOT FULLY CLOSED KEEP GOING IF OBJECT POSITION X(D1)<(X-100) THEN MOVE OBJECT RIGHT D1,5 REM IF DOOR 2 IS NOT FULLY CLOSED KEEP GOING IF OBJECT POSITION X(D2)>(X+100) THEN MOVE OBJECT LEFT D2,5 REM IF DOOR 1 IS IN THE OPEN POSITION SWITCH STATES TO CLOSED IF OBJECT POSITION X(D1)=(X-100) AIRLOCK(I).STATE = CLOSED TEXTURE OBJECT AIRLOCK(I).N+3,8 :REM CHANGE CONTROL PANEL TO SHOW CLOSED SET OBJECT EMISSIVE AIRLOCK(I).N+3,RGB(255,255,255) TEXTURE OBJECT AIRLOCK(I).N+4,8 :REM CHANGE CONTROL PANEL TO SHOW CLOSED SET OBJECT EMISSIVE AIRLOCK(I).N+4,RGB(255,255,255) ENDIF ENDFUNCTION REM THIS IS THE STATE MACHINE. THIS IS CALLED TO PROCESS THE REM THE AIRLOCK STATE MACHINE AND DECIDE WHAT TO DO FUNCTION PROCESS_AIRLOCK(I) GD = GET_DISTANCE(AIRLOCK(I).N) :REM GET EUCLIDIEAN DISTANCE FROM CAMERA TO DOOR IF GD < AIRLOCK_ACTIVATE_DISTANCE :REM IS IT WITHIN ACTIVE RANGE IF AIRLOCK(I).STATE = CLOSED THEN AIRLOCK(I).STATE = OPENING :REM IF YES THEN SWITCH TO OPENING STATE ENDIF IF GD > AIRLOCK_ACTIVATE_DISTANCE :REM IS IT OUTSIDE OF ACTIVE RANGE IF AIRLOCK(I).STATE = OPEN THEN AIRLOCK(I).STATE = CLOSING :REM IF YES THEN SWITCH TO CLOSING STATE ENDIF IF AIRLOCK(I).STATE = OPENING :REM IF IN OPENING STATE CALL OPEN FUNCTION OPEN_AIRLOCK(I) ENDIF IF AIRLOCK(I).STATE = CLOSING :REM IF IN CLOSING STATE CALL CLOSING FUNCTION CLOSE_AIRLOCK(I) ENDIF ENDFUNCTION REM THIS FUNCTION RETURNS THE EUCLIDEAN DISTANCE BETWEEN THE CAMERA AND THE OBJECT FUNCTION GET_DISTANCE(N) CX = CAMERA POSITION X() CY = CAMERA POSITION Y() CZ = CAMERA POSITION Z() OX = OBJECT POSITION X(N) OY = OBJECT POSITION Y(N) OZ = OBJECT POSITION Z(N) DX = CX-OX DY = CY-OY DZ = CZ-OZ D = SQRT(DX*DX+DY*DY+DZ*DZ) ENDFUNCTION D REM THIS FUNCTION CREATES AN AIRLOCK OBJECT AT COORDINATES X,Y,Z REM N IS THE NEXT AVAILABLE OBJECT NUMBER REM I IS THE NEXT AVAILABLE AIRLOCK NUBER FUNCTION MAKE_AIRLOCK(N,I,X,Y,Z) AIRLOCK(I).X = X AIRLOCK(I).Y = Y AIRLOCK(I).Z = Z AIRLOCK(I).N = N AIRLOCK(I).STATE = 0 N = MAKE_DOOR(N,X,Y,Z) :REM DRAW DOOR OBJECT AIRLOCK_INDEX = AIRLOCK_INDEX + 1 :REM INCREMENT AIRLOCK_INDEX ENDFUNCTION N REM THIS FUNCTION GENERATES THE 3D OBJECTS AND TEXTURING TO CREATE THE AIRLOCK OBJECT REM N IS THE NEXT AVAILABLE OBJECT REM X,Y,Z ARE THE COORDINATES OF THE AIRLOCK FUNCTION MAKE_DOOR(N,X,Y,Z) MAKE_BOX(N,1,800,400,200,X,Y,Z,8,4) :REM CREATES THE MAIN AIRLOCK BULKHEAD MAKE_BOX(N+1,2,400,350,300,X,Y-25,Z,2,2) :REM CREATES A CUTOUT OF THE DOOR WAY PERFORM CSG DIFFERENCE N,N+1 :REM SUBTRACT OUT DOOR DELETE OBJECT N+1 :REM DELETE OUT COOKIE CUTTER MAKE_BOX(N+1,1,750,500,100,X,Y,Z,8,4) :REM CREATE A CUTOUT OF DOOR SLIDE WAYS PERFORM CSG DIFFERENCE N,N+1 :REM SUBTRACT OUT DOOR SLIDE WAYS DELETE OBJECT N+1 :REM DELETE OUT COOKIE CUTTER MAKE_BOX(N+1,4,200,400,100,X-100,Y,Z,2,4) :REM MAKE LEFT DOOR MAKE_BOX(N+2,4,200,400,100,X+100,Y,Z,2,4) :REM MAKE RIGHT DOOR MAKE_CUBE(N+3,100,8,X+300,Y,Z-60) :REM MAKE CONTROL PANEL SET OBJECT EMISSIVE N+3,RGB(255,255,255) :REM SET A BRIGHTER PANEL MAKE_CUBE(N+4,100,8,X-300,Y,Z+60) :REM MAKE CONTROL PANEL SET OBJECT EMISSIVE N+4,RGB(255,255,255) :REM SET A BRIGHTER PANEL N = N +5 :REM INCREMENT OBJECT INDEX ENDFUNCTION N REM THIS FUNCTION PRODUCES A TEXTURED BOX OBJECT WITH TEXTURE SCALING REM N - OBJECT NUMBER REM T - TEXTURE NUMBER REM W - WIDTH OF BOX REM H - HEIGHT OF BOX REM L - LENGTH OR DEPTH OF BOX REM X,Y,Z SPATIAL COORDINATES REM U,V TEXTURE SCALE FACTORS FUNCTION MAKE_BOX(N,T,W,H,L,X,Y,Z,U,V) MAKE OBJECT BOX N,W,H,L POSITION OBJECT N,X,Y,Z TEXTURE OBJECT N,T SCALE OBJECT TEXTURE N,U,V N = N + 1 ENDFUNCTION N REM THIS FUNCTION PRODUCES A TEXTURED CUBE OBJECT REM N - OBJECT NUMBER REM S - SIZE REM T - TEXTURE NUMBER REM X,Y,Z SPATIAL COORDINATES FUNCTION MAKE_CUBE(N,S,T,X,Y,Z) MAKE OBJECT CUBE N,S POSITION OBJECT N,X,Y,Z TEXTURE OBJECT N,T N=N+1 ENDFUNCTION N |