;-------------------------------------------------------------------------------
;
; ;-------------------------------;
; ; Game On ;
; ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;
;
;,,,, ;-----------------------------------------------
; Introduction ;
;---- ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;
; You wanted to build games, right?
; Well you've come to the right place :)
;
; Here's an overview of
; what you will find here:
;
; Graphics: Graphics modes.
; Buffering: Flicker free graphics.
; Media: Images, sound and music.
; Input: Keyboard, mouse and joystick control.
; Timing: Timing is the key.
; Concepts: How games can be built.
;
; This part contains lots of sections.
; In fact, this program, as a whole,
; and even some sections
; can't be run at all.
;
; You will have to copy and paste
; each or some sections or parts
; of some sections to try it out.
;
; Although if you followed all
; previous parts you'll be able
; to understand a lot of it
; without even having to run it :)
;
;,,,, ;-----------------------------------------------
; Graphics ;
;---- ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;
; So you know about programming basics
; as well as some graphical commands
; like Color and Text.
;
; It's time for some real graphics.
;
; Most, if not all visual elements in Blitz
; rely on the current graphics mode.
;
; When you run a program in Blitz
; the graphics mode will be set
; for you, automatically,
; to a resolution of,
; for example, 400x300,
; depending on the videocard.
;
; Actually that's exactly
; what happened so far.
;
; When you run a program without
; setting the graphics mode
; a lot of strange things can happen
; such as colors not working
; or text not printing.
;
; Even though you can do a lot
; without setting the graphics mode,
; it's best to always set it
; before doing anything visual.
;
; You can set a graphics mode
; with the Graphics command.
Graphics 640 , 480 ; A resolution of 640x480 (width x height)
; A graphics mode is a bit like a graphics session.
; Although there can be only one session at a time.
; Each time you close or open a new graphics mode,
; all visual elements will get wiped.
; Much like redimensioning an array.
; Here's how to close a graphics session.
EndGraphics
; Actually, you don't even have to close
; the graphics mode because at the end
; of your program Blitz will do it for you.
End
; You can also easily change between
; graphics modes without using
; the EndGraphics command.
Graphics 800 , 600
Graphics 640 , 480
; Only specific graphics modes are available.
; This, again, depends on the videocard.
; Some cards have 10 different modes,
; and others have dozens.
;
; You can figure out which graphics modes
; are available to you by checking out,
; for example, the CountGfxModes command.
;
; I'll leave that part up to you
; to find out more about ;)
;
; Still, a very compatible graphics mode
; is 640x480 so I'll stick to that,
; as you can be very sure it will run
; on any videocard.
;
; The Graphics command has 2 more
; parameters which are optional.
;
; Graphics Width , Height , Depth , Mode
;
; Width and Height you are already know.
;
; Depth is the color depth, usually 16
; or 32 (bit), sometimes even 24.
; It is however recommended to let
; Blitz handle the color depth.
; So specifying a value of 0
; (or not using the parameter)
; will automatically detect
; a color depth.
;
; Mode specifies what state
; the game window should be in.
; Here are the available states:
;
; 0 - Automatic
;
; When running in debug mode
; (you know debug mode, right?)
; the game will be run windowed,
; e.g. in a window :)
;
; When not running in debug mode
; the game will run fullscreen.
;
; 1 - Fullscreen
;
; This will force the game
; to run in fullscreen mode.
;
; 2 - Windowed
;
; And this will force the game
; to run in a window.
;
; 3 - Scaled Window
;
; You can also force the game
; to run in a resizable window.
; So you can stretch the
; contents of the window.
Graphics 1000 , 100 , 0 , 3
; This will set a 1000x100 scalable window
; with autodetected colordepth.
;
; You can find out what the current
; graphics mode settings are using
; the GraphicsWidth, GraphicsHeight
; and GraphicsDepth functions.
;
; But you could also use constants
; or global variables for that :)
;
;,,,, ;-----------------------------------------------
; Buffering ;
;---- ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;
; Imagine a program with a rectangle
; scrolling from left to right.
;
;,,,, ,, , ,
Graphics 640 , 480
For PosX = 1 To 640
Rect PosX , 240 , 10 , 10 , False ; Draw a 10x10 rectangle.
Delay 5 ; Wait 5 milliseconds.
Cls
Next
End
;---- -- - -
;
; Two new commands, Rect and Delay.
; You can check them out (F1)
; to see how they work.
;
; Let's try a larger rectangle
; only this time, filled,
; with some text on it.
;
;,,,, ,, , ,
Graphics 640 , 480
For PosX = 1 To 640
Color 64 , 128 , 64
Rect PosX , 240 , 100 , 100 , True
Color 128 , 255 , 128
Text PosX , 240 , "FILLED"
Delay 5
Cls
Next
End
;---- -- - -
;
; Still looking okay,
; though it jerks a lot.
;
; Let's add the Text outline function
; from the previous part.
;
; And draw an outlined message
; 9 times inside the box.
;
;,,,, ,, , ,
Function TextOutLine ( Pos_X% , Pos_Y% , Message$ )
Local X%
Local Y%
Color 128 , 255 , 128 ; Altered.
For X = -1 To 1
For Y = -1 To 1
Text Pos_X + X , Pos_Y + Y , Message
Next
Next
Color 0 , 0 , 0
Text Pos_X , Pos_Y , Message
End Function
Graphics 640 , 480
For PosX = 1 To 640
Color 64 , 128 , 64
Rect PosX , 240 , 100 , 100 , True
For Y = 0 To 2
For X = 0 To 2
TextOutline PosX + X * 30 , 240 + Y * 40 , "OUT"
Next
Next
Delay 5
Cls
Next
End
;---- -- - -
;
; Maybe you can see that
; it's starting to flicker a bit.
;
; If not, we'll just increase
; the number of times we
; draw the outlined text.
;
;,,,, ,, , ,
Function TextOutLine ( Pos_X% , Pos_Y% , Message$ )
Local X%
Local Y%
Color 255 , 255 , 255
For X = -1 To 1
For Y = -1 To 1
Text Pos_X + X , Pos_Y + Y , Message
Next
Next
Color 0 , 0 , 0
Text Pos_X , Pos_Y , Message
End Function
Graphics 640 , 480
For PosX = 1 To 640
Color 128 , 128 , 128
Rect PosX , 240 , 100 , 100 , True
For Y = 0 To 9
TextOutline PosX , 240 + Y * 10 , String ( "@" , 13 )
Next
Delay 5
Cls
Next
End
;---- -- - -
;
; If you still can't see a flicker,
; I'm sorry, but your computer is too fast! :P
;
; So how do we get rid of this flickering?
; (And how do we make it more smooth?)
;
; There's a technique called double buffering
; where you draw to an invisible screen
; and swap it with the visible screen
; when you're done drawing.
;
; You can picture it like a piece of paper.
;
; Rear
; ,
; ,'
; |`-, |,'
; | `-, '--
; | `-,
; | |
; | |
; '-, |
; `-, |
; __, `-,|
; ,'|
; ,'
; '
; Front
;
; The idea is to always draw
; to the rear side of the paper.
;
; When you're done drawing you turn it around
; so the front becomes the back and vise versa.
;
; Then you clear the rear side
; and everything starts from the beginning again.
;
; The rear side of the paper is called
; the BackBuffer ().
;
; So no matter how you twist or turn the paper,
; the BackBuffer () will always be the rear.
BackBuffer ()
; The visible (front) side is called,
; you guessed it, the FrontBuffer ().
FrontBuffer ()
; You can swap the contents of the front
; and back buffer with the Flip command.
Flip
; After setting the graphics mode,
; the default drawing buffer is
; the front buffer.
;
; So everything you draw,
; and the things that we drew,
; will end up on the front buffer,
; e.g. instantly on screen.
;
; To change the current drawing buffer
; you can use the SetBuffer command.
SetBuffer BackBuffer ()
; As you can see BackBuffer () is actually
; a function returning a value.
; You could call this a buffer handle.
; And SetBuffer takes such handles
; as a parameter.
;
; The command above changes the
; drawing cursor to the back buffer,
; e.g. the rear side of the paper.
;
; So all things we draw now
; will not be visible at all
; until we turn the paper.
;
; Let's try this in a program.
;
;,,,, ,, , ,
; Set graphics mode.
Graphics 640 , 480
; Now drawing to the rear side of the paper.
SetBuffer BackBuffer ()
; Starting at top of screen.
PosY = 0
Repeat
; Orange color.
Color 255 , 128 , 0
; Draw a centered circle.
Oval 320 - 50 , PosY - 50 , 100 , 100 , False
; Turn the paper, swap front with rear.
Flip
; Clear rear side.
Cls
; Move circle downwards.
PosY = PosY + 2
; Until we reach the bottom.
Until PosY > 480
End
;---- -- - -
;
; It should be very smooth now.
; (and flickerfree :P)
;
; You may have noticed that
; the Delay command is gone.
; Actually the Flip command
; is now delaying the program
; for us, automatically.
;
; After flipping the screen,
; so after swapping the front with the rear,
; e.g. after turning the paper,
; the Flip command will wait
; for the monitor to refresh.
;
; This will produce very smooth results.
; E.g. smoother than, for example, using Delay
; without doing all kinds of tricky stuff.
;
; If your monitor refresh rate is very high,
; say, 85Hz, the circle will move down faster
; than when using a refresh rate of 60Hz.
;
; This can be fixed in various ways.
; But because this is actually a timing issue
; we'll stop by that topic first.
;
;,,,, ;-----------------------------------------------
; Media ;
;---- ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;
; No, not the press.
; Multimedia more like.
; Images, sounds and music!
;
; Do you have any image handy?
; I've included a crosshair image
; for you to try out.
; It should be in the same
; directory you're running
; the program from.
;
; Let's try it out.
;
;,,,, ,, , ,
Graphics 640 , 480
; Load the image.
Image = LoadImage ( "Crosshair.bmp" )
; Make sure it was loaded.
If Image <> 0
; Draw the image.
DrawImage Image , 0 , 0
Else
Print "Image not loaded."
End If
WaitKey
End
;---- -- - -
;
; You can use LoadImage to
; load an image into memory
; and store its handle in
; a variable of your choice
; to keep track of it.
;
; If an image was not loaded
; or something went wrong
; a value of 0 is returned.
;
; DrawImage can be used to
; draw the image to the screen
; at a location of your desire.
;
; If in any case you'd want to
; wipe an image from memory
; you can use the FreeImage command.
FreeImage Image
; These image handles are indeed
; very similar to pointers.
; Only pointers can't end up
; missing in action because
; you can use Blitz' native
; keywords to hunt them down.
;
; If you were to load an image
; and store its handle,
ImageHandle = LoadImage ( "MyImage.BMP" )
; and then forget its handle,
ImageHandle = 0
; you will never be able to
; retrieve the image.
; So it's gone forever,
; missing in action,
; still existing
; but hanging around
; somewhere in memory.
;
; The only way you'd be
; able to free it again
; is by using either the
; Graphics or EndGraphics command :P
;
; You can also create images manually,
; draw to them on the fly,
; and use them in your game.
;
; For this you can use
; the CreateImage command.
ImageHandle = CreateImage ( Width , Height )
; Maybe you'll remember
; that you can set the
; drawing buffer using
; the SetBuffer command.
;
; Well, an image can also
; be used as a buffer
; using the ImageBuffer command.
;
; Just like the front and back buffers.
;
; SetBuffer -> FrontBuffer ()
; -> BackBuffer ()
; -> ImageBuffer ( ImageHandle )
SetBuffer ImageBuffer ( ImageHandle )
; Now you can draw to the image
; as if it were the screen.
; Usually a little bit smaller
; than the screen though :P
;
;,,,, ,, , ,
Graphics 640 , 480
; Create an image.
ImageHandle = CreateImage ( 100 , 100 )
; Now drawing on the image.
SetBuffer ImageBuffer ( ImageHandle )
; Dark pink.
Color 224 , 32 , 104
; Drawing a filled circle.
Oval 0 , 0 , 100 , 100 , True
; Draw to screen.
SetBuffer FrontBuffer ()
DrawImage ImageHandle , 320 - 50 , 240 - 50
WaitKey
End
;---- -- - -
;
; There's a lot you can do
; with images but I'll leave
; most of it up to you to find out.
;
; For now, let's add some sound.
;
;,,,, ,, , ,
; Load the sound.
Sound = LoadSound ( "Where.wav" )
; If it was loaded succesfully.
If Sound <> 0
; Play the sound.
PlaySound Sound
Else
Print "Sound not loaded."
End If
WaitKey
End
;---- -- - -
;
; As with images,
; the LoadSound command
; returns a sound handle
; which you can then use to,
; for example, play the sound.
;
; You can even alter the default
; volume, pitch and panning.
;
; You can play sounds and music
; with various formats;
; WAV, MP3, OGG, MOD, S3M,
; IT and XM just to name a few.
;
; To free a sound again,
; as with images,
; you can call FreeSound.
FreeSound Sound
; There's a way to have
; more control over
; the sounds being played.
;
; Modern soundcards have
; 32 channels so you have
; 32 slots to play your sounds.
;
; When playing a sound,
PlaySound Sound
; it is actually returning a value.
Channel = PlaySound ( Sound )
; The value is the channel handle
; which you can use to fool around
; with the sound currently playing.
;
; You can actually change
; pitch, volume and panning
; while it is playing!
;
; When you want to stop playing
; the sound prematurely,
; you can use StopChannel.
StopChannel Channel
; Again, very similar to
; pointers and image handles.
;
; We'll put this into action.
;
;,,,, ,, , ,
; Load the sound.
Sound = LoadSound ( "Starglider.mp3" )
; If it was loaded succesfully.
If Sound <> 0
; Play the sound.
Channel = PlaySound ( Sound )
; Wait until done playing.
Repeat
Until Not ChannelPlaying ( Channel )
Else
Print "Sound not loaded."
WaitKey
End If
End
;---- -- - -
;
; Now you can no longer
; abort the program prematurely :P
;
; The program plays the sound
; until reaching the end
; of the sound.
;
; Now, I really hope you're
; not playing any large files :)
;
; There are a lot of commands
; I will not explain here
; so check them out
; and play around with them =)
;
; If you do not have
; a command reference
; in your copy of Blitz,
; there's an online version
; which you can find here:
http://www.blitzbasic.com/b3ddocs/command_list_2d_cat.php
; For example you can
; check out the commands for:
;
; Basic, Maths, String,
; Graphics, Text, Image and Sound.
;
; E.g. the things we just 'handled' :P
;
; There are more things
; that use handles as well,
; like banks, to store
; information in any way you want,
; or fonts, to change
; the way your text looks,
; or networking, to communicate
; with another computer
; on your local network,
; through a modem or
; via the internet.
;
;,,,, ;-----------------------------------------------
; Input ;
;---- ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;
; We displayed a crosshair on screen before
; but we weren't able to control it yet.
;
; Let's control it with the mouse.
; So wherever the mouse moves to,
; our crosshair will move to as well.
;
; We can use the MouseX () and MouseY ()
; functions to know the current pixel
; location of the mouse on screen.
MouseX ()
MouseY ()
; So we'll just do what we did the other time
; when drawing the crosshair.
; Only we'll add the location of the mouse.
;
; Oh, before you run it I have to tell you
; that you can exit the program
; by pressing the left mouse button.
;
;,,,, ,, , ,
Graphics 640 , 480
SetBuffer BackBuffer ()
Crosshair = LoadImage ( "Crosshair.bmp" )
Repeat
DrawImage Crosshair , MouseX () , MouseY ()
Flip
Cls
Until MouseHit ( 1 )
End
;---- -- - -
;
; If you're running this in Debug mode,
; and hopefully you are,
; you'll find that the Windows mouse cursor
; is actually overlapping our crosshair.
;
; Now if you ran the program in fullscreen
; you wouldn't see a mousecursor.
; A way to hide the mousecursor
; when it is over our game window
; is to call the HidePointer command.
HidePointer
; Logically there's ShowPointer
; to make it visible again.
;
; You saw we used MouseHit ( 1 )
; to detect a mouse button press.
;
; It returns True if you pressed it
; and False if you didn't.
;
; Now, the parameter doesn't
; indicate the number of times
; you can press it.
;
; Rather it means which button
; you have to press.
;
; 1 - Left mouse button
; 2 - Right mouse button
; 3 - Middle mouse button
MouseHit ( 2 )
; This would tell you
; if you pressed the
; right mouse button.
; (or the wrong :)
;
; There's also the MouseDown
; command to know if you're
; holding down the button.
;
; Similar to the MouseHit
; and MouseDown functions,
; there are the KeyHit
; and KeyDown functions
; which are, you guessed it,
; for the keyboard.
;
; The parameter you specify
; is the scancode a key has.
; There is a list of scancodes
; in your copy of Blitz
; in the command reference.
;
; If not..
Const Key1 = 2
Const Key2 = 3
Const Key3 = 4
Const Key4 = 5
Const Key5 = 6
Const Key6 = 7
Const Key7 = 8
Const Key8 = 9
Const Key9 = 10
Const Key0 = 11
Const KeyQ = 16
Const KeyW = 17
Const KeyE = 18
Const KeyR = 19
Const KeyT = 20
Const KeyY = 21
Const KeyU = 22
Const KeyI = 23
Const KeyO = 24
Const KeyP = 25
Const KeyA = 30
Const KeyS = 31
Const KeyD = 32
Const KeyF = 33
Const KeyG = 34
Const KeyH = 35
Const KeyJ = 36
Const KeyK = 37
Const KeyL = 38
Const KeyZ = 44
Const KeyX = 45
Const KeyC = 46
Const KeyV = 47
Const KeyB = 48
Const KeyN = 49
Const KeyM = 50
Const KeyPad7 = 71
Const KeyPad8 = 72
Const KeyPad9 = 73
Const KeyPad4 = 75
Const KeyPad5 = 76
Const KeyPad6 = 77
Const KeyPad1 = 79
Const KeyPad2 = 80
Const KeyPad3 = 81
Const KeyPad0 = 82
Const KeyF1 = 59
Const KeyF2 = 60
Const KeyF3 = 61
Const KeyF4 = 62
Const KeyF5 = 63
Const KeyF6 = 64
Const KeyF7 = 65
Const KeyF8 = 66
Const KeyF9 = 67
Const KeyF10 = 68
Const KeyF11 = 87
Const KeyF12 = 88
Const KeyLeftShift = 42
Const KeyRightShift = 54
Const KeyLeftAlt = 56
Const KeyRightAlt = 184
Const KeyLeftCtrl = 29
Const KeyRightCtrl = 157
Const KeyCapsLock = 58
Const KeyNumLock = 69
Const KeyScrollLock = 70
Const KeySpace = 57
Const KeyEnter = 28
Const KeyTab = 15
Const KeyBackSpace = 14
Const KeyInsert = 210
Const KeyDelete = 211
Const KeyHome = 199
Const KeyEnd = 207
Const KeyPageUp = 201
Const KeyPageDown = 209
Const KeyEscape = 1
Const KeyPause = 197
Const KeyLeftWin = 219
Const KeyRightWin = 220
Const KeyApps = 221
Const KeyBackQuote = 41
Const KeyMinus = 12
Const KeyEquals = 13
Const KeyLeftBracket = 26
Const KeyRightBracket = 27
Const KeyBackSlash = 43
Const KeySemiColon = 39
Const KeyQuote = 40
Const KeyComma = 51
Const KeyPeriod = 52
Const KeySlash = 53
Const KeyPadSlash = 181
Const KeyPadAsterisk = 55
Const KeyPadMinus = 74
Const KeyPadPlus = 78
Const KeyPadEnter = 156
Const KeyPadPeriod = 83
Const KeyArrowUp = 200
Const KeyArrowDown = 208
Const KeyArrowLeft = 203
Const KeyArrowRight = 205
; In fact, you could
; copy and paste this list
; in your program.
; (above or below)
;
; Then you won't have to
; remember which scancode
; belongs to which key.
;
; You could also paste this
; in a separate BB file.
; And use the Include command
; in your program to glue it
; to your current program
; when you hit Run.
Include "ScanCodes.BB"
; This is also how you can
; separate your program
; into multiple files.
;
; When you use the Include command,
; Blitz will actually think that all
; little BB files are one big program.
;
; Let's try out some keys in a program.
; I'll use the numbers for them
; instead of the name.
;
;,,,, ,, , ,
SetBuffer BackBuffer ()
Repeat
If KeyDown ( 200 ) Then
Text 0 , 0 , "Up"
Else If KeyDown ( 208 ) Then
Text 0 , 0 , "Down"
Else
Text 0 , 0 , "Nowhere"
End If
Flip
Cls
Until KeyHit ( 1 ) ; Esc
End
;---- -- - -
;
; We'll continue with a block
; that moves from left to right
; when you press the spacebar.
;
;,,,, ,, , ,
Graphics 640 , 480
SetBuffer BackBuffer ()
Block_PosX = 100 ; Position
Block_Dir = 10 ; Direction (and speed)
Repeat
If KeyDown ( 57 ) ; Space
; Move the block.
Block_PosX = Block_PosX + Block_Dir
; If crossing left or right boundary.
If Block_PosX < 100 Or Block_PosX > 540
; Reverse direction.
Block_Dir = -Block_Dir
End If
End If
; Display the block, but centered.
Rect Block_PosX - 50 , 240 - 50 , 100 , 100 , False
Flip
Cls
Until KeyHit ( 1 )
End
;---- -- - -
;
; Let's add some more control.
; For example being able to
; move it left and right manually.
;
;,,,, ,, , ,
Const KeyArrowLeft = 203
Const KeyArrowRight = 205
Const KeyEscape = 1
Graphics 640 , 480
SetBuffer BackBuffer ()
Block_PosX = 320 ; Position
Repeat
; If pressing left arrow.
If KeyDown ( KeyArrowLeft )
; Move block left.
Block_PosX = Block_PosX - 10
End If
; If pressing right arrow.
If KeyDown ( KeyArrowRight )
; Move block right.
Block_PosX = Block_PosX + 10
End If
; Display the block, but centered.
Rect Block_PosX - 50 , 240 - 50 , 100 , 100 , False
Flip
Cls
Until KeyHit ( KeyEscape )
End
;---- -- - -
;
; What if we wanted to stop the block
; at the screen boundaries?
;
; Let's put these boundaries
; in constants as well
; since the boundaries
; are indeed constant :)
;
;,,,, ,, , ,
Const KeyArrowLeft = 203
Const KeyArrowRight = 205
Const KeyEscape = 1
Const LeftBoundary = 50
Const RightBoundary = 590
Graphics 640 , 480
SetBuffer BackBuffer ()
Block_PosX = 320 ; Position
Repeat
; If pressing left arrow.
If KeyDown ( KeyArrowLeft )
; Move block left.
Block_PosX = Block_PosX - 10
End If
; If pressing right arrow.
If KeyDown ( KeyArrowRight )
; Move block right.
Block_PosX = Block_PosX + 10
End If
; If crossing left boundary.
If Block_PosX < LeftBoundary
; Make it stick to the boundary.
Block_PosX = LeftBoundary
End If
; If crossing right boundary.
If Block_PosX > RightBoundary
; Make it stick to the boundary.
Block_PosX = RightBoundary
End If
; Display the block, but centered.
Rect Block_PosX - 50 , 240 - 50 , 100 , 100 , False
Flip
Cls
Until KeyHit ( KeyEscape )
End
;---- -- - -
;
; You can see there's a lot in there
; we can put in constants as well
; as a lot of things actually do not change.
;
; But, why put them in constants anyway?
; Well, imagine a program where everything
; is based on a resolution of 640x480.
; Such as those boundaries we used before.
;
; If you're not using constants for this,
; you'd have to change each and every
; value in the program by hand.
;
; You can imagine how easy it is
; to alter some values if you
; have to change only one! :)
;
; So let's stick everything we can in constants
; without messing with the program too much.
;
;,,,, ,, , ,
Const ScreenWidth = 640
Const ScreenHeight = 480
Const KeyArrowLeft = 203
Const KeyArrowRight = 205
Const KeyEscape = 1
Const BlockSize = 100
Const BlockSpeed = 10
Const LeftBoundary = 0 + BlockSize/2
Const RightBoundary = ScreenWidth - BlockSize/2
Graphics ScreenWidth , ScreenHeight
SetBuffer BackBuffer ()
Block_PosX = ScreenWidth/2
Repeat
; Move block.
If KeyDown ( KeyArrowLeft ) Then Block_PosX = Block_PosX - BlockSpeed
If KeyDown ( KeyArrowRight ) Then Block_PosX = Block_PosX + BlockSpeed
; Limit block position.
If Block_PosX < LeftBoundary Then Block_PosX = LeftBoundary
If Block_PosX > RightBoundary Then Block_PosX = RightBoundary
; Display block.
PosX = Block_PosX - BlockSize/2
PosY = ScreenHeight/2 - BlockSize/2
Rect PosX , PosY , BlockSize , BlockSize , False
Flip
Cls
Until KeyHit ( KeyEscape )
End
;---- -- - -
;
; Yes, it has become more math intensive.
; But I think you'll agree that it's pretty easy
; to simply change the size of the block
; without having to change anything else
; and the program still doing what we want.
; E.g. blocking the block at the screen edges.
;
; Let's go back to our crosshair image
; and move it around using the arrow keys.
;
;,,,, ,, , ,
Const ScreenWidth = 640
Const ScreenHeight = 480
Const KeyArrowUp = 200
Const KeyArrowDown = 208
Const KeyArrowLeft = 203
Const KeyArrowRight = 205
Const KeyEscape = 1
Const Speed = 10
Graphics ScreenWidth , ScreenHeight
SetBuffer BackBuffer ()
Crosshair = LoadImage ( "Crosshair.bmp" )
PosX = ScreenWidth / 2
PosY = ScreenHeight / 2
Repeat
If KeyDown ( KeyArrowUp ) Then PosY = PosY - Speed
If KeyDown ( KeyArrowDown ) Then PosY = PosY + Speed
If KeyDown ( KeyArrowLeft ) Then PosX = PosX - Speed
If KeyDown ( KeyArrowRight ) Then PosX = PosX + Speed
DrawImage Crosshair , PosX , PosY
Flip
Cls
Until KeyHit ( KeyEscape )
End
;---- -- - -
;
; There are also joystick commands
; such as JoyXDir, JoyYDir and JoyDown.
;
; Make sure to check out the Input
; section of the command reference
; to see which other commands
; are available.
;
;,,,, ;-----------------------------------------------
; Timing ;
;---- ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;
; You remember the Delay command, right?
; Where you can halt the program
; for any number of milliseconds.
;
; You'll also remember the MilliSecs () function
; which will give you the number of
; milliseconds since Windows started.
;
; You can use the MilliSecs command
; in the same way as the Delay command.
Delay 1000
; This will halt the program for 1 second.
;
; MilliSecs () will count up
; to a value of 2,147,483,647
; (which takes 24.9 days).
;
; So you can look at the time like a stopwatch
; to see how long something takes.
Start = MilliSecs ()
; Do something.
Finish = MilliSecs ()
HowLong = Finish - Start
; Which can be interpreted as:
;
; Start Finish
; | -----> |
; v v
; , _,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,_ ,
; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
; | |
; |<----------------->|
; HowLong
;
; Where MilliSecs () is a constantly
; increasing value, hence the arrow.
;
; You can use this same principle for
; any or all of your timing routines.
;
; But why would we want to
; make it so complicated?
;
; Well, for example, to wait 1 second,
; and not halt the program totally,
; while we can do something else
; in the meantime.
;
;,,,, ,, , ,
HowLong = 1000
Start = MilliSecs ()
Finish = Start + HowLong
Repeat
; Do something else.
Until MilliSecs () >= Finish
End
;---- -- - -
;
; Ofcourse you can write this in various ways,
; but it's basically always the same;
; to see how long something takes.
;
; Below is another way of doing it.
; We'll put something on the screen
; to make it more interesting.
;
;,,,, ,, , ,
SetBuffer BackBuffer ()
HowLong = 1000
Start = MilliSecs ()
Finish = Start + HowLong
While MilliSecs () < Finish
Counter = Counter + 1
Text 0 , 0 , Finish - MilliSecs ()
Flip
Cls
Wend
End
;---- -- - -
;
; As you can see it's a counter
; counting down to zero.
; You know, like a bomb :P
;
; Okay now let's try moving something
; at exactly 1 pixel per millisecond.
; E.g. 1000 pixels per second.
;
; Some more code below
; to make a thing move around
; in 4 directions.
;
;,,,, ,, , ,
Graphics 640 , 480
Const MoveSize = 100
Const OvalSize = 50
Const Dir_Right = 0
Const Dir_Down = 1
Const Dir_Left = 2
Const Dir_Up = 3
SetBuffer BackBuffer ()
Repeat
; Check the current time.
Now = MilliSecs ()
; Number of pixels to move is
; number of milliseconds passed
; since last time.
Speed = Now - LastTime
; Remember what time it was.
LastTime = Now
; See if the thing
; crosses a boundary
; and change its direction
; and position if so.
Select Direction
Case Dir_Right
If Where >= MoveSize
Direction = Dir_Down
Where = 0
End If
Case Dir_Down
If Where >= MoveSize
Direction = Dir_Left
Where = MoveSize
End If
Case Dir_Left
If Where <= 0
Direction = Dir_Up
Where = MoveSize
End If
Case Dir_Up
If Where <= 0
Direction = Dir_Right
Where = 0
End If
End Select
; Update position of thing
; and decide on position on screen
; all depending on direction.
Select Direction
Case Dir_Right
Where = Where + Speed
PosX = Where
PosY = 0
Case Dir_Down
Where = Where + Speed
PosX = MoveSize
PosY = Where
Case Dir_Left
Where = Where - Speed
PosX = Where
PosY = MoveSize
Case Dir_Up
Where = Where - Speed
PosX = 0
PosY = Where
End Select
; Draw the thing (centered).
CenterX = PosX + OvalSize / 2
CenterY = PosY + OvalSize / 2
Color 128 , 32 , 0
Size = OvalSize * 4 / 4
Oval CenterX - Size/2 , CenterY - Size/2 , Size , Size
Color 255 , 0 , 0
Size = OvalSize * 3 / 4
Oval CenterX - Size/2 , CenterY - Size/2 , Size , Size
Color 255 , 128 , 0
Size = OvalSize * 2 / 4
Oval CenterX - Size/2 , CenterY - Size/2 , Size , Size
Color 255 , 255 , 0
Size = OvalSize * 1 / 4
Oval CenterX - Size/2 , CenterY - Size/2 , Size , Size
Flip
Cls
Until KeyHit ( 1 )
End
;---- -- - -
;
; Maybe a bit too much code
; for the moment :P
;
; We'll get back to our
; controllable crosshair program.
; The one with keyboard control.
;
; We want it to move slower
; by making it dependent
; on how long a second takes.
;
; Let's move it 1 pixel per 10 ms.
;
;,,,, ,, , ,
Const ScreenWidth = 640
Const ScreenHeight = 480
Const KeyArrowUp = 200
Const KeyArrowDown = 208
Const KeyArrowLeft = 203
Const KeyArrowRight = 205
Const KeyEscape = 1
Graphics ScreenWidth , ScreenHeight
SetBuffer BackBuffer ()
Crosshair = LoadImage ( "Crosshair.bmp" )
; Increase the precision
; to make it smoother
; and more accurate.
PosX# = ScreenWidth / 2
PosY# = ScreenHeight / 2
Repeat
Now = MilliSecs ()
Speed# = Now - LastTime ; Increased precision.
LastTime = Now
; Decrease speed tenfold.
Speed = Speed / 10
If KeyDown ( KeyArrowUp ) Then PosY = PosY - Speed
If KeyDown ( KeyArrowDown ) Then PosY = PosY + Speed
If KeyDown ( KeyArrowLeft ) Then PosX = PosX - Speed
If KeyDown ( KeyArrowRight ) Then PosX = PosX + Speed
DrawImage Crosshair , PosX , PosY
Flip
Cls
Until KeyHit ( KeyEscape )
End
;---- -- - -
;
; What about animation?
;
; We'll use the animated running guy
; which should be included with this tutorial.
;
; The image contains 4 unique frames of 32x32
; and we can use LoadAnimImage to load it.
Image = LoadAnimImage ( "Running.bmp" , 32 , 32 , 0 , 4 )
; We can animate the image
; by using a variable to keep track
; of the current frame.
;
; How fast the animation runs
; we can let depend on MilliSecs ().
; Let's begin with a delay of
; 100 milliseconds per frame.
;
; Remember how to do that?
Now = MilliSecs ()
If Now > LastTime + 100
LastTime = Now
; Do your thing.
End If
; Here's another way:
Now = MilliSecs ()
If Now - LastTime >= 100
LastTime = Now
; Do your thing.
End If
; You think you know a little bit
; what the program could look like?
;
;,,,, ,, , ,
Const ScreenSizeX = 640
Const ScreenSizeY = 480
Const AnimFile$ = "Running.bmp"
Const AnimSize = 32
Const AnimFrames = 4
Const AnimDelay = 100 ; Ms
Local Image
Local Frame
Local Now
Local LastTime
Graphics ScreenSizeX , ScreenSizeY
Image = LoadAnimImage ( AnimFile , AnimSize , AnimSize , 0 , AnimFrames )
LastTime = MilliSecs ()
SetBuffer BackBuffer ()
Repeat
; What's the time?
Now = MilliSecs ()
; Has enough time passed?
If Now - LastTime >= AnimDelay
; Remember the time.
LastTime = Now
; Increase the frame number.
Frame = Frame + 1
; Keep frame in range of [0..3].
; Yes, it starts from zero!
If Frame = 4 Then Frame = 0
End If
; Draw animated image from center of screen.
DrawImage Image , ScreenSizeX/2 , ScreenSizeY/2 , Frame
Flip
Cls
Until KeyHit ( 1 )
End
;---- -- - -
;
; Now we'll expand the program a bit
; by letting the character move
; from left to right in a loop
; at the bottom of the screen.
;
; We're gonna have to fiddle a bit
; with the movement speed
; e.g. to find the best
; running speed (in pixels)
; to match with the animation speed.
;
; Like, it doesn't look good
; if the character is doing warp 9
; while animating in slow-motion :P
;
;,,,, ,, , ,
Const ScreenSizeX = 640
Const ScreenSizeY = 480
Const AnimFile$ = "Running.bmp"
Const AnimSize = 32
Const AnimFrames = 4
Const AnimDelay = 100 ; Ms
Const MoveSpeed = 7 ; Pixels per AnimDelay (7 pixels every 100ms).
Local Image
Local Frame
Local Now
Local LastTime
Local PosX
Local PosY
Graphics ScreenSizeX , ScreenSizeY
Image = LoadAnimImage ( AnimFile , AnimSize , AnimSize , 0 , AnimFrames )
LastTime = MilliSecs ()
PosX = -AnimSize ; Just off-screen to the left.
PosY = ScreenSizeY - AnimSize ; Just above screen bottom.
SetBuffer BackBuffer ()
Repeat
; What's the time?
Now = MilliSecs ()
; Has enough time passed?
If Now > LastTime + AnimDelay
; Remember the time.
LastTime = Now
; Increase the frame number.
Frame = Frame + 1
; Keep frame in range of [0..3].
; Yes, it starts from zero!
If Frame = 4 Then Frame = 0
; Move the character.
PosX = PosX + MoveSpeed
; Place character back off-screen on the left
; when running off-screen on the right.
If PosX > ScreenSizeX
PosX = -AnimSize
End If
End If
; Draw animated image.
DrawImage Image , PosX , PosY , Frame
Flip
Cls
Until KeyHit ( 1 )
End
;---- -- - -
;
; Interesting? :)
;
; For some more related commands
; check out the Time section
; in the command reference.
;
; How to keep your gamespeed constant
; you will find further on in the tutorial.
;
;,,,, ;-----------------------------------------------
; Concepts ;
;---- ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;
; You can create your game
; in zillions of different ways.
;
; But sometimes you'll want
; to make the code look more understandable
; so you won't read back sometimes
; and wonder what sx-51 means :)
;
; Ofcourse adding comments
; like you have seen so far
; will help a lot too :)
;
; Now, the basic game structure
; usually consists of 4 main parts;
;
; - Def
; - Init
; - Play
; - Exit
;
; A definition section (Def)
; where you define everything
; from variables to objects.
;
; An initialization section
; where you setup the game.
;
; A play-the-game section
; where you.. play the game :)
;
; And a cleaning-up section
; to clean up everything.
;
; The definition section
; usually includes things like;
;
; - Const
; - Type
; - Global
; - Dim
;
; But you could also add
; functions in this section as well.
;
; The initialization section
; can contain commands like;
;
; - Graphics
; - LoadImage
; - LoadSound
;
; As well as preparing variables,
; objects and arrays for the game.
;
; In larger games you usually
; see a loading screen
; while media is being loaded.
;
; The play-the-game section
; can also be called
; the Main routine of your game.
;
; It can contain anything that
; you can fool around with.
; Ranging from operating menus
; to a complete 2D shooter.
; You can ofcourse divide these
; in their own separate sections as well.
;
; So, the Main routine would be the part
; where the player interacts with the game.
;
; In Blitz you can make the
; Exit section very tiny
; because Blitz will remove
; all traces of media, objects etc
; from memory for you.
;
; So you don't really have to
; clean-up everything yourself.
; That is why a lot of games
; usually only have 1 word
; in its Exit game routine: End :P
;
; However there are cases where
; Blitz will not clean up for you
; and cases where you will want
; to do it yourself anyway.
;
; To summarize,
; here's a possible
; basic game structure
; you can hold on to..
;
; Game
; |_ Definition
; | |_ Const
; | |_ Data
; | |_ Type
; | |_ Global
; | \_ Dim
; |_ Initialization
; | |_ Logic
; | | |_ Objects
; | | |_ Variables
; | | \_ Arrays
; | |_ Graphics
; | \_ Sound/Music
; |_ Play
; | |_ Local
; | \_ Loop
; \_ Exit
; \_ Delete
; \_ End
;
; There can also be a separate section
; for sub-routines (functions, gosubs),
; and a special section for Data,
; usually located at the bottom.
;
; In any way, remember that you
; basically can do anything you want.
; Below you will find some suggestions
; to keep things together, to make the code
; look more understandable in general
; but above all; for yourself.
;
; First, an example of a very small game.
;
;,,,, ,, , ,
;-------------------------------;
; Mini Game ;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;
;
; Layout:
; Def
; Init
; Main
; ( Sub )
; ( Data )
;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;--> Def
Const Screen (visual)
Const Game (logic)
Type Struct
Global Vars
Dim Arrays
;--> Init
Graphics Screen
SeedRnd MilliSecs ()
InitPlayer
InitEnemies
(Global) Vars =
LoadTileMap
;--> Main
Local
Repeat
UpdateInput ; Keyboard
UpdateStruct ; Objects
UpdateScreen ; Visual
Until GameExit
End
;--> Sub ( Can also be moved to after Def )
Function
;--> Data ( Can be moved to anywhere )
.Label
Data
;---- -- - -
;
; No real Exit section as the only
; clean-up command used it is: End :P
;
; So basically 5 sections.
;
; The definition section where all
; constants, objects, variables
; and arrays are defined.
;
; For example you could have
; screen dimensions (visual),
; animation speed (logic),
; what's inside a player object
; and an enemy object,
; global image handles,
; a global pointer to a player
; and an array with a tilemap.
;
; In the initialization section
; you'd setup the graphics mode,
; select a fresh random pattern,
; initialize the player object
; and the enemy objects,
; load the graphics
; and the tilemap.
;
; Then the Main routine
; where the game is played.
; But first setting some local
; variables like a counter
; to be used in the Main loop.
; Inside the Main loop
; looking for pressed keys,
; updating the objects
; like moving enemies
; and updating the screen
; with tiles, player
; and enemies.
;
; The sub-routines section
; could for example contain
; functions to manage the player.
; Like, initializing the player,
; checking for player input,
; moving the player,
; making the player die,
; and respawning the player.
;
; Let's continue with a game of
; similar size but using different code.
;
;,,,, ,, , ,
;-------------------------------;
; Small Game ;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;
;
; Layout:
; Def
; Init
; Main
; Sub
; Data
;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;--> Def
Const Screen (visual)
Const Game (logic)
Type Struct
Global Vars
Dim Arrays
;-- Init
InitVisual
InitLogic
InitStruct
InitVars
InitArrays
;-- Main
Repeat
Logic
Visual
Until GameExit
End
;-- Sub
Function Logic
UpdateInput
UpdateStruct
Function Visual
UpdateScreen
Function InitVisual
Graphics Screen
Function InitLogic
SeedRnd MilliSecs ()
Function InitStruct
InitPlayer
InitEnemies
Function InitVars
(Global) Vars =
Function InitArrays
LoadTileMap
;-- Data
.Label
Data
;---- -- - -
;
; The definition part is
; still completely the same.
;
; However the initialization
; part changed a bit.
; Each bit has been separated
; into clear categories
; and has been put into
; separate functions.
;
; Actually, the same thing
; happened in the Main routine.
; Any local variables would
; now have to be global,
; otherwise they won't be
; visible from inside
; those new functions.
;
; The Logic function controls
; all game logic, being input
; and objects in this case.
;
; And the Visual function simply
; draws the game on the
; background buffer.
;
; The sub-routines part is now
; the part that contains most code.
; In fact, all code where anything
; happens with anything at all :P
;
; You can order the functions
; in any way you like.
;
; Now, watch what happens
; when you further separate
; everything in functions.
;
;,,,, ,, , ,
;-------------------------------;
; Medium Game ;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;
;
; - Method 1
;
; Layout:
; Def
; |_ Const
; |_ Data
; |_ Type
; |_ Global
; \_ Dim
; Sub
; \_ Function
; Init
; Main
;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;== (Global) Def
;-- Constant Def
Const Screen (visual)
Const Game (logic)
;-- Data ( Can be considered part of Constant Def )
Data
;-- Type Def
Type Struct
;-- (Global) Var Def
Global Vars
Dim Arrays
;== Sub
Function Init
InitVisual
InitLogic
InitStruct
InitVars
InitArrays
Function InitVisual
Graphics Screen
Function InitLogic
SeedRnd MilliSecs ()
Function InitStruct
InitPlayer
InitEnemies
Function InitVars
(Global) Vars =
Function InitArrays
LoadTileMap
Function Main
Repeat
Logic
Visual
Until GameExit
Function Logic
UpdateInput
UpdateStruct
Function Visual
UpdateScreen
;== Init
Init
;== Main
Main
End
;---- -- - -
;
; As you can see, the code is now
; completely separated, code-wise.
;
; You could also separate all parts
; that are not directly related.
;
;,,,, ,, , ,
;-------------------------------;
; Medium Game ;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;
;
; - Method 2
;
; Layout:
; Visual
; Logic
; Tilemap
; Player
; Enemies
; Main
; \_ Sub
;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;== Visual
Const Screen (visual)
Global Vars
Function InitVisual
Graphics Screen
InitVisual
;== Logic
Const Game (logic)
Global Vars
Function InitLogic
SeedRnd MilliSecs ()
InitLogic
;== Tilemap
Const
Data
Global Vars
Dim Arrays
Function InitArrays
LoadTileMap
InitArrays
;== Player
Const
Type Struct
Global Vars
Function InitPlayer
InitPlayer
;== Enemies
Const
Type Struct
Global Vars
Function InitEnemies
InitEnemies
;== Main
Repeat
Logic
Visual
Until GameExit
End
;-- Sub
Function Logic
UpdateInput
UpdateStruct
Function Visual
UpdateScreen
;---- -- - -
;
; Pretty much the same as before,
; just separated differently.
;
; What if you wanted to spread your code
; over a number of different files?
;
; Maybe you'll remember the Include command
; which you can use to glue BB files together.
;
;,,,, ,, , ,
;-------------------------------;
; Medium-Large Game ;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;
;
; - Method 1
;
; Layout:
; Includes
; |_ Visual
; |_ Logic
; |_ Tilemap
; |_ Player
; \_ Enemies
; Game
; \_ Subs
; |_ Level 1
; |_ Level 2
; \_ ...
;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;== Includes
Include "Visual.BB"
;-> Visual.BB
Const Screen (visual)
Global Vars
Function InitVisual
Graphics Screen
Include "Logic.BB"
;-> Logic.BB
Const Game (logic)
Global Vars
Function InitLogic
SeedRnd MilliSecs ()
Include "Tiles.BB"
;-> Tiles.BB
Const
Data
Global Vars
Dim Arrays
Function InitArrays
LoadTileMap
Include "Player.BB"
;-> Player.BB
Const
Type Struct
Global Vars
Function InitPlayer
Include "Enemy.BB"
;-> Enemy.BB
Const
Type Struct
Global Vars
Function InitEnemies
;== Game
InitGame
RunGame
EndGame
;-- Sub level 1
Function InitGame
InitVisual
InitLogic
InitArrays
InitPlayer
InitEnemies
Function RunGame
Repeat
Logic
Visual
Until GameExit
Function EndGame
End
;-- Sub level 2
Function Logic
UpdateInput
UpdateStruct
Function Visual
UpdateScreen
;---- -- - -
;
; The Game section could be a file
; called Main.BB containing all
; parts that are first executed
; as well as calls to functions
; in the Include files.
;
; So all 'external' parts are now
; neatly separated from the code
; for the Main routine.
;
; You could also put all definition
; code in a single section/file.
;
;,,,, ,, , ,
;-------------------------------;
; Medium-Large Game ;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;
;
; - Method 2
;
; Layout:
; Construct
; |_ Definition
; |_ Visual
; |_ Logic
; |_ Tilemap
; |_ Player
; |_ Enemies
; \_ Game
;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;== Construct
Include "Definition.BB"
;-> Definition.BB
;-- Screen
Const Screen (visual)
Global Vars
;-- Logic
Const Game (logic)
Global Vars
;-- Tilemap
Const
Data
Global Vars
Dim Arrays
;-- Player
Const
Type Struct
Global Vars
;-- Enemies
Const
Type Struct
Global Vars
Include "Visual.BB"
;-> Visual.BB
Function InitVisual
Graphics Screen
Function Visual
UpdateScreen
Include "Logic.BB"
;-> Logic.BB
Function InitLogic
SeedRnd MilliSecs ()
Function Logic
UpdateInput
UpdateStruct
Include "Tiles.BB"
;-> Tiles.BB
Function InitArrays
LoadTileMap
Include "Player.BB"
;-> Player.BB
Function InitPlayer
Include "Enemy.BB"
;-> Enemy.BB
Function InitEnemies
;-> Game.BB
Function ExecGame
InitGame
RunGame
EndGame
Function InitGame
InitVisual
InitLogic
InitArrays
InitPlayer
InitEnemies
Function RunGame
Repeat
Logic
Visual
Until GameExit
Function EndGame
End
ExecGame
;---- -- - -
;
; You can also see that the code
; from the Main routine has been
; moved around a bit.
;
; Now in the Game.BB file only
; one function is called,
; followed by a chain-reaction.
;
; You'll also find the Logic
; and Visual parts to be moved
; to separate files.
;
; Following is an example of
; a rather large game
; where all, each and every part
; is completely separated.
;
; Where the basic construction
; contains only Logic and Visual.
;
; Ofcourse for programs this size
; you can make it anything at all
; ranging from a single program of GOTOs
; to programs running completely independently.
;
; I have not included the entire structure
; as it would be extremely large so
; I just went upto the point
; where I think you'll get the idea :P
;
;,,,, ,, , ,
;-------------------------------;
; Large Game ;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;
;
; Layout:
; Construct
; |_ Logic
; | |_ Player
; | | \_
; | |_ Enemies
; | | \_
; | \_ Tilemap
; | \_
; \_ Visual
; |_ Player
; | \_
; |_ Enemies
; | \_
; \_ Tilemap
; \_
;
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
;-> GameName.BB
Include "Code\Construct.BB"
;-> Code\Construct.BB
Include "Code\Logic.BB"
Include "Code\Visual.BB"
Const Application
..
Function Application_Init
..
Application_Run Application_Init ()
Application_Exit First Application_Structure
End
;-> Code\Logic.BB
Include "Code\Logic\Player.BB"
Include "Code\Logic\Enemies.BB"
Include "Code\Logic\Tilemap.BB"
Const Logic
..
Function Logic_Init
..
Logic_Init
;-> Code\Visual.BB
Include "Code\Visual\Player.BB"
Include "Code\Visual\Enemies.BB"
Include "Code\Visual\Tilemap.BB"
Const Visual
..
Function Visual_Init
..
Visual_Init
;-> Code\Logic\Player.BB
Include "Code\Logic\Player\Const.BB"
Function Player_InitLogic
..
..
..
..
..
;---- -- - -
;
; And you can go all the way.
; Almost as far as chopping it up
; into thousands of little sections.
;
; It just depends on what you want to create
; and how difficult you want to make it for yourself :o)
;
; So for a game like this I would personally
; definitely go for the Mini game structure :)
;
; Always try to shape the code as you see fit.
; You don't have to use the same technique every time.
;
; Also in the code above you'll see that
; there's a whole directory structure
; where both code and media
; are specifically organized.
;
; Here's another example of a more simple
; directory structure:
;
; [Game]
; |_ [Images]
; | |_ Player.BMP
; | \_ Enemy.BMP
; |_ [Sounds]
; | \_ Explosion.WAV
; \_ Main.BB
;
; There are also 2 more interesting
; sections in the commands reference
; being System and Debug.
;
; The Debug section contains the
; commands DebugLog and Stop to aid you
; in debugging your programs.
;
; Now, we talked about the timing issue
; when you run your program on other computers
; with different monitor refresh rates.
;
; There are various solutions to make your program
; run with exactly the same speed on every computer.
;
; One of the easiest solutions is using a Blitz timer.
; You may have noticed the CreateTimer command
; in the command reference under the Time section.
;
; If not, you can check it out in the Blitz help,
; as well as the related commands, such as WaitTimer.
;
;,,,, ,, , ,
Const GameSpeed = 30 ; Frames per second.
Timer = CreateTimer ( GameSpeed )
;---- -- - -
;
; Timer contains the timer handle
; which you can then use in your Main loop
; to synchronize the number of times
; your game is updated with GameSpeed,
; while the number of times the
; game is displayed on the screen
; actually stays the same.
;
;,,,, ,, , ,
; Main loop.
Repeat
; Calculate number of times
; we should update the game
; to stay synchronized with
; 30 frames per second.
UpdateCount = WaitTimer ( Timer )
; Update the game
; that number of times.
For UpdateNumber = 1 To UpdateCount
; Update the game logic
; e.g. objects, input etc.
Logic
Next
; Draw the game on screen.
Visual
; Display the game screen
; and synchronize with the
; monitor refresh rate.
Flip
; End game using Esc.
Until KeyHit ( 1 )
;---- -- - -
;
; So if you run this on a fast enough computer,
; the game logic will not be updated
; more than one time per screen update.
; E.g. only one logic update per run
; through the main loop, e.g. one frame.
; So the program runs as fast as possible.
;
; If you run it on a slower computer,
; the game logic will be executed
; more than one time per frame
; to keep up with the GameSpeed.
;
; This will however cause jerks in the movement
; of objects in the game, but the speed
; will still be the same on any computer.
;
; You can find a tutorial on a smoother solution
; of frame limiting (keeping the speed constant)
; on the BlitzCoder website, as well as numerous
; other enlighting articles and code snippets.
;
http://www.blitzcoder.com/articles.shtml
http://www.blitzcoder.com/code.shtml
;
;-------------------------------------------------------------------------------