You are on page 1of 48

1

DarkBASIC Notes: on DarkBASIC Pro Game Programming, 2nd Edition


Chapter 1
1. First 3D program (10)
2. Did 2D program (11)
3. Did Pong program (11)
4. animated spider (23)
5. rotating earth (24)
Fun entering and seeing the programs run. All worked well and were fun.
Chapter 2 Programming Basics Variables, Data Types, and Scope
(33) Importance of the game loop
(39) Definition of a variable
(40) Algorithm step by step solution of a problem
REMSTART REMEND for multi line comments
END command that ends a program
(49)
number = 3828549
decimal#=3.14159
person$ = "Ray Schneider" //note suffixes of variable identifiers.
DATA TYPES listed on page 53.
DOUBLE INTEGER 64 bits
FLOAT, DOUBLE FLOAT 32 bits and 64 bits
GLOBAL prefix word that declares Scope
function endfunction delimits a function which has variables of local scope (56)
Chapter 3 (59)
String Declaration: ex. movie AS STRING
Initialization: phrase AS STRING = "One ring to rule them all."
Assignment copies one string to another. (61)
WAIT KEY general instruction to have the program pause until a key is pressed.
String Conversion Command:
ASC( ) (converts a character to its ASCII code)
ex. AsciiValue AS BYTE
AsciiValue = ASC("A")
Print AsciiValue, " is the ascii value of A"
CHR$( ) converts a BYTE to its character equivalent
LEN( ) returns the length of a string, ex. LEN("this is a string")
MID$(<string>,<number>) prints the nth character in the string starting with 1.
RIGHT$(string, number) prints right most n characters
LEFT$(string,number) prints left most n character
VAL( string ) converts a string to a floating point number

2
STR$(number) converts a numeric variable to a string
PRINT list prints stuff on screen in current cursor position
TEXT ScrX, ScrY, string prints stuff on screen at X,Y
CENTER TEXT ScrX, ScrY, string sets a string.
SET CURSOR ScrX, ScrY the x and y coordinates must be integers
Font commands only work with the TEXT or CENTER TEXT commands.
Use SET TEXT FONT to change the font.
SET TEXT FONT "font name"
SET TEXT SIZE point_size typically 10, 12, 14, 16, or 18
To discover the current font you can use TEXT FONT$( )
ex. FontName as string
FontName = TEXT FONT$( )
You can also get the font size
ex. FontSize = TEXT SIZE( ) returns text size as an integer
TEXT WIDTH(string) returns text width in pixels.
TEXT HEIGHT(string) returns text height in pixels
Style Commands: NORMAL ITALIC BOLD BOLDITALIC
SET TEXT TO <style>
TEXT STYLE returns a value 0 .. 3 for the above styles.
Text TRANSPARENCY
SET TEXT OPAQUE sets text background to current color specified in INK command
SET TEXT TRANSPARENT sets background to well background
TEXT BACKGROUND TYPE returns the background type of the current font 0 for
opaque and 1 for transparent. ex. Background Value = TEXT BACKGROUND TYPE( )
UDTs are User Defined Types like structs, ex.
TYPE Person
FirstName as string
LastName as string
Age as integer
ENDTYPE then you can declare Person's as padawan as Person. Internal variable are
accessed with DOT notation as padawan.FirstName = "Obi-Wan" etc.
NESTED UDTs UDTs can have elements that are other UDTs.
Chapter 4 Program Logic (77)
IF THEN
IF <cond> THEN <statement> Note: Compound versions don't use the THEN
IF <cond> {statements} ENDIF
IF .. ELSE ENDIF

FUNCTIONS (84)

3
FUNCTION FunctionName([parameters])
<statements>
ENDFUNCTION [ReturnValue]
Note: parameter list is like ex. x as integer, y as integer, message as string, etc. default if
no type is given is integer.
RND(N) Random Number function 0 .. N-1
Chapter 5 Looping Statements, Data Sequences, and Arrays
4 kinds of loops: FOR NEXT, DO LOOP, REPEAT UNTIL, WHILE
ENDWHILE. Note: EXIT command will exit loops, like C/C++ break command.
FOR NEXT (104)
FOR variable = Starting_Value TO Ending_Value
<statements>
NEXT variable
STEP OPTION: FOR x = start TO finish STEP 2 would step by 2 also negative steps
step backwards ex. FOR i = 10 TO 1 STEP -1
DO LOOP (105)
DO
<statements>
LOOP the do loop is an infinite loop so you need to explicitly break out of it using the
EXIT command. So do a test inside the loop that produces an EXIT from the loop.
REPEAT UNTIL (107)
REPEAT
<statements>
UNTIL <true condition>
WHILE <true condition>
<statements>
ENDWHILE
DATA SEQUENCE (112)
ex. DATA <comma delimited list of data elements>
DATA "Jones", "Bob", 34
DATA "Anderson", "Julie", 19
READ <var list>
ex.
FOR n = 1 to 4
READ LastName$, FirstName$, Age

4
NEXT n
RESTORE moves the internal data sequence position to the beginning of the DATA
sequence.can also RESTORE [data label] (115)
See Examples pg.116
HEROS: ' label to allow RESTORE heros to go to head of data sequence
DATA 4 ' used to indicate number of records
DATA "Warrior", 15, 12, 10 ' actual data records
DATA "Archer", 8, 8, 15
DATA "Valkyrie", 14,13, 12
DATA "Wizard", 4, 3, 8
ARRAYS (118)
DIM VariableName(number of elements) AS DataType
Note: DarkBASIC actually allocates an extra elements so you can index the array from 0
or 1.
ARRAYS OF USER DEFINED TYPES (123)
ex.
TYPE POINT
X AS INTEGER
Y AS INTEGER
ENDTYPE
' Declare an Array of Points
DIM points(10) AS POINT
USE DOT NOTATION TO MODIFY ELEMENTS
points(i).X = RND(640)
points(i).Y = RND(480)
Chapter 6 Number Crunching: Math Operators and Commands (127)
Increment and Decrement commands: INC <var> [,amt] or DEC <var> [,amt]
default without [amt] is one.
ex. INC num, 20 if num was 10 it will be 30 after execution of that statement
RELATIONAL OPERATOR (134)
= Equal <> not equal < less than > greater than <= less than or equal >= greater than or
equal
SQRT(<num>) square root
ABS(<num>) Absolute value of num
INT num truncates number to an integer
EXP raise to an integer power

5
^ raise to a decimal power
RANDOM NUMBERS
RND(N) returns values from 0 to N so a dice roll is d = RND(5)+1
Seeding generator RANDOMIZE <int>
RANDOMIZE TIMER() will use the TIMER() function to get a value of system time in
milliseconds.
DATE and TIME
GET DATE$() returns a format like 08/05/02 DarkBASIC only provides that date format.
If you want another you will have to program it. See examples pg. 141.
GET TIME$() returns a format like 18:16:31 24-hour format. To get other formats you
must program them. See page 142.
HIGHER MATH SIN() COS() TAN() in degrees.
Chapter 7 Reading and Writing Data: File Input/Output Command (147)
Folder and Directory are interchangeable terms
GET DIR$ returns the current drive letter and folder name
Print get DIR$() will print it out.
DRIVELIST prints the list of all the drives available to the screen
PERFORM CHECKLIST FOR FILES
CHECKLIST STRING$ file and directory names
CHECKLIST VALUE 0 is a file, otherwise it is a folder.
DIR prints all the files within the current directory
SET DIR
Special relative directories: "." the current directory, and ".." the previous directory (151)
MAKE DIRECTORY creates a new folder in current directory folder must not
exist or command will fail
DELETE DIRECTORY deletes a directory must be empty to delete it.
FILE ACCESS MODES (152)
SEQUENTIAL FILES (text files)
RANDOM-ACCESS FILES (structured files)
BASIC FILE COMMANDS (153)
SEARCH | INFORMATION | MANAGEMENT commands
Finding Files: FIND FIRST locates first file in current directory
GET FILE NAME$ name of current file being searched,
GET FILE DATE$ date of the current file being searched,
GET FILE TYPE 1 directory, 0 otherwise, -1 no more files
FILE NEXT continues file search
INFORMATION (154)
FILE SIZE in bytes
FILE EXIST takes on string parameter and returns 1 if exists 0 if it doesn't USE PRIOR
to FILE SIZE if you are not sure if file exists.

6
PATH EXIST command checks to see if a directory exists. 1 if it does 0 if it doesn't.
MANAGEMENT (155)
MAKE FILE, COPY FILE, DELETE FILE, MOVE FILES, RENAME FILE commands
MAKE FILE takes one parameter, the name of the file you want to create file must not
already exist
COPY FILE two parameters source, destination, fails if destination exists
DELETE FILE filename fails if file does not exist
MOVE FILE source, destination fails if destination file already exists
RENAME FILE original, new fails if original does not exist or if new does.
FILE INPUT/OUTPUT (156)
Open files for reading or writing. After reading or writing close the file.
ex. OPEN TO READ 1, "NewFile.txt"
OPEN TO READ #, <filename> # 1 to 32 unique <filename> string.
OPEN TO WRITE #, <filename>
CLOSE FILE #
FILE OPEN(#) returns 1 if open 0 if not
FILE END(#) returns 1 on end of file, 0 if not.
READING AND WRITING STUFF (158)
READ and WRITE reads or write an integer. Done often enough it will force FILE END
to 1. ex. READ STRING 1, somedata where somedata was declared to be a string.
READ FILE #, <var> reads an integer from file integer is four bytes in size
READ BYTE #, <var> one byte
READ WORD #, <var> two bytes
READ LONG #, <var> four bytes
READ FLOAT #, <var> four bytes
READ STRING #, <var>
CLIPBOARD (162)
GET CLIPBOARD$ returns string containing content of clipboard
WRITE TO CLIPBOARD <string>
Part II 2D Game Programming (163)
Chapter 8 Introduction to 2D Graphics: Basic Vector Drawing Commands (165)
Topics: Pixels and Resolution (167)
Color 32 bit 24 bits of color and 8 bits of alpha which controls transparency.
Polygons composed of three or more vertices
Double Buffering copy of display screen, write to hidden screen and switch. Essential
for flicker-free animation. DB handles this automatically and does everything in DirectX
3D mode. So DB is considered a 3D programming language.
Commands that return values must include empty parentheses because that is how DB
distinguishes between regular functions and those that return a value.

7
' Check for installed video cards
PERFORM CHECKLIST FOR GRAPHICS CARDS 'gives graphics cards
VideoCards = CHECKLIST QUANTITY()
IF VideoCards > 1
PRINT "There are ",VideoCards," installed video cards. "
FOR Index = 1 TO VideoCards
PRINT " ", Index, " - ", CHECKLIST STRING$(Index)
NEXT Index
ELSE
PRINT "There is one installed video card."
ENDIF
' Display current video driver
PRINT "Video Driver: ", CURRENT GRAPHICS CARD$()
' Check for transform and lighting
IF TNL AVAILABLE() = 1 ' tells if transform and lighting are supported
PRINT "Transform and lighting supported. "
ELSE
PRINT "No transform and lighting. "
ENDIF
' Display memory available
PRINT "Total video memory: ", SYSTEM DMEM AVAILABLE()
PRINT "System memory free: ", SYSTEM SMEM AVAILABLE()
PRINT "Total memory free: ", SYSTEM TMEM AVAILABLE()
' Wait for user to press key
WAIT KEY
' Delete checklist array from memory
EMPTY CHECKLIST
' End the program
END
(174-177)
DISPLAY MODE CODE
' Get the list of video modes
PERFORM CHECKLIST FOR DISPLAY MODES
SET DISPLAY MODE 640, 480, 32
DO
' Draw gray resolution markers
CLS
INK RGB(120, 120,120), 0

8
BOX 0,0,1599,1199
INK RGB(100,100,100),0
BOX 0,0,1279,959
INK RGB(80,80,80),0
BOX 0,0,1023,767
INK RGB(60,60,60),0
BOX 0,0, 799,599
INK RGB(30,30,30),0
BOX 0,0,639,479
' Display the list of video modes
INK RGB(255,255,255),0
modes = CHECKLIST QUANTITY()
FOR t=1 TO modes / 2
' First column of resolutions
SET CURSOR 0,t * 16
PRINT t;" ";CHECKLIST STRING$(t);
' Second column of resolution
SET CURSOR 200, t * 16
index = modes/2+t
PRINT index; " ";CHECKLIST STRING$(index)
NEXT t
' Ask user to select a video mode
INPUT "Select mode: ";position
' Rip the values out of the video array
width = CHECKLIST VALUE A(position)
height = CHECKLIST VALUE B(position)
depth = CHECKLIST VALUE C(position)
' Change Display Mode width, height, depth
SET DISPLAY MODE width, height, depth
LOOP
(180) BASIC GRAPHICS PROGRAMMING
Drawing Color: INK and RGB are used to set foreground and background colors for
graphics and text drawing
INK with two parameters: foreground and background color
ex.
Forecolor = RGB(120,120,120)
Backcolor = RGB(255,0,0)
INK Forecolor, Backcolor 'RGB(red, green, blue) returns color code
CLEARING SCREEN
CLS uses the background color previously set with an INK fore, back command.

9
The CLS command in the program on page 181 did not work as advertised. CLS cleared
the screen but did not change the default background color from black.
READING AND SETTING PIXELS (181)
DOT X,Y plots a pixel to the screen using the INK command color
' Inirialize the program: draws randomly colored pixels to random locations
SET DISPLAY MODE 1280,800, 32
CLS
' Start the Main Loop
DO
' Pick a random color
fcolor = RGB(RND(255),RND(255),RND(255))
INK fcolor, RGB(0,0,255)
' Draw the pixel
DOT RND(1280),RND(800)
LOOP
DRAWING LINES (182)
LINE X1,Y1,X2,Y2 draws a line in current INK
' Initialize Line Drawing Program
SET DISPLAY MODE 1280,800, 32
CLS
' Start the main loop
DO
' Pick a random color
fcolor = RGB(RND(255),RND(255),RND(255))
INK fcolor, RGB(0,0,0)
' Draw the line
LINE RND(1280),RND(800),RND(1280),RND(800)
LOOP
DRAWING RECTANGLES (183)
BOX X1,Y1, X2, Y2 draws box in INK
' Initialize Rectangle Drawing Program
SET DISPLAY MODE 1280,800, 32
CLS
' Start the main loop
DO
' Pick a random color
fcolor = RGB(RND(255),RND(255),RND(255))
INK fcolor, RGB(0,0,0)
' Draw the line

10
BOX RND(1280),RND(800),RND(1280),RND(800) ' only command changed
LOOP
DRAWING CIRCLES (184)
CIRCLE X,Y, R X,Y the center and R the radius in pixels
' Initialize Circle Drawing Program
SET DISPLAY MODE 1280,800, 32
CLS
' Start the main loop
DO
' Pick a random color
fcolor = RGB(RND(255),RND(255),RND(255))
INK fcolor, RGB(0,0,0)
' Draw the line
CIRCLE RND(1280),RND(800),RND(200)
LOOP
THE FOLLOWING PROGRAM DRAWS A CIRCLE WITH DOTS (186)
' Initialize Circle Drawing Program
SET DISPLAY MODE 1280,800, 32
CLS
v=0
size = RND(200)+ 100
' Start the main loop
DO
' Pick a random color
fcolor = RGB(RND(255),RND(255),RND(255))
INK fcolor, 0
' Draw the line
' Move point around circle
ox = COS(v)* size
oy = SIN(v)* size
v=v+1
' Draw the point
DOT 640 + ox, 400 + oy
LOOP
DRAWING ELLIPSES (185)
ELLIPSE X,Y, RX, RY see programs (187-189)
CHAPTER 9 BITMAPPED GRAPHICS and IMAGES (191)
BITMAPS a collection of bytes that represents a picture

11
Many formats .TIF .JPG .GIF .PCX DB natively supports .BMP Windows Bit Map
format. Bitmaps vary in BPP (Bits Per Pixel) or color depth where total colors available
are 2^(bit depth) ex. 8, 256; 12, 4096; etc.
TOOLS example tools: Paint Shop Pro (www.jasc.com or www.corel.com) for creating
bitmaps and Pro Motion (www.cosmigo.com) for working with animated sprites.
DB limits the number of bitmaps loaded to 32. Each is addressed like an array with
indices from 0 .. 31. Bitmap 0 is a special bitmap because it appears directly on the
screen. Bitmap numbers may not be reused without deleting the previous bitmap.
BITMAP CHARACTERISTICS width, height, depth
LOAD BITMAP filename, bitmap number (196) loads bitmap into memory
CREATE BITMAP bitmap number, width, height when you create a bitmap all
drawing operations go to the new bitmap.
COPY BITMAP bitmap number, 0 displays the bitmap
COPY BITMAP FromBM, ToBM
COPY BITMAP FromBM, Left, Top, Right Bottom, ToBM, Left, Top, Right, Bottom
BITMAP EXIST(bitmap number) returns 1 for true 0 for false
BITMAP WIDTH(bitmap number) returns width
BITMAP HEIGHT(bitmap number) returns height
BITMAP DEPTH(bitmap number) returns depth
SET CURRENT BITMAP <bitmap number> lets you draw to any bitmap you like
CURRENT BITMAP() returns the bitmap number of the current bitmap
SAVE BITMAP filename, bitmap number saves a bitmap to file
DELETE BITMAP bitmap number you cannot delete bitmap 0 so only 31 can be
deleted 1 .. 31.
Example code drawing bitmap of random circles:
' creat a new bitmap
PRINT "Creating the bimap ... "
CREATE BITMAP 1, 640,480
' Display message on screen
SET CURRENT BITMAP 0
PRINT "Drawing Circles ... "
' draw some circles on the bitmap surface
SET CURRENT BITMAP 1
FOR N = 1 TO 200
INK RGB(RND(255),RND(255),RND(255)),0
CIRCLE RND(540)+50,RND(380)+50,RND(40)
NEXT N
SET CURRENT BITMAP 0
PRINT "Press a key to display the bitmap ... "
WAIT KEY

12
' copy bitmap 1 to the screen
COPY BITMAP 1, 0
WAIT KEY
END
Make sure that the bitmap jeep.bmp is loaded in the project file. (199)
LOAD BITMAP "jeep.bmp",1
COPY BITMAP 1,0
WAIT KEY
Bitmap Info Program displays bitmap and information about it.
` load the bitmap file
LOAD BITMAP "earth.bmp",1
` display the bitmap file
COPY BITMAP 1, 0
` display information about the bitmap
SET CURRENT BITMAP 0
TEXT 460,0, "WIDTH: "+STR$(BITMAP WIDTH(1))
TEXT 460,20,"HEIGHT: "+STR$(BITMAP HEIGHT(1))
TEXT 460,40,"COLOR DEPTH: "+STR$(BITMAP DEPTH(1))+ " bits"
` delete the bitmap from memory
DELETE BITMAP 1
WAIT KEY
END
MANIPULATING BITMAPS (201)
COPY BITMAP has two sets of parameters: From, To and a more complicated version
that specifies copying only part of a bitmap to a part of another (201)
COPY BITMAP FromBM, Left, Top, Right Bottom, ToBM, Left, Top, Right, Bottom
(COPY BITMAP uses 0,0 as the upper left corner so you should not attempt to copy
beyond WIDTH-1 or HEIGHT -1.
SPECIAL EFFECTS COMMANDS five types MIRROR, FLIP, FADE, BLUR, and
SET GAMMA
MIRROR BITMAP bitmapNumber flips bitmap horizontally
BITMAP MIRRORED(bitmap number) lets you check if a bitmap has been mirrored
FLIP BITMAP bitmapNumber flips bitmap vertically
BITMAP FLIPPED(bitmap number) checks if bitmap is flipped
FADE BITMAP bitmap number, fade value 0 black, 100 no fade, effect is permanent
until you create or load the bitmap again.
BLUR BITMAP bitmap number, blur value 1 beer, to 6 vodka permanent until
reloaded
SET GAMMA red, green, blue values 0 to 511 with 255 being the middle 0 removes
all of the particular color.

13
IMAGE SHUFFLE GAME CODE (204) 4x4 tile game (code pages 206 210) about
200 lines of code. Some improvements suggested as projects. Suggestions to
improve the game include: High Score, New Tilesets, Board Size, Special
Effects when tile moves.
CHAPTER 10 2D ACTORS: BASIC SPRITE COMMANDS (213)
Introduction to Sprites
Sprite a small two dimensional bitmap drawn to the screen at a specified position and
usually with transparency.(transparency is defined by pixels in the source bitmap
that are set to a certain color which is "transparent" so that the background color
shows through.) Transparency is the key to game play since it allows objects to be
in front of others in a realistic way.
BitBlt bit block transfer. Memory blocks are copied from one location to another using
a direct memory transfer mode optimized with machine code.
Loading Sprites two ways (1) first load bitmap image into the bitmap file using the
LOAD BITMAP filename, bitmap number command. Use this generally to
load a sheet of images and fetch images from the sheet using:
GET IMAGE Image number, left, top, right, bottom.
or you can (2) use LOAD IMAGE filename, image number
DRAWING A SPRITE use SPRITE Sprite#, X, Y, Image# (218)
SPRITE IMAGE(#) returns image number
SPRITE WIDTH(#) returns width
SPRITE HEIGHT(#) returns height
SPRITE EXIST(#) returns 0 or 1 depending on whether the sprite exists
OFFSET SPRITE command can be used to change the default horizontal and vertical
offset from the top-left corner to the center or some other corner.
SPRITE OFFSET X(#) returns horizontal offset or shift value of the sprite
SPRITE OFFSET Y(#) returns vertical offset or shift value of the sprite
DRAWING AND MOVING SPRITES (219) DB combines the two functions of
drawing and moving in a single command called SPRITE
SHOW SPRITE # makes Sprite visible, doesn't change position
HIDE SPRITE # makes Sprite invisible, doesn't change position
SPRITE #, X, Y, Image#
SPRITE X(#) returns sprite's X position
SPRITE Y(#) returns sprite's Y position
SPRITE RENDERING PROPERTIES let's background restoration and
transparency properties be changed. Restoration controls saving sprite
backgrounds so that they can be restored when the sprite moves. If disabled
(value of 0) the sprite will smear the screen.
SET SPRITE #, BackSave, Transparency State
VISIBILITY SHOW SPRITE # and HIDE SPRITE #
SHOW ALL SPRITES makes all visible, HIDE ALL SPRITES makes all invisible.

14
GAME LOOPS commonly thought of as the GAME ENGINE. Table 10.1 has a
listing of game engines is some popular games (221)
A Game Loop is usually set to run indefinitely. When a condition for ending the game
arises you can use EXIT to break out of the loop. Any of the looping commands
can be used to start a game loop:
DO .. LOOP
REPEAT .. UNTIL
WHILE .. ENDWHILE
USUAL CONTENTS
GRAPHICS | SOUND | AI | USER INPUT | MULTIPLAYER
SIMPLE GAME LOOPS
Running =1
These simple loops do not include timing
REPEAT
which you must include yourself in your
IF MOUSECLICK() = 1
game loop.
Running = 0
SLEEP duration and WAIT duration will
ENDIF
pause the program for a given number of
UNTIL Running <> 1
milliseconds.
Running = 1
WHILE Running = 1
IF MOUSECLICK() = 1
Running = 0
ENDIF
ENDWHILE
DO
IF MOUSECLICK() = 1
EXIT
ENDIF
LOOP

TIMER returns internal system time in


milliseconds and can also be used for
profiling a game (223)
SYNC ON|OFF allows user control of
the screen update rate. SYNC command
copies the double buffer to the screen
SYNC RATE frameRate tells DB to
maintain the given frameRate. By
default DB tries to maintain 40 frames
per second. Setting rate to 0 tells DB to
run as fast as possible.

THE DARKANOID GAME PROJECT (225) a typical ball and paddle style game.
DEVELOPMENT GOALS
1. acquire artwork to be used in game
2. draw background
3. draw blocks in predefined arrangement
4. move and draw ball and deflect it from the wall
5. move and draw the paddle based on player input
ALL GRAPHICS WILL BE DRAWN USING PASTE IMAGE
Entering Darkanoid code manually to get a sense of the code. Finished entering code
and only had a couple of minor glitches missentered the dim statement and
accidentally used an '=' where a '-' was supposed to be thereby mislocating the paddle.

15
CHAPTER 11 2D ACTING: Sprite Animation (235)
Modern game designers call what used to be named "sprites" actors. Still very relevant.
Three basic commands:
LOAD BITMAP Filename, Bitmap#
GET IMAGE Image#, Left, Top, Right, Bottom
SPRITE Sprite#, X, Y, Image#
Animated Spites supported by DB. An animated sprite is just series of static sprites.
Figure 11.1 (237) shows 80 frames, 10 frames for each of eight directions, cardinal and
intercardinal points. Check www.reinerstileset.de for examples of free sprite artwork.
DB can handle large numbers of animation frames using images drawn with the SPRITE
command.
Entered code for AnimationTest and played with rates to change the speed of the
ogre_attack sprite. (241)
Drawing Sprites the Easy Way
DB provides an easier way
CREATE ANIMATED SPRITE loads bitmap and grabs frames and handles animation.
After loading use: PLAY SPRITE and PASTE SPRITE or SPRITE command to draw the
current sprite.
Animated Raptor example, page 242.
Creating and Editing Sprites Using Pro Motion www.cosmigo.com (243) Played a little
with the free version and ordered the full version.
Tutorial on Pro Motion can use free trial version on CD.
Rotating Sprites On The Fly (257)
ROTATE SPRITE command allows you to rotate sprites
Entered code on page 258-259 which rotates tank but rotates it around left corner, then
added correction using: offset sprite 1, 32,32 (pg 260) which causes the tank to rotate
around center.
Resizing Sprites on the Fly
SCALE SPRITE command with 100 = original full scale. Example in text (260) scales
wasp.bmp image. Using SCALE SPRITE image#, scale demonstrated sprite scaling.
Note: can't scale a sprite from CREATE ANIMATED SPRITE
Update Darkanoid game (263)
Ran into a problem that I seem to have lost all previous source code. I'll need to look at
that carefully. So far I've looked at it and I keep losing the source code. Can't really see
how it works I'll have to read the documentation on saving source files. What I've
been doing seems like it should work but it isn't working. I try to open a file in the
project that I saved with code in it and a blank file opens. That's just strange. I continued
fooling with it and it is certainly non-intuitive.
Chapter 12 Game Physics: Sprite Collision Testing (269)
Three types of collisions: 1) Bounding Rectangle, 2) Impact, and 3) No Collision
BOUNDING RECTANGLE

16
Checks for overlap between the bounding rectangle of the two sprites.good way for a
quick check but it is not exact because the contents of the sprite might not have actually
collided. But it would well as a fast screen for which to check more closely. (271)
IMPACT COLLISION called pixel perfect collision detection and is generally only
checked after bounding rectangle detection.
DB provides: SPRITE COLLISION Bounding rectangle collision and SPRITE HIT
impact collision on actual image pixels.
Entered the code for the Collision Test and ran it backed up the code in notepad to
make sure that I didn't lose it. (278)
Keyboard Basics (284) key states UP, DOWN, PRESSED
UP means has not been pressed
DOWN means currently pressed
PRESSED was up, then down currently up is in the pressed state.
Keys commonly used in games include: arrow keys (AWSD sometimes, left, up, down,
right) other commonly used keys are Enter, Alt, Ctrl, and Spacebar.
Mouse Basics (285) used to indicate XY-position, cursor control and mouse buttons.
Button states are UP, DOWN (used to drag things), CLICKED (equivalent to
PRESSED) and DOUBLE-CLICKED.
Joystick Basics (286) similar to mouse, gives XY and button clicks, commonly UP,
DOWN or PRESSED
Keyboard Commands (287) used to read strings using INPUT command. Two forms:
INPUT string$ or INPUT string$, variable$ downside, INPUT is a blocking
command. You can't do anything else while you are INPUT'ing.
Can also read keyboard as a series of individual keys.
WAIT KEY waits for any key to be pressed. It is a blocking command, and the
equivalent SUSPEND FOR KEY command performs the same function.
INKEY$() command tells which key is currently being pressed and is a non-blocking
command so you can loop without stalling the program. It returns the current key
being pressed. The command is case sensitive you can detect UP, DOWN and
PRESSED by checking for NOT value of key, value of key and a sequence of not,
equal and then not again. You can check for ASCII value of keys with INKEY$
()=CHR$(value), ex. Enter as CHR$(13) etc.
Reading Special Keys (289) Tab:8, Backspace:9, Enter:13, Esc:27, and Sparebar:32.
Nine special keys are supported.
UPKEY() up arrow
DOWNKEY() down arrow LEFTKEY() left arrow
RIGHTKEY() right arrow CONTROLKEY() Ctrl
SHIFTKEY() shift
SPACEKEY() spacebar RETURNKEY() Enter
ESCAPEKEY() esc
Key commands return 0 if UP and 1 if DOWN
Reading Multiple Keys and Scan Codes (291) scancodes are independent of ASCII
but instead refer directly to the key pressed and may not always be standard
SCANCODE() returns the scancode of a key when it is currently being pressed.

17
KEYSTATE(scancode) return 1 if down and 0 if up.
Non-Blocking Input (292) two commands for non-blocking input.
ENTRY$() and CLEAR ENTRY BUFFER commands read status of Windows
keyboard buffer. Example code:
sync on
InputString as string
StaticString as string
charhit as string
newlen as integer
repeat
cls
ink rgb(255.255.255), rgb(0,0,0)
text 10,10 get time$()
text 10, 370 "Type your string here and notice that time keeps
ticking"
charhit = inkey$()
if charhit = chr$(8)
StaticString = StaticString + entry$()
NewLen = len(StaticString) -1
StaticString = left$(StaticString, NewLen)
clear entry buffer
endif
InputString = StaticString + entry$()
text 10, 400, InputString
sync
until escapekey()=1

Mouse Commands (294)


HIDE MOUSE hides the mouse
SHOW MOUSE opposite of hide mouse
Mouse Position (295) DB reads X, Y, Z coordinates (Z refers usually to the mouse
wheel)
MOUSEX() returns X position of mouse 0 .. pixels width 1
MOUSEY() returns Y position of mouse 0 .. pixels height 1
MOUSEZ() returns value of the mouse wheel between 0 .. 100
Positioning the Cursor (295) POSITION MOUSE X-pos, Y-pos Example code:
sync on
white = RGB(255,255,255)
black = RGB(0,0,0)
while escapekey()=0
ink 0,0
box 0,0,639,479
ink white, black
tempstring$ = "Mouse X pos: " +
text 10,10,tempstring$
tempstring$ = "Mouse Y pos: " +
text 10,22,tempstring$
tempstring$ = "Mouse Z pos: " +
text 10, 34, tempstring$
tempstring$ = "Press R to Reset
text 10,400,tempstring$
if inkey$()="R" OR inkey$()="r"

STR$(MOUSEX())
STR$(Mousey())
STR$(MouseZ())
the mouse"

18
POSITION MOUSE 0,0
endif
sync
endwhile

Mouse Movement historically this is done by differencing mouse position data to get
deltas. DB provides MOUSEMOVE commands:
MOUSEMOVEX() returns delta X
MOUSEMOVEY() returns delta Y, and
MOUSEMOVEZ() returns delta Z.
Code example for using Mouse Motion commands:
HIDE MOUSE
SYNC ON
SYNC RATE 30
SIZEX = 100
SIZEY = 100
LOAD BITMAP "mustang.bmp", 1
SET CURRENT BITMAP 0
WHILE ESCAPEKEY()=0
cls
sizex = sizex + (MOUSEMOVEX()/10)
IF sizex > 100 THEN sizex = 100
IF sizex < 1 THEN sizex = 0
sizey = sizey + (MOUSEMOVEY()/10)
IF sizey > 100 THEN sizey = 100
IF sizey < 1 THEN sizey = 0
x2 = (bitmap width(1)*sizex)/100
y2 = (bitmap height(1)*sizey)/100
COPY BITMAP 1,0,0,bitmap width(1), bitmap height(1),0,0,0,x2,y2
TEXT 10, 460,"Move the mouse to scale the picture"
SYNC
ENDWHILE

Mouse Buttons are returned by MOUSECLICK() with values (for a two button
mouse) of 0=none, 1=left, 2=right, 3=both. (299) has codes up to four buttons.
To detect a mouse click detect the mouse click followed by MOUSECLICK()=0.
To determine a double click requires detecting that the mouse has been clicked
twice within a given timeframe.
The Mouse Handler a concept that works well in the context of game programming.
It's a function that handles all mouse activity.
Shooting Gallery Program
SYNC ON
SYNC RATE 30
DIM SpriteHit(20)
DIM Spritetimer(1)
HIDE MOUSE
SpriteTimer(1) = 0
LOAD IMAGE "crosshair.bmp",25

19
LoadTargetAnims()
` Initialize all the sprites
FOR x = 2 TO 20
SPRITE X, -100, 68, 5
SET SPRITE x, 1, 1
SpriteHit(x)=0
NEXT X
` set the mouse cursor sprite
SPRITE 1, 320,240, 25
SET SPRITE 1,1,1
` Setting up the lines in the background
SET CURRENT BITMAP 0
Green = RGB(0,255,0)
Red = RGB(255,0,0)
Black = RGB(0,0,0)
White = RGB(255,255,255)
INK Green, Black
BOX 0,98,639,102
INK Red, Black
BOX 0,100,639,100
INK White, Black
inum = 5
TEXT 10, 40, "Click on the target to destroy it!"
` Play the game until the Escape key is hit.
WHILE ESCAPEKEY()=0
ProcessSprites()
ControllerHandler()
SYNC
ENDWHILE
END
` This moves the crosshairs to where the mouse is
FUNCTION ControllerHandler()
SPRITE 1, MOUSEX(), MOUSEY(), 25
IF MOUSECLICK() = 1
FOR X = 2 TO 20
IF SPRITE COLLISION(1,X)
SpriteHit(X) = 1
ENDIF
NEXT X
ENDIF
ENDFUNCTION
` This does all the Sprite Collisions processing
FUNCTION ProcessSprites()
SpriteTimer(1) = SpriteTimer(1) - 1
IF SpriteTimer(1) <= 0 THEN MoveNewSprite()
FOR X = 2 TO 20
IF SPRITE X(X) > 704
SPRITE X, -100,68,5
ENDIF
IF SpriteHit(X)
SPRITE X, SPRITE X(x)+5,SPRITE Y(X), SPRITE IMAGE(X)+1
IF SPRITE IMAGE(X) >=15
SPRITE X, -100, 68, 5
SpriteHit(X)=0
ENDIF

20
ELSE
IF SPRITE X(X) >= -64
SPRITE X, SPRITE X(x)+5,SPRITE Y(x),5
ENDIF
ENDIF
NEXT X
ENDFUNCTION
` Moves out a new sprite
FUNCTION MoveNewSprite()
FOR X=2 TO 20
IF SPRITE X(X)<= -100
SPRITE X, -64,SPRITE Y(X),5
X=21
ENDIF
NEXT X
SpriteTimer(1) = 30
ENDFUNCTION
` Loads the target animations
FUNCTION LoadTargetAnims()
LOAD BITMAP "target.bmp",1
inum = 5
fadestep = 100
SET CURRENT BITMAP 1
FOR x = 0 to 10
FADE BITMAP 1, 90
GET IMAGE inum, 0,0,64,64
inum = inum + 1
NEXT X
DELETE BITMAP 1
SET CURRENT BITMAP 0
ENDFUNCTION

Code works! Skipped the rest of Chapter 13 which focuses on Joysticks.


Chapter 14 Game Audio: Sound Effects and Music (317)
How to load and play WAV, MIDI, and MP3 sound brief discussion of frequency and
sampling. CD sound is sampled at 16 bits of resolution.
Loading Sound Files
Use LOAD SOUND "filename" , sound number ex. LOAD SOUND "yeah.wav", 13
LOAD 3DSOUND "filename" , sound number (320)
Is a Sound Loaded? to find out use SOUND EXIST (sound number)
You can also CLONE a sound buffer letting you play the same sound multiple times
without having separate buffers for each play.
CLONE SOUND destination sound number , source sound number
ex. CLONE SOUND 4, 114
Deleting a Sound Buffer
DELETE SOUND sound number
Playing Sound Files
PLAY SOUND sound number , start position sound position is optional
ex. PLAY SOUND 5

21
ex. PLAY SOUND 5 , 30000 you can also LOOP SOUND which makes the sound
repeat
LOOP SOUND sound number , start position , end position , initial position
ex. LOOP SOUND 5
LOOP SOUND 5, 3000
LOOP SOUND 5, 3000, 5000
LOOP SOUND 5, 3000, 5000, 2500
Finally to Stop
STOP SOUND sound number you can also PAUSE and RESUME sounds
PAUSE SOUND sound number
RESUME SOUND sound number
Panning and Volume Control
Panning adjusts the amount of the sound coming from the left and right speakers. You
can also adjust the Speed to make the sound render faster
Panning Left to Right (323)
SET SOUND PAN sound number , pan value Pan Value is between -100 and +100
where -100 is left speak full on and right off and vice versa.
GET SOUND PAN (sound number) returns current Pan Value.
Speed Changing Sound's Playback Frequency (324)
SET SOUND SPEED sound number , frequency value lets you speed up or slow down
sounds.
GET SOUND SPEED (sound number) returns the value of the sound speed.
Setting a Sound's Volume (325)
SET SOUND VOLUME sound number , volume value Volume Value 0 .. 100 percent.
GET SOUND VOLUME (sound number) returns the Volume Value.
SOUND BUFFER PROPERTIES
SOUND TYPE (sound number) returns 0 for Normal Sound and 1 for a 3D Sound
SOUND PLAYING (sound number) tells whether the selected sound is playing.
3D SOUND Positional Sound Playback
Positional sound using combinations of panning, speed and volume to position the
listener and the sounds in a virtual room. You have to keep track of the listener
and the location of the sound to control 3D sound effectively.
The sequence of activity is:
1) Load sound as a 3D sound, then 2) Position the sound, and 3) Play the sound. (327)
Most important is POSITION SOUND with syntax:
POSITION SOUND sound number , X-position, Y-position , Z-position
To return the position of the sound use SOUND POSITION X(sound number) or
SOUND POSITION Y(sound number) or SOUND POSITION Z(sound#)
Positioning the Listener
POSITION LISTENER X-position , Y-position , Z-position you can also get the
listener's position using:
LISTENER POSITION X(), LISTENER POSITION Y(), or LISTENER POSITION Z()
Adjusting Listener's Rotational Position (330)
ROTATE LISTENER X-angle , Y-angle , Z-angle angle in degrees
You can also retrieve the Listener's angle with:
LISTENER ANGLE X(), LISTENER ANGLE Y(), or LISTENER ANGLE Z()

22
MUSIC (331) MIDI (Musical Instrument Direct Interface) .mid and MP3 are the two
formats that DarkBASIC supports. MIDIs are really synthesized music while
MP3's are a compressed form of digital recording (MP3 can run good quality near
CD sound at 1 MB per minute (44KHz, 16bit). MIDI takes less space, about 10
Kbytes per minute versus MP3's 1 MB per minute.
Loading Music Files
LOAD MUSIC filename , music number maximum of 32 can be loaded at a time.
DELETE MUSIC music number frees up a music number
Playing Music
PLAY MUSIC music number starts the music playing at the beginning
ex. LOAD MUSIC "TitleMusic.mid" , 20
PLAY MUSIC 20
LOOP MUSIC music number always starts at beginning and loops back to beginning.
STOP MUSIC music number stops the music
PAUSE MUSIC music number and RESUME MUSIC music number
MUSIC PLAYBACK PROPERTIES
Checking the Validity of a Song
MUSIC EXIST lets you find out if a song has been loaded.
Value = MUSIC EXIST (Music Number) returns a 1 if song exists and a 0 if it doesn't.
Value = MUSIC PLAYING (Music Number) tells you if the song is playing
Value = MUSIC LOOPING (Music Number) checks if music is looping
Value = MUSIC PAUSED (Music Number) checks if music is paused. Pausing music
is good for a dramatic effect. Code example (335)
Enhancing Darkanoid begins on page 336. Note on page 338 about DB modes,
specifically tutorial mode and project manager PM mode.
Main source code file for your project is always open and assumed to be in the project.
The Sources File list consists of the additional files in the project. DB (340) puts
all your files into a long source file for compilation so you can put various
elements in separate files for organizational clarity and they will be compiled
together. GOOD IDEA to read the code, both to understand it and to see some of
the good practices a game programmer uses. Notice the global declarations at the
beginning of the program. The MAIN GAME LOOP is in a function named
Run_Game() (345) Check out the enhancements to Darkanoid and play the
game to experience the powerups, the sound effects, etc. Then read the code to
figure out how it was done. There is no better way to learn programming than
to read the code written by someone who knows what they are doing.
CHAPTER 15: 2D WORLDS (359)
Learn to work with scrolling and tile-based backgrounds. Scrolling displays a small
portion of a larger 2D game world.
Scrolling the Screen
Do example on page (361-362)
Tiling example of a tiling declaration
`Tiling code
global MAP_ACROSS as integer = 10
global MAP_DOWN as integer = 5
data 1,1,1,1,1,1,1,1,1,1

23
data 1,2,2,2,2,2,2,2,2,1
data 1,2,2,2,2,2,2,2,2,1
data 1,2,2,2,2,2,2,2,2,1
data 1,2,2,2,2,2,2,2,2,1
data 1,1,1,1,1,1,1,1,1,1
` page 366 data map tiling example
Open ScrollTiles Project and read the code:
Initial code is a wide range of global constants defined to accomplish various things. The
first globals are TILEW, TILEH, and COLS then the data statements for the tiled
background are added.MAP_ACROSS at 29 and MAP_DOWN as 25 where the data
elements identify the tiles to be used in rendering from the tiles in figure 15.5 on page
367.
Next are more global constants: TILE_BITMAP, SCROLL_BITMAP and a series of
scrolling variables: scrollx, scrolly, and tilex, tiley then comes the creation of the
bitmap:
CREATE BITMAP SCROLL_BITMAP, MAP_ACROSS*TILEW,
MAP_DOWN*TILEH note the map parameters are multiplied by the tile width and
height which gives the pixel count of the map:29*32, 25*32 = 928,800 32x32 pixel
tiles. Then the code loads the tile bitmap with:
LOAD BITMAP "tiles.bmp", TILE_BITMAP where TILE_BITMAP is just an integer
identifier.

Next the code copies the tiles to the scroll buffer which is just another bitmap.(370)
Creating the Scroll Buffer is done in a NESTED FOR LOOP that loops over the data
structure reading in the horizontal lines first. The code in the loop begins:
READ tilenumber this reads an integer that selects the tile type. (see 113)
The tilenumber has to be converted to a reference into the tiles bitmap using:
x = (tilenumber MOD COLS)*(TILEW+1) x coordinate of selected tile bitmap
note: MOD is the modulus or remainder operator, notice that the tile bitmap on page
367 is divided up into 10 tiles per row.
y = (tilenumber / COLS)*(TILEH+1) y coordinate of selected tile bitmap
Now we have to load the tiles into the SCROLL_BITMAP from the TILE_BITMAP.
This loading is done tile by tile inside the nested FOR-loop using the COPY BITMAP
statement:
COPY BITMAP TILE_BITMAP, x, y, x+TILEW, y+TILEH, SCROLL_BITMAP,
tilex*TILEW, tiley*TILEH,tilex*TILEW+TILEW, tiley*TILEH+TILEH this
basically says using the tile bitmap at x,y and put it into tilex,tiley in the
SCROLL_BITMAP but we have to pass both sides of the bitmap tiles.
ENTER THE GAME LOOP (370)

24
Review code on page 370 which 1) sets sync rate, 2) enters game loop which 2.1) gets the
mouse parameters and uses those to calculate the bitmap scrolling parameters both x
and y and then CLS (clear the screen) and draw the scroll window using a portion of
the virtual buffer:
COPY BITMAP SCROLL_BITMAP, etc. (see page 371)
***POSSIBLE ENHANCEMENTS: 1) Make the map bigger, 2) Modify the tiles used
and their placement, 3) get ambitious and create a unique tile set of your own.
Dynamic Tile-Based Scrolling (required because static bitmaps can become too large
for the memory available)
Dynamic scrolling or "just in time" scrolling draws tiles directly to the screen read the
description of the technique beginning on page 371. The technique involves only
drawing the portion of the tiles that will actually be displayed plus a few so that the
scroll buffer can be simply updated as the scrolling takes place which takes much less
memory. Other then the dynamic character of the rendering, the basic idea is similar
to the static example. The code begins on page 377 the way to understand this is to
compare it in detail with the code for the static scroller which was discussed starting
on page 367.

Chapter 16 Advanced Sprite Programming: Alpha Channel Transparency and


Angular Motion (385)
Chapter addresses 1) alpha channel transparency, and 2) angular motion.
Checkout sprite designers Levi Bath @ http://www.levibath.com and Reiner Prokein @
http://www.reinerstileset.de Check these links out if you want to see what is out there.
Both links are fascinating. Prokein's link offers many models which can be
downloaded and fooled with.
Two kinds of transparency: 1) use a transparency color key problem is that you must
know the color key, however picking a standard color key reduces this problem,
SET IMAGE COLORKEY 255,255,255 would set a white color key,

25
2) you can also use an alpha channel instead of a color key. Alpha channel is a color
channel in a 32 bit image that stores a mask which filters out portions of the image.
DarkBASIC supports 32 bit images with alpha channels in PNG formats (388)
went to change the bitmap of the space ship in Photoshop elements and the program
failed to compile throwing a compiler exception which I could not isolate. This also
caused me to lose the executable that was on my disk so I'll have to reload it. Drat!
Angular Motion begins to be discussed on page (391) to achieve a real feel game
sprites need to be able to represent angular motion. Without angular abilities the
sprites typically can only move in 8 directions NSEW, SE,SW,NE,NW and this makes
things very unrealistic. It also makes the game code rather bulky with special purpose
code. Angular motion is demoed with Astro Gunner a little space shooting gallery
game. Load and run Astro Gunner and play it a little to get the idea. Follow along
with the logic entering the code for Astro Gunner.
Astro Gunner Code enter code for Astro Gunner keeping track of what is going on.
The first part (401) defines a lot of constants then we get to a sprite structure definition
which uses two new properties: imagenum and spritenum. These let more complex
games to be built so we define a custom sprite datatype.
See (402)
type mySPRITE
elements in earlier sprite definition
imagenum as integer
spritenum as integer
endtype
As I entered the Astro Gunner code I continued to have problems with the compiler. So I
decided to try to see if I could move the project and compile it. Didn't work so I spent
some time trying to dig up the author and get some help via email found his web site
and some other stuff but mostly got bounces from efforts to contact him. Left a message
on his Discussion Forum. I'm presuming it is a versioning problem of some kind.
Chapter 17 Playing Intro Movies and Cut-Scenes (413)
Introducing Movies and playing a short discussion of the advent of video in games
mentioning Wing Commander II. Video formats mentioned are .AVI (Audio-Video
Interleaved), and Apple's Quicktime (.MOV), RealMedia (.RM), .MPG MPEG. Term
animation is used in DarkBASIC to refer to videos.
DarkBASIC works with AVI files using the command:
LOAD ANIMATION filename , animation number can load up to 32 but they are
likely to be large so you may not want to load too many at one time.
Checking A Video's Status
Value = ANIMATION EXIST(animation number) if loaded returns one, else 0.
Value = ANIMATION PLAYING(animation number) to see if it is playing.
Value = ANIMATION WIDTH(animation number) returns width in pixels
Value = ANIMATION HEIGHT(animation number) returns height
PLAY ANIMATION animation number, Left, Top, Right, Bottom plays animation.
DELETE ANIMATION animation number removes animation from memory.

26

Testing AVI Playback (417) to test AVI playback I wrote a short program using the
Shroud of Turin avi files that I have.
SET DISPLAY MODE 640, 480, 32
HIDE MOUSE
LOAD ANIMATION "VP8-1-1A.avi", 1
PLAY ANIMATION 1, 0,0, 320,240
LOOP ANIMATION 1
WAIT KEY ` after keypress loads second video
LOAD ANIMATION "VP8-1-2A.avi",2
LOOP ANIMATION 2, 0, 320,0,640,240
WAIT KEY ` second keypress ends animation
DELETE ANIMATION 1
DELETE ANIMATION 2
END

To play an animation continuously you want to use:


LOOP ANIMATION animation number, bitmap number, Left, Top, Right, Bottom all
the parameters except the animation number are optional.
STOP ANIMATION animation number stops the animation playback.
PAUSE ANIMATION animation number pauses animation at current position
Value = ANIMATION PAUSED(animation number) returns the status of the
animation, 1 if it is paused, 0 otherwise.
RESUME ANIMATION animation number will resume the animation
Multi-Animation Program (420) DarkBASIC allows multiple animations at a time.
The example of the Shroud animations demonstrated this but the code in the book is a
bit more flexible and demos four simultaneous animations. Sample movies can be
downloaded from www.ifilm.com. See program (420-422).
Changing Position and Size of Movie (422)
PLACE ANIMATION animation number, Left, Top, Right, Bottom used to reposition
and scale an image during playback. During playback you may which to know where
the animation is on the screen. This can be discovered using ANIMATION
POSITION.
Value = ANIMATION POSITION X (animation number)
Value = ANIMATION POSITION Y (animation number) return X and Y position of
the animation respectively. The animation can be scaled by adjusting the size of the
image using the Left, Top, Right, Bottom parameters in PLACE ANIMATION. See
ScaleAnim program on pages (424-425)
Movie Trailers (425-426) conversion to movie format can be accomplished with may
tools readily available, ex. EO Video http://www.eo-video.com DarkBASIC can
actually compile the movie into the executable. A short example program is given on
pages 426-427.
Part III 3D Game Programming (six chapters: 18-23)
Chapter 18 Fundaments of 3D Graphics Programming (431)
Terminology: Vertices are points (x, y, z) and three vertices make up a polygon. The
Coordinate system is a Cartesian coordinate system (435) x-horizontal, y-vertical and
z into the screen. When rendering you can think of the CAMERA as the LOCAL
ORIGIN. Graphics quality is determined by a variety of things: fill rate, vertex
shader, pixel shaders, anti-aliasing, transform and lighting

27
Introducing Polygons (438) Drawing a wireframe
` Wireframe Prgram pg 439
` set up the screen
SYNC ON
SYNC RATE 30
COLOR BACKDROP RGB(0,0,0)`BLACK
INK RGB(255,255,255),0` WHITE
` create a triangle (a set of three points)
MAKE OBJECT TRIANGLE 1, 0,0,0,0,10,0,10,10,0 ` three 3D points
` center triangle at the origin
MOVE OBJECT LEFT 1, 5
MOVE OBJECT DOWN 1, 5
` draw object as a wireframe
SET OBJECT WIREFRAME 1,1
` drag camera back away from object
MOVE CAMERA -12 ` Z axis pull back
` wait for a keypress
REPEAT
SYNC
UNTIL ESCAPEKEY()=1
END

Edges of triangle may look a little fuzzy due to anti-aliasing. FSAA (Full Screen AntiAliasing) is a capability of some probably most graphics cards it may not always look
great. You can fool with it in the Windows Display Settings (Control Panel)
Drawing a Wireframe Cube (440)
Enter code on page 441
` Wireframe Example pg 441
` set up screen
SYNC ON
SYNC RATE 30
COLOR BACKDROP RGB(0,0,0)
INK RGB(255,255,255),0
` create a triangle
MAKE OBJECT CUBE 1, 50
` draw the triangle as a wireframe
SET OBJECT WIREFRAME 1,1
` uncomment to show away-facing polygons
SET OBJECT CULL 1, 0 ` turns off culling to see all edges
` move the amera out for a better view
POSITION CAMERA 50,50,-60
POINT CAMERA 0,0,0
` wait for a keypress
REPEAT
SYNC
UNTIL ESCAPEKEY()=1
END

Drawing a Shaded Polygon (442)


Without the SET OBJECT WIREFRAME the result is a shaded white surface. SET
OBJECT COLOR command creates colors.
` Triangle Program pg 444
` enable manual screen refresh
SYNC ON
SYNC RATE 100
` set some initial settings
HIDE MOUSE

28
COLOR BACKDROP RGB(0, 40, 40)
RANDOMIZE TIMER()
` create a colored triangle
MAKE OBJECT TRIANGLE 1,-10,-10,0,-10,10,0,10,10,0
COLOR OBJECT 1, RGB(RND(255),RND(255),RND(255))
` move camera back away from object
MOVE CAMERA -20
` main loop
REPEAT
` rotate the X axis of the triangle
XROTATE OBJECT 1, OBJECT ANGLE X(1) + 1
` rotate the Y axis of the triangle
YROTATE OBJECT 1, OBJECT ANGLE Y(1) + 1
` update the screen
SYNC
UNTIL ESCAPEKEY()=1
` clean up
SHOW MOUSE
END

When I first entered the code for this I accidentally entered the second point of the
triangle the same as the first (so there were only two distinct vertices) and the result
was that the triangle didn't render. You have to be careful with the coordinates.
Drawing a Shaded Quadrilateral introduces the idea of two triangles called a
triangle list there is an optimized way to render triangles by reducing the number of
vertices you have to enter using shared vertices with adjacent triangles called a
triangle strip.
` Quadrilateral pg 447
` enable manual refresh
SYNC ON
SYNC RATE 100
` set some initial settings
HIDE MOUSE
COLOR BACKDROP RGB(0,40,40)
RANDOMIZE TIMER()
` create colored triangle
MAKE OBJECT TRIANGLE 1,-10,-10,0,-10,10,0,10,10,0
COLOR OBJECT 1, RGB(RND(255),RND(255),RND(255))
MAKE OBJECT TRIANGLE 2,-10,-10,0,10,10,0,10,-10,0
COLOR OBJECT 2, RGB(RND(255),RND(255),RND(255))
` move camera away from object
MOVE CAMERA -20
` main loop
REPEAT
` rotate the X axis of the triangle
XROTATE OBJECT 1, OBJECT ANGLE X(1)+1
XROTATE OBJECT 2, OBJECT ANGLE X(2)+1
YROTATE OBJECT 1, OBJECT ANGLE Y(1)+1
YROTATE OBJECT 2, OBJECT ANGLE Y(2)+1
` update the screen
SYNC
UNTIL ESCAPEKEY()=1
` clean up
SHOW MOUSE
END

29
Running this program I noticed that as the triangle flattened (into a plane??) the color
went out of the composite triangles.
Drawing a Rectangle spelling error in DB
MAKE OBJECT PLAIN (should be PLANE) it creates a polygon (two triangles, 4
points) without joining the triangles.
` Rectangle Drawing page 449
` enable manual screen refresh
SYNC ON
SYNC RATE 100
` set some initial settings
HIDE MOUSE
COLOR BACKDROP RGB(0,40,40)
RANDOMIZE TIMER()
` create a colored triangle
MAKE OBJECT PLAIN 1, RND(10)+1, RND(10)+1
COLOR OBJECT 1,RGB(RND(255),RND(255),RND(255))
` uncomment to draw in wireframe
` SET OBJECT WIREFRAME 1,1
`main loop
REPEAT
XROTATE OBJECT 1, OBJECT ANGLE X(1) -0.75
YROTATE OBJECT 1, OBJECT ANGLE Y(1) +1
SYNC
UNTIL ESCAPEKEY()=1
SHOW MOUSE
END

BASIC 3D Graphics Commands (451)


Creating Stock Objects already seen CUBE, TRIANGLE, and plane PLAIN
Triangle MAKE OBJECT TRIANGLE number, x1,y1,z1,x2,y2,z2,x3,y3,z3 triangles
are the fundamental building block of all other shapes
Surface (Plane) MAKE OBJECT PLAIN number, Width, Height
Creating Stock Objects seen some plane (PLAIN), triangle, cube (452)
MAKE OBJECT TRIANGLE number, x1,y1,z1,x2,y2,z2,x3,y3,z3 building block of all
other objects
MAKE OBJECT PLAIN number, Width, Height rectangular surface (a plane)
MAKE OBJECT CUBE number, size
MAKE OBJECT BOX number, Width, Height, Depth
MAKE OBJECT CYLINDER number, size
MAKE OBJECT CONE number, size
MAKE OBJECT SPHERE number, size, rows, columns
Transforming and Drawing 3D Objects
Transformations include: 1) Rotation, 2) Translation, 3) Scaling
You have to be concerned with the location of the CAMERA, i.e. the viewpoint from
which the scene is rendered.
The MakeObjects Program
` Make Objects page 453
` create some arrays
DIM angle(5)
DIM posx(5)
DIM posz(5)

30
` initialize the program
SYNC ON
SYNC RATE 40 ` set this to 0 for fastest speed
HIDE MOUSE
COLOR BACKDROP RGB(0,40,40)
` create a CUBE
MAKE OBJECT CUBE 1, 50
COLOR OBJECT 1, RGB(255,0,0) ` red
` create a CONE
MAKE OBJECT CONE 2, 50
COLOR OBJECT 2, RGB(0,255,0) ` green
` create a sphere
MAKE OBJECT SPHERE 3, 50
COLOR OBJECT 3,RGB(0,0,255) ` blue
` create a box
MAKE OBJECT BOX 4, 50,25,25
COLOR OBJECT 4, RGB(255,255,0) ` yellow
` create a cylinder
MAKE OBJECT CYLINDER 5, 50
COLOR OBJECT 5, RGB(0,255,255) ` cyan
` reposition the camera to get the whole view
PITCH CAMERA DOWN 25
MOVE CAMERA -200
` set initial angles for each object
ANGLE(1) = 0
ANGLE(2) = 72
ANGLE(3) = 144
ANGLE(4) = 216
ANGLE(5) = 288
radius = 150
` start the loop
REPEAT
` move the objects in a circle
FOR n = 1 to 5
` calculate X position using cosine
posx(n)=COS(ANGLE(n))*radius
posz(n)=SIN(ANGLE(n))*radius
angle(n)=angle(n)+1
POSITION OBJECT n, posx(n),0, posz(n)
XROTATE OBJECT n, OBJECT ANGLE X(n)+1
YROTATE OBJECT n, OBJECT ANGLE Y(n) + 0.5
NEXT n
` display frame rate and update the screen
TEXT SCREEN WIDTH()-80, SCREEN HEIGHT()-30,"FPS: "+STR$(SCREEN FPS())
SYNC
UNTIL ESCAPEKEY()=1
`clean up
SHOW MOUSE
END

Simple but fairly cool program that shows the relative power of the standard objects.
Adding Textures to 3D Objects (456)
Texturing pastes a bitmap image onto a polygon and gives realism to the rendering.

31
To maintain speed all video cards paste textures in the hardware. Software texturing
simply cannot keep up. DB makes texturing very easy. A texture is just a bit map
it can be a JPG, PNG, BMP, TGA, DDS, or DIB file.
LOAD IMAGE filename, imageNumber loads a bitmap. After loading
Applying Texture to a Polygon
TEXTURE OBJECT object-number, image-Number
Code for Applying Texture
` Make Objects page 453
` create some arrays
DIM angle(4)
DIM posx(4)
DIM posz(4)
` initialize the program
SYNC ON
SYNC RATE 40 ` set this to 0 for fastest speed
HIDE MOUSE
COLOR BACKDROP RGB(0,60,60)
` create a light source
SET AMBIENT LIGHT 0
MAKE LIGHT 1
MAKE OBJECT SPHERE 9, 10
COLOR OBJECT 9, RGB(255,255,255)
` create a CUBE
MAKE OBJECT CUBE 1, 75
LOAD IMAGE "pyramid.bmp",1
TEXTURE OBJECT 1,1
` create a CONE
MAKE OBJECT CONE 2, 50
COLOR OBJECT 2, RGB(0,255,0) ` green
` create a sphere
MAKE OBJECT SPHERE 3, 50
COLOR OBJECT 3,RGB(0,0,255) ` blue
` create a box
MAKE OBJECT CUBE 4, 50
COLOR OBJECT 4, RGB(255,0,0) ` red
` reposition the camera to get the whole view
PITCH CAMERA DOWN 25
MOVE CAMERA -200
` set initial angles for each object
ANGLE(2) = 0
ANGLE(3) = 135
ANGLE(4) = 270
radius = 150
` start the loop
REPEAT
` move the objects in a circle
FOR n = 2 to 4
` calculate X position using cosine
posx(n)=COS(ANGLE(n))*radius
posz(n)=SIN(ANGLE(n))*radius
angle(n)=angle(n)+1
POSITION OBJECT n, posx(n),0, posz(n)

32
NEXT n
YROTATE OBJECT 1, OBJECT ANGLE Y(1)+0.5
YROTATE OBJECT 2, OBJECT ANGLE Y(2)+ 1
XROTATE OBJECT 3, OBJECT ANGLE X(3)+1
XROTATE OBJECT 4, OBJECT ANGLE X(4) + 1
` MOVE THE LIGHT SOURCE ACCORDING TO THE MOUSE POSITION
POSITION LIGHT 1, MOUSEX()-320,0,240-MOUSEY()
POSITION OBJECT 9, MOUSEX()-320,0,240-MOUSEY()
` display some text messages and refresh the screen
TEXT 5,5, "Use your mouse to move the light source."
TEXT SCREEN WIDTH()-100,SCREEN HEIGHT()=30,"FPS: "+STR$(SCREEN FPS())
TEXT SCREEN WIDTH()-80, SCREEN HEIGHT()-30,"FPS: "+STR$(SCREEN FPS())
SYNC
UNTIL ESCAPEKEY()=1
`clean up
SHOW MOUSE
END

This code is fairly cool it shows how a light source can be positioned and moved with
a mouse and shows the light influencing the rendering of the objects as they orbit the
central textured object.
CHAPTER 19 LIGHTS, CAMERA, ACTION: 3D Lighting and Camera Control
(463) In this chapter the issues are lighting the scene and controlling the camera. Passive
lighting can be simulated by drawing the lighting directly into the scene but then it is
not dynamic. DB provides built in support for lighting
Ambient Light
Something like fill light uniform lighting present in a scene without specific
directionality like a fog of light. All surfaces lite with a fixed illumination.
SET AMBIENT LIGHT percentage value 0 .. 100. 100 is too bright no shadows. 0 is
useful if you want to use directional lights in a scene (you want ambient to be dark)
You can also set colored light.
COLOR AMBIENT LIGHT colorValue
Program Ambient Light
` Ambient Light page 465
Ambient = 0
Direction = 1
Red = 0
Green = 0
Blue = 0
` initialize program
SYNC ON
SYNC RATE 60
HIDE MOUSE
COLOR BACKDROP RGB(0,60,60)
` create textured cube
MAKE OBJECT CUBE 1, 75
LOAD IMAGE "cube.bmp",1
TEXTURE OBJECT 1,1
POSITION OBJECT 1, 0,-20,-120
`position the camera
MOVE CAMERA -150
PITCH CAMERA DOWN 20

33
` START THE LOOP
REPEAT
` rotate the objects individually
YROTATE OBJECT 1, OBJECT ANGLE Y(1)+1
` update ambient variable
Ambient = Ambient + Direction
IF Ambient > 100
Ambient = 100
Direction = -1
ENDIF
IF Ambient < 0
Ambient = 0
Direction = 1
ENDIF
` set the ambient light
SET AMBIENT LIGHT Ambient
` update the ambient color variables
IF Red > 254
IF Green > 254
IF Blue > 254
Red = 0
Green = 0
Blue = 0
ELSE
Blue = Blue + 1
ENDIF
ELSE
Green = Green + 1
ENDIF
ELSE
Red = Red + 1
ENDIF
` set the ambient color
COLOR AMBIENT LIGHT RGB(Red, Green, Blue)
` display the ambient variable
TEXT 10,10,"Ambient level: " + STR$(Ambient)
TEXT 10,20,"Color: "+STR$(Red)+","+STR$(Green)+","+STR$(Blue)
` update the screen
SYNC
UNTIL ESCAPEKEY()=1
` clean up
SHOW MOUSE
END

This program creates a rotating cube that is lighted by the ambient light level which
cycles from red to yellow to white as each light is cycled in turn.
Directional Lighting (468)
SET DIRECTIONAL LIGHT LightNumber, DirX,DirY,DirZ X,Y,Z defines the
direction the light is pointing
Directional Lighting Program (469-470)
` DirectionalLight pg. 469
` create variables
posx = 0
posz = 0
angle = 0
radius = 200

34
` initialize program
SYNC ON
SYNC RATE 60
HIDE MOUSE
COLOR BACKDROP RGB(0,40,40)
` create the floor
MAKE MATRIX 1, 1000, 1000, 10,10
LOAD IMAGE "floor.bmp", 2
POSITION MATRIX 1, -500,-100,-500
PREPARE MATRIX TEXTURE 1,2,1,1
UPDATE MATRIX 1
` CREATE THE LARGE SPHERE
MAKE OBJECT SPHERE 1, 100
COLOR OBJECT 1, RGB(245,200,0)
` CREATE THE SMALL SPHERE
MAKE OBJECT SPHERE 2, 20
COLOR OBJECT 2, RGB(255,0,255)
POSITION OBJECT 2, 200, 0, 200
` create the directional light
MAKE LIGHT 1
SET DIRECTIONAL LIGHT 1, 0,0,0
COLOR LIGHT 1, RGB(255,0,0)
` set up the camera
POSITION CAMERA 0, 200, -400
POINT CAMERA 0,0,0
` start the loop
REPEAT
` MOVE THE SMALL SPHERE AND LIGHT SOURCE
posx = COS(angle)*radius
posz = SIN(angle)*radius
angle = angle + 1
POSITION OBJECT 2, posx + 20, 0, posz + 20
POSITION LIGHT 1, posx, 0, posz
POINT LIGHT 1, 0,0,0
` UPDATE THE SCREEN
SYNC
UNTIL ESCAPEKEY()=1
` CLEAN UP
SHOW MOUSE
END

Small sphere circles large sphere small sphere is a light source that is red that
illuminates the large sphere as it circles it. Interesting example.
Point Lights
Point lights emit light in all directions but with limited range so they allow for limited
lighting effects. DB has only a limited supply of lights.
SET POINT LIGHT LightNumber, PosX,PosY,PosZ X,Y,Z is position of the light
Program to Test Point Lights
A small light source circles a larger sphere in the darkness.
` point light example code pg 471
` create some variables
posx = 0
posz = 0
angle = 0
radius = 120
`initialize the program

35
sync on
sync rate 60
hide mouse
color backdrop rgb(0,0,0) ` dark background
` set the ambient light
set ambient light 5
`create a point light
set point light 0,0,0,0
color light 0, rgb(245,200,0)
set light range 0,200
` create the central sphere
make object sphere 1, 50
color object 1, rgb(245,200,0)
` set up the camera
position camera 0, 50, -100
point camera 0,0,0
`start the loop
repeat
` orbit the point aorund the sphere
posx = cos(angle)*radius
posz = sin(angle)*radius
angle = angle + 2
position light 0, posx, 0, posz
` rotate the central sphere
yrotate object 1, object angle y(1)+1
` update the screen
sync
until escapekey()=1
`clearn up
show mouse
end

This program is interesting, but the rendering at least on my Vaio is at least strange since
the sphere isn't very spherical looks a little rippled and polygonal.
Spot Lights
SET SPOT LIGHT LightNumber, InnerAngle, OuterAngle PosX,Y,Z parameters
position the light
Testing Spot Lights program (473)
` Testing Spot Lights page 473
posx = 0
posz =0
angle = 0
height = 150
radius = 400
` initialize program
sync on
sync rate 60
hide mouse
color backdrop rgb(0,60,60)
` create a textured cube
make object cube 1, 100
load image "cube.bmp", 1
texture object 1,1
`create the "floor"
make matrix 1, 1000, 1000, 10, 10
load image "floor.bmp", 2

36
position matrix 1, -500, -100, -500
prepare matrix texture 1,2,1,1
update matrix 1
` marker object for green light
make object sphere 10,10
color object 10, rgb(0,0,255)
position object 10, 200,0,200
` create a green spotlight
make light 1
set spot light 1, 30,10
color light 1, rgb(0,0,255)
position light 1, 200,0,200
point light 1, 0,0,0
` marker object for red light
make object sphere 11, 10
color object 11, rgb(255,255,0)
position object 11, -200,0,-200
` create a red spot light
make light 2
set spot light 2, 30,10
color light 2, rgb(255,255,0)
position light 2, -200,0,-200
point light 2, 0,0,0
` start the loop
` set up the camera
`position camera 0, 200, -400
`point camera 0,0,0
` start the loop
repeat
`rotate the camera around the scene
posx = cos(angle)*radius
posz = sin(angle)*radius
angle = angle + 1
position camera posx, height, posz
point camera 0,0,0
sync
until escapekey()=1
show mouse
end

I had a hassle doing this one because in the game loop I typed 'range' instead of 'radius'
and because basics create variables on the fly and initialize them to zero as a default it
killed off the program. I looked at the code forever before finally seeing that I'd type
range instead of radius. This is a problem with basics that will bite you sooner or later.
Controlling the Camera (475)
Cameras are very important since they lend dynamics to the game. The presence of
cameras controls scene rendering. The default camera is numbered 'zero' 0.set slightly
back on the Z-axis and pointed at 0,0,0. You can use the default camera or you can
create new cameras.
MAKE CAMERA CameraNumber creates a camera
SET CURRENT CAMERA CameraNumber selects the camera being rendered
SET CAMERA VIEW CameraNumber, Left, Top, Right, Bottom which I think means
you can render a camera in a section of the screen (the next test program will show
that)

37
You can also position the camera using:
POSTION CAMERA CameraNumber, X, Y, Z
To find out the camera's position you can ask:
CAMERA POSITION X(CameraNumber) or Y or Z.
Pointing the Camera
POINT CAMERA CameraNumber, X, Y, Z sets the camera direction. That's all you
need.
Testing Camera Commands (477)
` Camera Test program pg 479
` create some variables
posx = 0
posz = 0
angle = 0
height = 150
radius = 300
screenw = screen width()
screenh = screen height()
` initialize program
sync
sync rate 100
hide mouse
color backdrop rgb(0,60,60)
` create the floor
make matrix 1, 1000,1000,10,9
load image "floor.bmp",2
position matrix 1, -500,-100,-500
prepare matrix texture 1,2,1,1
update matrix 1
` create a textured cube
make object cube 1,100
load image "cube.bmp", 1
texture object 1,1
` create the moving sphere
make object sphere 2, 50
color object 2, rgb(245,0,200)
` create and set up the cameras
make camera 1
set camera view 1, 10,10,110,110
make camera 2
set camera view 2, screenw -110, 10, screenw-10,110
make camera 3
set camera view 3, 140,10, 240, 110
make camera 4
position camera 4, 0, 600,0
point camera 4, 0,0,0
set camera view 4, screenw-240, 10, screenw-140,110
make camera 5
position camera 5, 900,400,-900
point camera 5, 0,0,0
set camera view 5, screenw/2-50,10, screenw/2+50,110
position camera 0,0,100,-400
point camera 0,0,0,0
`start the loop
repeat
yrotate object 1, object angle y(1)+1

38
set camera to follow 2,0,0,0,0,200,30,1.0,0
posx=cos(angle)*radius
posz=sin(angle)*radius
angle = angle +1
` move camera 1
position camera 1, posx, height, posz
point camera 1, 0,0,0
` move the sphere
position object 2, -1*posx, cos(angle)*posz/2,-1*posz+200
` move camera 3
x=object position x(2)
y=object position y(2)
z=object position z(2)
set camera to follow 3,x,y,z,1,100,y,1.0,0
` display frame rate
text screenw-70,screenh-20,"FPS "+STR$(screen fps())
sync
until escapekey()=1
show mouse
end

This is a program that really shows how flexible DB really is with many cameras
viewing the scene through may view points all simultaneously. Very powerful!
CHAPTER 20 3D ACTORS: Loading and Rendering 3D Models (483)
DB supports two 3D mesh formats .X and .3DS Direct X and 3D Studio repectively. It
also supports three file formats .MDL, .MD2, and .MD3
Loading a Mesh File (484)
LOAD OBJECT Filename, ObjectNumber there are many commands that are not
covered in the text filename extensions (X, 3DS,MDL, MD2,MD3), many
commands we don't have time to explore, see http://www.thegamecreators.com
Drawing a 3D Object must specify the x,y,z coordinates, ensure camera is pointing at
the object and that it is less than 5000 units from the camera.
POSITION OBJECT ObjectNumber, X,Y,Z positions the object
SHOW OBJECT ObjectNumber will render the first frame if an animation, to play an
animation there are two options
PLAY OBJECT ObjectNumber [, start, end] square brackets indicate optional. To
play an object continuously you can use LOOP
LOOP OBJECT ObjectNumber [ , start, end] w/o start, end the whole animation will
play
Before playing you have to specify the speed which is related conceptually with the
frame rate of the game specified using the sync rate command which is mostly set to
60. So you have to set the animation speed using the command
SET OBJECT SPEED ObjectNumber, Speed
A Short Program to render a mesh
load object "soldier.x",1
position object 1, 0,0,0 ` position object at origin
` reorient object so it is standing
xrotate object 1, -90
yrotate object 1, 90
` animate the object
set object speed 1, 6000
loop object 1
` point camera at the object

39
cy = object size y(1)/2
position camera 100, cy, -200
point camera 0, cy, 0

Testing 3D Animation

` Animated Model page 487


` animation constants
ani_idle = 1
ani_fidget = 2
ani_attack = 3
ani_hurt = 4
ani_dodge = 5
ani_block = 6
ani_falldown = 7
ani_getup = 8
ani_walkstart = 9
ani_walking = 10
ani_walkstop = 11
ani_runstart = 12
ani_running = 13
ani_runstop = 14
animations:
data 0, 12800
`idle
data 12800,24000 `fidget
data 24000,32000 `attack
data 32000,40000 `hurt
data 40000,48000 `dodge
data 48000,56000 `block
data 56000,64000 `fall down
data 64000,72000 `get up
data 72000,75200 `walk-position to loop
data 75200,84800 `walk-looping
data 84800,88000 `walk-return to stance
data 88000,91200 `run-position to loop
data 91200,100800 `run-looping
data 100800,104000 `run-return to stance
` custom animation type
type ANIMTYPE
start as integer
stop as integer
endtype
` create and fill the animation array
dim anim(14) as ANIMTYPE
for n = 1 to 14
read anim(n).start
read anim(n).stop
next n
`global variables
global axis_size as integer = 500
global radius as integer = 300
global angle as integer = 0
global frame as integer = 0
` code creates three axes
` show the X axis
` color backdrop rgb(0,0,0) ` added looking at disk code
make object plain 8, axis_size,axis_size
xrotate object 8, 90

40
color object 8, rgb(255,0,0)
` show the Y axis
make object plain 9, axis_size,axis_size
yrotate object 9, 90
color object 9,rgb(0,255,0)
ghost object on 9
` show the Z axis
make object plain 10, axis_size,axis_size
color object 10, rgb(0,0,255)
ghost object on 10
` load ans position the Samurai model
load object "samurai.x", 1
position object 1,0,0,0
xrotate object 1, -90
yrotate object 1, 90
set object speed 1, 9000
animate(ani_walking)
sync on
sync rate 60
color backdrop rgb(0,0,0)
set ambient light 50
set spot light 0, 10, 20
position light 0, 500, -1000, 500
point light 0,0,0,0
set normalization on
` animate function
` now for the game loop
repeat
key as string
key = inkey$()
select key
case "1":animate(ani_idle):endcase
case "2":animate(ani_fidget):endcase
case "3":animate(ani_attack):endcase
case "4":animate(ani_hurt):endcase
case "5":animate(ani_dodge):endcase
case "6":animate(ani_block):endcase
case "7":animate(ani_falldown):endcase
case "8":animate(ani_getup):endcase
case "9":animate(ani_walking):endcase
case "0":animate(ani_running):endcase
endselect
` print the object size
sx$ = str$(int(object size x(1)))
sy$ = str$(int(object size y(1)))
sz$ = str$(int(object size z(1)))
text 0,0, "object size: " + sx$ + "," + sy$ + "," + sz$
` print the object position
px$ = str$(int(object position x(1)))
py$ = str$(int(object position y(1)))
pz$ = str$(int(object position z(1)))
text 200,0, "object pos: " + px$ + "," + py$ + "," + pz$
text 0,10, "animation frame: " + str$(object frame(1))+ " of " + str$
(total object frames(1))
` print camera position

41
px$ = str$(int(camera position x()))
py$ = str$(int(camera position y()))
pz$ = str$(int(camera position z()))
text 600,0,"camera pos: " + px$ + "," + py$ + "," + pz$
` animation key instructions
text 0,100,"1 - Idle"
text 0,110,"2 - Fidget"
text 0,120,"3 - Attack"
text 0,130,"4 - Hurt"
text 0,140,"5 - Dodge"
text 0,150,"6 - Block"
text 0,160,"7 - Fall Down"
text 0,170,"8 - Get Up"
text 0,180,"9 - Walk"
text 0,190,"0 - Run"
` print instructions
center text screen width()/2,screen height()-20,"rotate: mouse buttons,
zoom: mouse wheel"
` rotate camera based on mouse buttons
button = mouseclick()
if button = 1 then angle = angle - 1
if button = 2 then angle = angle + 1
` mouse wheel zooms in and out
zoom = mousemovez()
if zoom > 0 then radius = radius - 10
if zoom < 0 then radius = radius + 10
` rotate the camera around the scene
posx = cos(angle)*radius
posz = sin(angle)*radius
position camera posx, 100, posz
point camera 0, 40, 0
sync
until escapekey()
function animate(frame as integer)
loop object 1, anim(frame).start, anim(frame).stop
endfunction

This code above runs while the code on the disk did not run properly. I had a lot of
trouble with this code because typos entering the code caused errors which were quite
unclear and hard to find turned out to be extra colons in the select statement. One hint
for finding errors is to look for anomalies in the auto-coloring of the text if something
isn't colored correctly, especially in view of surrounding code then there's an error in the
vicinity. The compiler doesn't always find the errors correctly (surprise surprise!)
CHAPTER 21 LANDSCAPING: Building 3D Terrain Using Matrices (493)
Chapter talks about bumpy terrain and following the terrain contours. We've used the
matrix command but not seen it discussed. First you have to create a matrix using the
make matrix command.
MAKE MATRIX MatrixNumber, Width, Height, Xtiles, Ytiles creates a flat matrix and
divides it into tiles. Then you want to load an image using LOAD IMAGE and apply
the image to texture the matrix. (See the texture tiles used in Chapter 15) The tile

42
image looks like an animation strip. Use PREPARE MATRIX TEXTURE to apply the
textures to the tiles.
PREPARE MATRIX TEXTURE MatrixNumber, ImageNumber, TilesAcross, TilesDown
the last two parameters should describe the parameters of the texture image.
RANDOMIZE MATRIX MatrixNumber, MaxHeight generates random heights for the
tile vertices. The more tiles the higher the quality of the resulting terrain.
SET MATRIX TILE MatrixNumber, TileX, TileZ, TileNumber this command allows
you to iterate through the tiles and create your terrain directly. Example code would
look something like that on (494)
for z = 0 to 99
for x = 0 to 99
tile = rnd(3)+1 ` to generate random tile
SET MATRIX TILE 1, x, z, tile
next x
next z

Once you've made changes to your matrix you must update it with:
UPDATE MATRIX MatrixNumber
Contour Following
Typically you will want to have other 3D items go over the contour you have created. To
do that you have to know the height of the matrix at each point.
GET GROUND HEIGHT with parameters of matrix number, x-position, and z-position
allows you to find the height:
height = GET GROUND HEIGHT( MatrixNumber, Xposition, Yposition )
So how do you go about following the contour of the terrain? Here's the code example
on page (495)
sync on
sync rate 60
color backdrop rgb(0,0,0)
randomize timer()
` animation constants
global WALK_START = 75200
global WALK_STOP = 84800
` create a random matrix
load image "tiles.bmp", 30
MAKE MATRIX 1, 2000,2000,40,40
PREPARE MATRIX TEXTURE 1, 30, 4, 1
RANDOMIZE MATRIX 1, 40
for z = 0 to 39
for x = 0 to 39
tile = rnd(3)+1
SET MATRIX TILE 1, x, z, tile
next x
next z
UPDATE MATRIX 1
` set up some simple ambient lighting
set ambient light 50
set normalization on
` now let's load the mesh
` load the geisha model
load object "geisha.x", 1

43
xrotate object 1, -90
yrotate object 1, 180
position object 1, 200, 0, 200
loop object 1, WALK_START, WALK_STOP
set object speed 1, 9000
` now enter main loop
repeat
` keep character on top of terrain
x = object position x(1)
z = object position z(1)
y = GET GROUND HEIGHT(1, x, z)
position object 1, x, y, z
` move object using arrow keys
if leftkey() then position object 1,x-5, y,z
if rightkey() then position object 1, x+5, y, z
if upkey() then position object 1, x, y, z+5
if downkey() then position object 1, x, y, z-5
` set the camera
position camera -100, 200, -100
point camera 2000, 0, 2000
sync
until escapekey()

CHAPTER 22 MULTIPLAYER LAN and Internet Programming (499)


Games are more fun when you can play with others and that requires some kind
of connectivity. This chapter touches in a very introductory way some of the
issues associated with multiplayer games, including: 1) Multiplayer
Games, 2) Networking Models, 3) TCP/IP Protocol, and illustrates it by 4)
Writing a Chat Program.
Multiplayer or Single player games?
DB uses DirectX's DirectPlay to support multiplayer games. DirectPlay is a
networking component. Two models are supported: 1) client/server and 2) peerto-peer. Both require a server or host and a client but they differ in how they pass
packets around. A packet is a collection of data used in communicating between
computers.
Client/Server one computer is the master and the rest are clients and all
packets are first sent to the server. This is a centralized model.
Peer-to-Peer No master computer. It is a computer to computer free for all.
Packet Transport (501) DB supports four types of packet transport: 1) Serial
(NULL Modem), 2) modem, , 3) IPX/SPX, and 4) TCP/IP which this book covers
and is the most widely used protocol.
The TCP/IP Protocol every computer in the network has an IP address. This
is currently described with 4-bytes, i.e. four numbers in the range 0..255 (ex.
192.168.0.50) You can also have domain names, but these must be translated to
IP addresses.
Selecting the Correct Transport You need to know what number represents
the TCP/IP protocol. Use: PERFORM CHECKLIST FOR NET CONNECTIONS
which will fill the CHECKLIST with the transports available. CHECKLIST
STRING$ contains protocol names and numbers. (502)
Establishing a Network Connection Two paths are required: a client and a
server path. They differ by a single command.

44
Creating the Server Path start by setting the connection type using
SET NET CONNECTION ConnectionNumber " " the blank space in quotes is
required to establish the computer as host. The ConnectionNumber was gotten
from the PERFORM CHECKLIST FOR NET CONNECTIONS command.
Now you create the game with
CREAT NET GAME GameName, PlayerName, NumberOfPlayers, Flag
maximum number of players is 256 including yourself. The Flag designates
1=peer-to-peer, 2=client/server. Once the server path is created the server just
waits for players.
Establishing the Client Path everyone not a host is a client and must connect
to the host to play. They connect by using the command:
SET NET CONNECTION ConnectionNumber, AddressData same form of
command as for the Server Path. AddressData is a string. It can be blank or
hold an IP address or a domain name. If blank a dialog box will request the
address data.
Finding Games on Host use PERFORM CHECKLIST FOR NET SESSIONS
and then to establish connection to game use:
JOIN NET GAME SessionNumber, PlayerName Session Number is the
number found with the PERFORM CHECKLIST command and the Player
Name is a string containing your name.
Chat Client Program Example you can connect by starting two instance on
your computer and connecting to local host 127.0.0.1 or the IP address of your
machine.
Code for Chat Program
` Chat program page 504
sync on
sync rate 30
` keep track of what was saidn and who said it
dim ChatText$(32)
dim PlayersName$(1)
dim NumberOfPlayers(1)
dim LastNumberOfPlayers(1)
` find the TCP/IP conneciton number
TcpIpNumber = FindTCPIPConnectionNumber()
print "Simple network chat client!"
print
sync
` Get their name
input "Please Enter Your Name: ", MyName$
PlayersName$(1) = MyName$
sync
if MyName$ = ""
print "You need to enter a name!"
wait key
end
endif
` find out who the host and clients are
print "(1) I'm the Host"
print "(2) I'm the Client"
sync

45
a$=""
Answer = 0
` Get Host or Client
while Answer = 0
a$=inkey$()
if a$="1" then Answer = 1
if a$="2" then Answer = 2
endwhile
` do this if I'm the Host
if Answer = 1
print "Creating net session. Please wait"
sync
sleep 200
set net connection TcpIpNumber, " "
create net game "Sample Net Session", MyName$, 16, 1
endif
` Do this if I'm the Client
if Answer = 2
input "Please enter the Host's IP Address: ",AddressData$
print "Connecting to net session. Please Wait"
sync
set net connection TcpIpNumber, AddressData$
perform checklist for net sessions
NumberOfGames = CHECKLIST QUANTITY()
if NumberOfGames = 0
print "No session found at that address"
sync
wait key
end
endif
join net game 1, MyName$
print "Connected to Session!"
sync
endif
`Do the chat client
ChatClient()
end
`This function will determine which net connection number is
TCP/IP
function FindTCPIPConnectionNumber()
flag = 0
cls
perform checklist for net connections
for x = 1 to checklist quantity()
service$ = checklist string$(x)
if left$(service$,15)="Internet TCP/IP"
flag = x
endif
next x
endfunction flag
` This function does all the chat client functionality
function ChatClient()
` clears the chat text from the array
ClearChatText()
` Displays the initial players in the room

46
perform checklist for net players
NumberOfPlayers()=checklist quantity()
for x = 1 to NumberOfPlayers(1)
AddUserMessage(checklist string$(x))
next x
` send a coming in message
c$ = PlayersName$(1)+" has joined."
send net message string 0,c$
` displays the chat text
DisplayChatText()
` set the entry buffers
a$=""
b$=""
c$=""
clear entry buffer
`Capture text input and process it accordingly
while escapekey()=0
CheckIncomingMessages()
a$ = inkey$()
if asc(a$) = 8
c$ = c$+entry$()
c$=left$(c$,len(c$)-1)
clear entry buffer
cls
DisplayChatText()
endif
b$ = c$ + entry$()
text 10, 460, b$
if returnkey()=1 and b$<>""
sleep 250
` send remote message
d$=PlayersName$(1)+": "+b$
send net message string 0, d$
` display local message
AddStringToChat(d$)
d$=""
b$=""
c$=""
clear entry buffer
` display new chat window
DisplayChatText()
endif
sync
endwhile
endfunction
` scans the incoming messages for strings
` and displays them
function CheckIncomingMessages()
get net message
if net message exists()=0 then exitfunction
while net message exists()<>0
MsgType = net message type()
if MsgType = 3
Msg$ = net message string$()
AddStringToChat(Msg$)
DisplayChatText()
endif

47
get net message
endwhile
endfunction
` message to display if a user has joined
function AddUserMessage(Name$)
NewString$=Name$+" is here."
AddStringToChat(NewString$)
endfunction
` adds a string to the ChatText$ array
function AddStringToChat(a$)
for x = 1 to 32
if ChatText$(x)=""
ChatText$(x)=a$
exitfunction
endif
next x
ChatText$(32)=a$
endfunction
`Clears the ChatText$ Variables
function ClearChatText()
for x = 1 to 32
ChatText$(x)=""
next x
endfunction
` displays the chat text on the screen
function DisplayChatText()
cls
set current bitmap 0
center text 320,10,"Chat Client"
for x = 1 to 32
text 10,10+(x*15),ChatText$(x)
next x
endfunction

Program works well. To run it you have to open two sessions. Open the Server
session first and then run a second instance of the program and open a Client
session. (509)
Multiplayer games are more complex than this of course but the bones are there.
In every case the way things work is by passing data. Once the data is received
the receiving program uses it to do some rendering. In the chat program it was
displaying the text. In more complex games it would involve modification of
the graphics, sounds and other game elements.
Getting the Number and Names of Players something you need to do is
done with the PERFORM CHECKLIST FOR NET PLAYERS which fills the
checklist with the names and numbers of players when it is called. Various
information is provided:
CHECKLIST STRING$(PlayerNumber) returns player name for the number
CHECKLIST VALUE A(PlayerNumber) contains a unique ID for duration of
the game but not the same on all the computers in the game
CHECKLIST VALUE B(PlayerNumber) contains a special universal ID which
will be the same on all the computers in the game
CHECKLIST VALUE C(PlayerNumber) returns 1 if the player is you

48
CHECKLIST VALUE D(PlayerNumber) returns 1 if the player is the host of
the game
Sending Information is done using commands with the following form:
SEND NET MESSAGE TYPE PlayerNumber, Value this command sends a
packet of data. DarkBASIC refers to these as Net Messages. A table on page
510 lists all the message types. Player Number is the player that receives the
data. Set to 0 means it goes to everyone but the originator. The TYPE can be
(INTEGER, FLOAT, STRING, MEMBLOCK, BITMAP, IMAGE, SOUND,
MESH) see page 510. The last five have an associated flag parameter if
set to 1 it guarantees that the data will reach the other computer, otherwise DB
may drop the packet.
Read pages 511 through 517 to complete this chapter. They cover reading net
messages and handling memory blocks.
CHAPTER 23 Battle Checkers (519) You might want to load and play this
game and explore the code to see how the game works. I'll leave you to do that
on your own. These notes represent my own effort to familiarize myself with
the book. I hand typed in every bit of the code in the book that is here and I
debugged it when I'd made mistakes and I ran it and I looked it over to make
sure I understood it. You have to do a lot of that kind of thing to get to know
how programming languages and programs work. There is no short cut. It's a
lot of sticktoitiveness you have to tough it out sometimes and sometimes it
isn't very easy. A few times I made errors entering the code that were very
difficult to find. Generally the syntax aware editor that comes with
DarkBASIC was very helpful.
I hope these notes are helpful to you. I figure since I prepared them I might as
well make them available.
Ray Schneider
rschneid@bridgewater.edu
5/17/2007

You might also like