[bb] Simple Fog by Strider Centaur [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:43

Previous topic - Next topic

BlitzBot

Title : Simple Fog
Author : Strider Centaur
Posted : 1+ years ago

Description : This demo a test of fog Im using for my 3D FP MMO about living under the sea is to test the fog system.  Its really super simple.

-- Updated 11/22/2004 -----
1) Used Killwoods city gen stuff to put more stuff in the scene.

2) Added improved movement control to include all degrees of rotation.  Contoles are displayed at bottom of screen.

3) Now with collision support for sea floor and objects.


Code :
Code (blitzbasic) Select
; The Aquatic Demo, a demo to experiment with underwater effects.
;
; Would like to grow this into a mer based game, in this demo the goals are:
;
; 1) Creat a pleasing underwater experiance in sight, sound and movement
; 2) Support multiple player access to allow it to be shared
; 3) incorperate the 3D tile system based using a 2D tile system to layout the sea floor
; 4) for comparison, try alternate terrain builds using other tool.
; 5) experement heavily with strong lighting affects and LOD in relation to intensity and fog.
; 6) create models and animation sequances that match the movement to produce a smooth integrated feel.
; 7) Get pats on the back from my Blitz Pals.  Uhh, huh, thats it yea.  LOL
;
;

; A few things we never want to change
Const WALL_TYPE = 3
Const SEA_FLOOR_TYPE = 2
Const PLAYER_TYPE = 1
; Keeping it simple
; Where possible I will beg barrow and umm barrow as mutch from other peoples work ( with their permisions ) as possible
; I will also use the refinement process for development, that is, first get it all working, then make it look good and
; optimize as needed.


; Step 1  the Player type needed for the Network thingy
Type pdata
Field playerID ; The NetID of this player
Field name$ ; the Name of this player shown over head.
Field x# ; Now if Blitz supported Vectors this would be so much easier
Field y# ; these are movement variable not positional ones
Field z#
Field wx# ; world postion These on the otherhand, are postional variables
Field wy#
Field wz#
Field yaw# ; ya know this 3D world stuff is gona really take some experimenting to get these right
Field pitch#
Field roll#
Field speed# ; yea see, its like this, things underwater do not instantly start and stop like in most FPSs.
Field accell# ; so we need to know how fast things can speed up
Field decell# ; and slow down
Field mesh ; give you one guess what goes here, if you guess the mesh Entity handle, you'd be right.
Field pivot ; used for movemement
End Type

Type timer
Field timerID
Field tdelay
Field lasttime
Field mode ; 0 off, 1 + number of times to triger, -1 allways on.
Field triggered ; 1+ = number of times triggered, should be cleared to 0 when tested. max value will never exceed 32000
End Type
; So Im going to make some assumptions on screen size and modes here, I like windowed
; but if you one of those full screen types, go ahead, change it.
; Why globals, Well sure I can get this info from inside blitz, but to set the data this is how I like to do it.
; no constants this time, its nice to be able to define defaults that can be changed.  :)
Global viewwidth = 800
Global viewheight = 600
Global viewmode = 2
Global viewcolors = 32


;Never sure if this is needed or not, but I do it anyway
Global ppivot
Global pcammera
Global pfog1
Global pfog2
Global pfog3
Global pfogtex
Global plight1
Global plight2
Global surfacedownplane
Global surfaceupplane
Global seafloorplane
Global surfacedowntex
Global surfaceuptex
Global seafloortex


; and our dimmed arrays
Dim cube%(100,100)
Dim sphere%(100,100)


;Timers?  We don't need no stinking timers!  Well maybe just a few
;


Global fratetimer   ; this will hold the frame rate timer handel
Global frdelay = 1000/60 ; this is sort of 60FPS  adjust to taste

Global gamestatus ; used to track the return status codes from functions

; Main Loops should be very clean, no uneeded logic, no variables that are not predefined above
; easy and clean.
;============= MAIN GAME LOOP =================
gamestatus = Init_Game() ; make a non-stop timer for FPS and game controle
If gamestatus = 1 Then RuntimeError ("Could not INITIALIZE GRAPHICSMODE")
If gamestatus = 2 Then RuntimeError ("PDATA type does not exist, not created")

Init_World("demo") ; Load the game world sceen data, we make the basice in init_game, this loads
; models for details in terrain and sturctures.
fratetimer = Init_Timer( frdelay, -1 )
Init_Collisions()
While Not KeyHit(1)
If TimerCheck(fratetimer) Then
InputUpdate()
;NetHandler()
CollisionHandler()
MovementUpdate()
RenderUpdate()
;NetUpdate()
EndIf
;AIUpdate()
Wend

End

;=============  END MAIN GAME LOOP ============



; you will find Im function crazy, I think a game or any code should have a main section of almost purely function
; calls and the main game loop and thats it.

; Setup all the pre demo stuff and screen modes
Function Init_Game%()
AppTitle " The Merfolk Demo "
If Not GfxMode3DExists(viewwidth, viewheight, viewcolors) Then Return (1)
Graphics3D viewwidth, viewheight, viewcolors, viewmode
SetBuffer BackBuffer()

;creat the first pdata so we can load up the player info
p.pdata = New pdata
If p = Null Then Return (2)

; ok lets set up the player pivot parent and camera ( going FP here )
ppivot = CreatePivot ()
pcammera = CreateCamera(ppivot)
EntityType ppivot, PLAYER_TYPE
EntityRadius ppivot, 1.4

;light?  Yea the spot light its so handing to see things.
; but Blitz is do kind to give us a default one we simply need to change the color
; nice semi-dark blue for now
CameraFogMode pcammera,1
CameraFogColor pcammera, 0,0,100
CameraFogRange pcammera, 1,55 ; about 100 meters

; Now we all know that the cammera fog is not Volumetric so we will emmulate this with a few large boxes.
; how this works is they are centered on us, and we flip them so we can see the texture on them from the inside.
; we then set the alpha levels from low to high as they radiate out from us.  We use 10 such bozes with a .10 alpha
; each, the first box in placed right in front of the cammera, so everything is shaded 10% by that one, the others
; stretch out from there till 100% opacity is reached at max range.  We can increase viewing range by simple
; decreasing the alpha as needed.  Above water is would be reasonable to all layers to 0 opacity, or for those fogy
; surfuce days, the first 3 or so to 0 and the rest to propper levels for the fog desired.
;pfog1 = CreateCube(ppivot)
;pfog2 = CreateCube(ppivot)
;pfog3 = CreateCube(ppivot)
;pfog4 = CreateCube(ppivot)
;pfog5 = CreateCube(ppivot)
;pfog6 = CreateCube(ppivot)
;pfog7 = CreateCube(ppivot)
;pfog8 = CreateCube(ppivot)
;pfog9 = CreateCube(ppivot)
;pfog10 = CreateCube(ppivot)

pfog1 = CreateSphere(8,ppivot)
pfog2 = CreateSphere(8,ppivot)
pfog3 = CreateSphere(8,ppivot)
pfog4 = CreateSphere(8,ppivot)
pfog5 = CreateSphere(8,ppivot)
pfog6 = CreateSphere(8,ppivot)
pfog7 = CreateSphere(8,ppivot)
pfog8 = CreateSphere(8,ppivot)
pfog9 = CreateSphere(8,ppivot)
pfog10 = CreateSphere(8,ppivot)


FlipMesh pfog1
FlipMesh pfog2
FlipMesh pfog3
FlipMesh pfog4
FlipMesh pfog5
FlipMesh pfog6
FlipMesh pfog7
FlipMesh pfog8
FlipMesh pfog9
FlipMesh pfog10
pfogtex = LoadTexture ("texturesfog.bmp")
EntityTexture pfog1, pfogtex
EntityTexture pfog2, pfogtex
EntityTexture pfog3, pfogtex
EntityTexture pfog4, pfogtex
EntityTexture pfog5, pfogtex
EntityTexture pfog6, pfogtex
EntityTexture pfog7, pfogtex
EntityTexture pfog8, pfogtex
EntityTexture pfog9, pfogtex
EntityTexture pfog10, pfogtex

; since the alphas tend to add up we try to keep them change at each dispance the same
; finally reaching opaque at the tenth box
EntityAlpha pfog1,.10
EntityAlpha pfog2,.10
EntityAlpha pfog3,.10
EntityAlpha pfog4,.10
EntityAlpha pfog5,.10
EntityAlpha pfog6,.10
EntityAlpha pfog7,.10
EntityAlpha pfog8,.10
EntityAlpha pfog9,.10
EntityAlpha pfog10,.10

; scale the boxes to cover the range we need
ScaleEntity pfog1,15,1,1
ScaleEntity pfog2,15,5,5
ScaleEntity pfog3,15,10,10
ScaleEntity pfog4,15,15,15
ScaleEntity pfog5,20,20,20
ScaleEntity pfog6,25,25,25
ScaleEntity pfog7,30,30,30
ScaleEntity pfog8,35,35,35
ScaleEntity pfog9,45,45,45
ScaleEntity pfog10,55,55,55


; more light out there in front of us for that cool distant glow feel
; Thats right our water will be a magical happy glowing kind of place
; not very realistic but hey we are merfolk, we can do this kind of stuff.  :)
plight1 = CreateLight(2,ppivot)
LightColor plight1, 0,100,100
LightRange plight1, 150
PositionEntity plight1, 0,20,200

; and some more light, placed at point of view
plight2 = CreateLight(3,ppivot)
LightColor plight2, 0,50,50
LightRange plight2, 200.0

; Ok we need the Sea, well 3 planes, yea we will make a sky orb and use it when you get close to surface
; The top plane is the furface of the water as seen from above the water, hey we want to jump out of water too.
; this one is less transparant than the one from looking up.
surfacedownplane = CreatePlane()
PositionEntity surfacedownplane, 0,0.01, 0 ; minor adjustment over plane below it.
surfacedowntex = LoadTexture("textureswater.bmp")
EntityAlpha surfacedownplane,.75
EntityTexture surfacedownplane, surfacedowntex

; The next one down is the bottom a mostly transparant( hey isn't that translucent? ) plane that we can see the
; sky throuh.  Also know that Fog is turned off when we are less than 100 meters from the surface, well in reality
; the closer we get the further the max range of the fog raises so its still there, when we are very need the surface
; it will extend well beyond the skysphere and thus appear non-present.  Ahh, you ask what about if you look down while
; near the surface?  Well silly, since your location in the sphere is very near the upper side of it, the fog will
; still be blocking the extreams of the toward the hurizon and bellow the surface, Genius I know, but as a friend
; said, why not just use a 5 sided sky box centered on the character and placed above the water? To witch I said, "umm".
;surfaceupplane = CreatePlane()
;PositionEntity surfaceupplane, 0,0,0
;surfaceuptex = LoadTexture("texturewater.bmp")  ; in future will be using 2 sepereate texture for up/down
;EntityAlpha surfaceupplane, .30
;FlipMesh surfaceupplane
; of coarse we cant flip planes, what was I thinking, no big deal will simply make a surface mesh, that way I can
; animate it with waves and stuff anyway.  So there.

; Finally the sea floor, yea, its a big flat sea with a sandy texture, dont like it?  Me either so will be adding
; stuff down there real soon.
seafloorplane = CreatePlane()
PositionEntity seafloorplane, 0, -300, 0
seafloortex = LoadTexture("texturesseafloor.bmp")
EntityTexture seafloorplane, seafloortex
EntityType seafloorplane, SEA_FLOOR_TYPE

;initialize the skybox, using my friend idea, see also move_skybox
;init_skybox()

;Set the starting info
; sence we don't have spawn points in our wourld yet we get the good ole 0,250,0
pwx# = 0.0
pwy# = -299.0 ;we starting out at close to 300 meters down, hows that For working under preasure?  
pwz# = 0.0
pyaw# = 0.0


;pmesh = LoadAnimMesh("merperson1.3ds", ppivot);  Hey when I have a model I get to uncomment this.  :)


; position the player in starting location.
PositionEntity ppivot, pwx, pwy, pwz
;PositionEntity pcammera, pwx, pwy, pwz
;PositionEntity pfog1, pwx, pwy, pwz
;PositionEntity pfog2, pwx, pwy, pwz
;PositionEntity pfog3, pwx, pwy, pwz
;PositionEntity pfog4, pwx, pwy, pwz
;PositionEntity pfog5, pwx, pwy, pwz
;PositionEntity pfog6, pwx, pwy, pwz
;PositionEntity pfog7, pwx, pwy, pwz
;PositionEntity pfog8, pwx, pwy, pwz
;PositionEntity pfog9, pwx, pwy, pwz
;PositionEntity pfog10, pwx, pwy, pwz


Return (0) ; if not true our function was completed without a problem
End Function

;setup collisions
Function Init_Collisions()
Collisions PLAYER_TYPE, SEA_FLOOR_TYPE,2,3
Collisions PLAYER_TYPE, WALL_TYPE,2,3
End Function

; Handle collisions
Function CollisionHandler()

End Function

; get input from player
; Using 3D free flight controls for all 6 degrees of rotation.
Function InputUpdate()
p.pdata = First pdata
pyaw# = 0 ; lets make sure we only move if a key is down
ppitch# = 0;
poll# = 0;
pz# = 0;
py# = 0;
px# = 0;
; yaw ( Turn on Y Axis control)
If KeyDown( 30 ) Then
pyaw#=+1
EndIf
If KeyDown( 32 )  Then
pyaw#=-1
EndIf
; move backward
If KeyDown( 31 ) Then
pz#=-0.4
EndIf
; move forward
If KeyDown( 17 ) Then
  pz#=+0.4
EndIf
; strafe Left
If KeyDown( 16  ) Then
px# = -0.4
End If
;strafe right
If KeyDown( 18 ) Then
px# = +0.4
End If
;ascend ( move on Y axis )
If KeyDown( 57 ) Then
py# = +0.4
EndIf
;descend ( on Y axis )
If KeyDown( 45 ) Then
py# = -0.4
EndIf
; pitch control ( turn on X Axis control)
If KeyDown( 208 ) Then
ppitch# =+1
EndIf
If KeyDown( 200 ) Then
ppitch# = -1
End If
; roll control  ( Turn on Z axis control )
If KeyDown( 203 ) Then
poll# = +1
End If
If KeyDown( 205 ) Then
poll# = -1
End If

End Function


; Basicly set up BlitzPlay the totally awesome network lib for Blitz.  Woot BP rocks
; Mode is either Host 0 or client 1
; port is the port to listen/connect on
; players is the max number of players
; ServerIP is the IP address of the game server(host) defaults to localhost at 128.0.0.1
; return status codes 0 if all went ok.
Function Network_Init%( mode%, port, players%, ServerIP$ = "128.0.0.1" )


Return (0)
End Function

; update the network, basicly sends network data and recieves it from network
; while I use BlitzPlay for this, I use my own wrappers so the netcode
; stays independant of the game, incase I want to use something else later.
; returns 0 if all went as planed or errorcode otherwise.
Function NetUpdate%()

Return (0)
End Function

;The heart of the network portion of the demo/game
; This function handles all incomming messages and sorts/stores/posts the data to the right variables used
; by other functions like ChatUpdate, MovementUpdate and so forth.
Function NetHandler%()

Return (0)
End Function

; Called after input and NetHandler this function updates all movable objects in the world space
; basicly cycles through the pdata's and other similar types and adjust there postion to speed ratio
; based on the timer datas for each object. This will position all players in the game/demo
Function MovementUpdate()
For p.pdata = Each pdata
TurnEntity ppivot, ppitch#, pyaw#, poll#
MoveEntity ppivot, px#, py#, pz#
pwx# = EntityX(ppivot)
pwy# = EntityY(ppivot)
pwz# = EntityZ(ppivot)
Next
End Function

; This function calles all the updateworld and render functions, also handles the HUD information
Function RenderUpdate()
UpdateWorld
RenderWorld
Draw2DHUD()
Flip
End Function


;Create a new timer useing the Delay provided
; the mode is -1 non-stop, 1+ count down timer, 0 stopped( usually cause countdown has happened )
; use countdown for cases where you want effects to last for a specific time but dont need to keep
; updating the effect after that.  powerup durations for example durations for example.
; return the timer id from the timer type created
Function Init_Timer%(timeDelay%, mode ="-1")
utimer = 0
For t.timer = Each timer
If t <> Null Then
tiemid = t imerID
If timerid > utimer Then utimer = timerid   ; lets get the highest timer ID so far
End If
Next
utimer = utimer + 1; lets make this ID one greater than the highest ID so far and thus unique
t.timer = New timer
t imerID = utimer
t delay = timeDelay
tlasttime = MilliSecs ()
t riggered = 0

Return t imerID
End Function

;Checks the a given timer( by ID ) to see if it has triggered, clearmode 0 (default) will clear the timer if trigger and
; if so return the number of times it triggerd since last check. Setting the clearmode to none zero will
; simply return the timer triggered data and not clear it, regardless of if it triggered or not.
; the default is to clear the trigger data if triggered.
Function TimerCheck%(timerID%, clearmode = 0)
For t.timer = Each timer
If tiemrID% = t imerID Then
If t riggered Then
ttemp = t riggered
If clearmode = 0 Then t riggered = 0
tlasttime = MilliSecs()
Return (ttemp)
End If
End If
Next
Return (-101) ;Invalid trigerID
End Function

; loop through all timers and update there triggered stats
Function TimerUpdate()
For t.timer = Each timer
If tmode > -1 Then ; is it non-stop or other?
If tlasttime + t delay > MilliSecs() Then    ; did the time expire?
t riggered = t riggered + 1 ; yep, so increment triggered
tlasttime = MilliSecs() ; reset timer.
If tmode > 1 Then ; its a count down timer amd it hasnt counted down yet?
tmode = tmode -1 ; yep, so count down
If tmode < 0 Then tmode = 0   ; prevent it from any chance of crossing over into a non-stop timer
End If
End If
Else ; so its a non-stop timer
If tlasttime + t delay > MilliSecs() Then    ; did the time expire?
t riggered = t riggered + 1 ; yep, so increment triggered
tlasttime = MilliSecs() ; reset timer.
End If
End If
Next
End Function

; TimerResetMode lets you change the mode or count of a timer, so that for instance you can restart a stopped
; countdown timer.  It does no other testing, so if you should use TimerCheck before a reset if you are interested
; in the timer status before the reset.
Function TimerResetMode( id%, modecount% )
For t.timer = Each timer
If id = t imerID Then
tmode = modecount
Return
End If
Next
End Function

; Reset the delay setting of a timer, used for fine tuning a timer at run time, like when else silly?
; ID is the timer ID and tdelay is the delay for the timer.  It does no other timer opperation, see also TimerResetMode
Function TimerResetDelay( id% , tdelay% )
For t.timer = Each timer
If id = t imerID Then
t delay = tdelay
Return
EndIf
Next
End Function


; this handles the zone specific data for this area of the world, it loads all models and terrains
; repositions player to the propper zone entry point in relations to players present zone settings
; sets all lighting and rendering options and updates the network to let other players know that this
; player has left one zone and entered the one specified, including the new players starting location.
; of coarse in the Demo there is only one zone, but I figured what they heck, better to plan ahead.
; The data read comes from the zone file, named __zonename__.zon.  These files are located in the zones directory
; there format???? well to be done still.  But probably very INI in format.
Function Init_World( zone$ )
zonefile$ = "zones"+ zone$ +".zon"

; this is just a referance set of shapes set out there in the sea
; a bit of random city code by Killwood 04
For x = 0 To 30
For y = 0 To 49

 Read map
 
  If map = 1

   dice = Rand(0,1)

   Select dice

    Case 0
     cube(x,y) = CreateCube()
     PositionEntity cube(x,y),y * 10,-299,x * 10
     EntityType cube(x,y), WALL_TYPE
     Case 1
      sphere(x,y) = CreateSphere()
      PositionEntity sphere(x,y),y * 10,-299,x * 10
EntityType sphere(x,y), WALL_TYPE

    End Select
 
EndIf

Next
Next
End Function


; draws some debugging data to screen.  Will be using surfaces in 3D later, but for now this will do.
; called by RenderUpdate
Function draw2DHUD()
linenum = 0
For p.pdata = Each pdata
linenum = linenume+1
Text 10,2+(FontHeight()*linenum),"Player: "+p
ame+" at location: x:"+pwx# +" y:"+pwy# +"z:"+pwz#
Next
Text 10, GraphicsHeight()-((FontHeight()+2)*3), "W/S Move Forward / Back, A/D Turn Left / Right, Q/E Strafe Left/Right"
Text 10, GraphicsHeight()-((FontHeight()+1)*2),"Arrow UP/DOWN Pitch Up/Down, Arrow Left/Right Roll Left/Right"
Text 10, GraphicsHeight()-((FontHeight()-1)), "Space Bar/X ascend/descend"
End Function



.map


Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0


Comments :


killwood(Posted 1+ years ago)

 Very Good! Where could I get all the media? Thanks!-Killwood


_PJ_(Posted 1+ years ago)

 Please cpould you provide code just for the fog effect? So we dont need to worry about excess media etc?


Trader3564(Posted 1+ years ago)

 i like it as it is, its better to cut in code than to complete it because someone did not provide the media. After all most of us want to see first before work.