Let's see what help I can provide. *Cracks Knuckles*
First off, let's talk about
indentation. Indentation is when you press "tab" to move sections of code further to the right. There are rules you need to follow in order to do correct indentation. It's very simple: Every command that has a "partner" to it will trigger an indentation. Examples of these commands are:
if...endif
do...loop
repeat...until
for...next
open to read...close file
lock vertexdata for limb...unlock vertexdata
And an example with correct indentation:
a = 1
b = 3
if a = 1
if b = 3
for t = 1 to 5
print "I live in a giant bucket"
next t
endif
endif
Why does this help? Imagine you forgot to use an "endif" somewhere in your huge amount of code. All the compiler will do is say "GAY! NESTING ERROR AT LINE <insert garbage number here>!!" and jump to a line that has nothing to do with the actual error. If you indented correctly, you will easily be able to see where you have an indentation too much, or too little. That's one of the major reasons why it's useful, the other reason is that it's so much easier to read because it reflects the logic.
Absolute and Relative File Names
This is an absolute file name.
load image "C:\Program Files (x86)\The Game Creators\Dark Basic Pro Free\Dark Basic Pro\Projects\Unit 22 Game\background.png",1
This is a relative file name.
load image "background.png",1
How does this help? The most important thing is that your program, when using absolute file names, will only run if you have placed it in the folder "C:\Program Files (x86)\The Game Creators\Dark Basic Pro FRee\Dark Basic Pro\Projects\Unit 22 Game\". Well that isn't useful if you want to give it to people who want to play it, right? That's where relative file names become useful. If the executable program is in the same directory as the image, you only need to use:
load image "background.png" , 1
If you decide to make a directory in that folder called "images" and place your image in there, you just change it to:
load image "images\background.png" , 1
It's as simple as that.
Comments
As some guy I can't remember the name of once said,
"Good comments are half the code". This is both literally and ideologically true, as you do write much more, but if you leave a program for 6 months and return to it, you'll praise the lord and kiss Adam's apple like a bag of potato chips (I have no idea where this metaphor is going) for having written comments. A non-commented program is a programmer's worst nightmare because you easily forget why you did something in a particular way. Comments will help you remember. There are many ways to make comments in DBP, the standard BASIC syntax is the keyword "rem". But you can use these as well:
rem this is a comment
// this is a comment
` this is a comment
You don't necesseraly have to write comments for every single line of code, but try to group your code and explain as much as possible. Here's an example of good grouping:
rem load the player object
load object "GANGMANSTYLE.x" , 1
position object 1 , 0 , 0 , 0
rotate object 1, 0 , 90 , 0
texture object 1 , 3
set object effect 1 , 1
rem let the user know that he will have no hope with this program
print "You. User."
print "A pile of camel's diarrhea is going to be more successful"
print "than this game."
See how there isn't a comment before every command, but there is a comment explaining what each section does.
Arrays
Said to be one of the scariest types of variables in existance, but they are vital if you want to have more than one of the same thing in your program (such as more than 1 asteroid). This is why you must understand the concept of an array. Here's an example of how to define and fill an array:
rem define our array
dim MyArray$(5) as string
rem fill the array with useless garbage (also known as RAM abuse)
MyArray$(0) = "My dog ate a sausage"
MyArray$(1) = "Donuts are my best friend"
MyArray$(2) = "Beware, for I know kung-fu, Ninjitsu, and other Japanese words!"
MyArray$(3) = "Today I ate food."
MyArray$(4) = "Why do I always talk about food..."
MyArray$(5) = "I suppose it reflects the current state of my stomach"
So let's print that to the screen:
print MyArray$(0)
print MyArray$(1)
print MyArray$(2)
print MyArray$(3)
print MyArray$(4)
print MyArray$(5)
Well that was a waste of coding space... Here's where arrays get cool. You can compress the latter by doing this:
for t = 0 to 5
print MyArray$(t)
next t
Arrays don't have to be strings, they can be floats, integers, bytes, booleans, words... Anything a normal variable can be.
User Defined Types
These help structure and group together variables that have things in common. If you wanted to create a player UDT (user defined type), this is how you'd do it:
rem declare player structure
type PlayerVT
PositionX as integer
PositionY as integer
Dead as integer
Shooting as integer
endtype
rem define player
global Player as PlayerVT
rem now we can change the player's values:
Player.PositionX = 1
Player.PositionY = 4
Player.Dead = 0
Player.Shooting = 1
See how all of the elements between the "type...endtype" commands can now be used inside the player variable? This is really cool because it's really easy to add variables just to the player later on, and it keeps all of your variables really structured.
Oh and if you're wondering what the "VT" stands for, it's a habit of mine so I know that it's a type and will be used for a variable, hence "
Variable
Type". If it were for an array, I'd use "AT" for "
Array
Type".
Comet, will you shut up already and get to my code?!
Since you asked so nicely, of course!
Let's first get your player moving around at the bottom of the screen. First off, let's get a basic program structure down, declare the player type and define a player variable:
rem ----------------------------------------------
rem starting stuff
rem ----------------------------------------------
set display mode 640, 480, 32
cls rgb(0,0,0)
ink rgb(255,255,255),0
set text size 80
center text 320, 240, "Space Defense!"
wait key
rem ----------------------------------------------
rem set up screen
rem ----------------------------------------------
rem Sync on and backdrop on so we have control of the drawing
sync on
sync rate 60
backdrop on
color backdrop 0
rem ----------------------------------------------
rem User defined types
rem ----------------------------------------------
rem vector 2 (makes positions easier to handle later on)
type vec2
x as integer
y as integer
endtype
rem declare player structure
type PlayerVT
state as integer
position as vec2
endtype
rem ----------------------------------------------
rem Global variables
rem ----------------------------------------------
global Player as PlayerVT
rem ----------------------------------------------
rem Load images here
rem ----------------------------------------------
load image "player.png" , 1
rem ----------------------------------------------
rem main loop
rem ----------------------------------------------
rem start of main loop
do
rem refresh screen
sync
rem end of main loop
loop
rem ----------------------------------------------
rem Functions
rem ----------------------------------------------
Alright, now we move the player! For this we create a function which controls the player:
function ControlPlayer()
rem player is alive and well
if Player.state = 0
rem move the player with the arrow keys
if leftkey() then dec Player.pos.x
if rightkey() then inc Player.pos.x
rem make sure player doesn't go off screen
if Player.pos.x < 0 then Player.pos.x = 0
if Player.pos.x > screen width() - image width(1) then Player.pos.x = screen width() - image width(1)
rem y position of player is constant, could be changed if you want though!
Player.pos.y = screen height() - image height(1)
endif
endfunction
Insert that into the program:
rem ----------------------------------------------
rem starting stuff
rem ----------------------------------------------
set display mode 640, 480, 32
cls rgb(0,0,0)
ink rgb(255,255,255),0
set text size 80
center text 320, 240, "Space Defense!"
wait key
rem ----------------------------------------------
rem set up screen
rem ----------------------------------------------
rem Sync on and backdrop on so we have control of the drawing
sync on
sync rate 60
backdrop on
color backdrop 0
rem ----------------------------------------------
rem User defined types
rem ----------------------------------------------
rem vector 2 (makes positions easier to handle later on)
type vec2
x as integer
y as integer
endtype
rem declare player structure
type PlayerVT
state as integer
position as vec2
endtype
rem ----------------------------------------------
rem Global variables
rem ----------------------------------------------
global Player as PlayerVT
rem ----------------------------------------------
rem Load images here
rem ----------------------------------------------
load image "player.png" , 1
rem ----------------------------------------------
rem main loop
rem ----------------------------------------------
rem start of main loop
do
rem control all game elements
ControlPlayer()
rem refresh screen
sync
rem end of main loop
loop
rem ----------------------------------------------
rem Functions
rem ----------------------------------------------
function ControlPlayer()
rem player is alive and well
if Player.state = 0
rem move the player with the arrow keys
if leftkey() then dec Player.pos.x
if rightkey() then inc Player.pos.x
rem make sure player doesn't go off screen
if Player.pos.x < 0 then Player.pos.x = 0
if Player.pos.x > screen width() - image width(1) then Player.pos.x = screen width() - image width(1)
rem y position of player is constant, could be changed if you want though!
Player.pos.y = screen height() - image height(1)
rem control the player
paste image 1 , Player.pos.x , Player.pos.y
endif
endfunction
Wow, it moves! Alright, what's next? Asteroids that spawn at the top of the screen and despawn at the bottom. This is where we will use the full power of our knowledge and use... ARRAYS!!
The same procedure. Declare the asteroid type, define the asteroid array.
rem how many asteroids do you want at most?
#constant MaxAsteroids 50
rem asteroid type
type AsteroidAT
Active as integer
pos as vec2
endtype
global dim Asteroid( MaxAsteroids ) as AsteroidAT
Awesome. Now here is where it get's a bit complicated, but cope with me. We are going to create a spawn and despawn function for the asteroids. Here's the spawn function:
function CreateAsteroid( x , y )
rem local variables
local n as integer
rem find an asteroid currently not in use
for n = 0 to MaxAsteroids
if Asteroid( n ).Active = 0 then exit
next n
rem if no free slot was found, don't create asteroid
if n = MaxAsteroids + 1 then exitfunction
rem if free slot was found, activate!
Asteroid( n ).Active = 1
Asteroid( n ).pos.x = x
Asteroid( n ).pos.y = y
endfunction
And here we have the despawn function:
function DestroyAsteroid( n )
rem deactivate!
Asteroid( n ).Active = 0
endfunction
Alright, now we just need to control the asteroids. For this, we'll add a control function just like we did with the player.
function ControlAsteroids()
rem local variables
local n as integer
rem loop through all active asteroids
for n = 0 to MaxAsteroids
if Asteroid( n ).Active = 1
rem move the asteroid down (speed 2)
inc Asteroid( n ).pos.y , 2
rem if the asteroid reaches the bottom of the screen, destroy
if Asteroid( n ).pos.y > screen height() then DestroyAsteroid( n )
rem draw the asteroid to the screen
paste image 2 , Asteroid( n ).pos.x , Asteroid( n ).pos.y
endif
next n
endfunction
Awesomeness! Now add it to the main program. I also added one line to spawn asteroids randomly in the main loop just to demonstrate.
rem ----------------------------------------------
rem starting stuff
rem ----------------------------------------------
set display mode 640, 480, 32
cls rgb(0,0,0)
ink rgb(255,255,255),0
set text size 80
center text 320, 240, "Space Defense!"
wait key
rem ----------------------------------------------
rem set up screen
rem ----------------------------------------------
rem Sync on and backdrop on so we have control of the drawing
sync on
sync rate 60
backdrop on
color backdrop 0
rem ----------------------------------------------
rem User defined types
rem ----------------------------------------------
rem how many asteroids do you want at most?
#constant MaxAsteroids 50
rem asteroid type
type AsteroidAT
Active as integer
pos as vec2
endtype
rem vector 2 (makes positions easier to handle later on)
type vec2
x as integer
y as integer
endtype
rem declare player structure
type PlayerVT
state as integer
position as vec2
endtype
rem ----------------------------------------------
rem Global variables
rem ----------------------------------------------
global Player as PlayerVT
global dim Asteroid( MaxAsteroids ) as AsteroidAT
rem ----------------------------------------------
rem Load images here
rem ----------------------------------------------
load image "player.png" , 1
load image "asteroid.png" , 2
rem ----------------------------------------------
rem main loop
rem ----------------------------------------------
rem start of main loop
do
rem spawn asteroids randomly
if rnd(50) = 0
CreateAsteroid( rnd(screen width()) , 0 - image height(2) )
endif
rem control all game elements
ControlPlayer()
ControlAsteroids()
rem refresh screen
sync
rem end of main loop
loop
rem ----------------------------------------------
rem Functions
rem ----------------------------------------------
function ControlPlayer()
rem player is alive and well
if Player.state = 0
rem move the player with the arrow keys
if leftkey() then dec Player.pos.x
if rightkey() then inc Player.pos.x
rem make sure player doesn't go off screen
if Player.pos.x < 0 then Player.pos.x = 0
if Player.pos.x > screen width() - image width(1) then Player.pos.x = screen width() - image width(1)
rem y position of player is constant, could be changed if you want though!
Player.pos.y = screen height() - image height(1)
rem control the player
paste image 1 , Player.pos.x , Player.pos.y
endif
endfunction
function CreateAsteroid( x , y )
rem local variables
local n as integer
rem find an asteroid currently not in use
for n = 0 to MaxAsteroids
if Asteroid( n ).Active = 0 then exit
next n
rem if no free slot was found, don't create asteroid
if n = MaxAsteroids + 1 then exitfunction
rem if free slot was found, activate!
Asteroid( n ).Active = 1
Asteroid( n ).pos.x = x
Asteroid( n ).pos.y = y
endfunction
function DestroyAsteroid( n )
rem deactivate!
Asteroid( n ).Active = 0
endfunction
function ControlAsteroids()
rem local variables
local n as integer
rem loop through all active asteroids
for n = 0 to MaxAsteroids
if Asteroid( n ).Active = 1
rem move the asteroid down (speed 2)
inc Asteroid( n ).pos.y , 2
rem if the asteroid reaches the bottom of the screen, destroy
if Asteroid( n ).pos.y > screen height() then DestroyAsteroid( n )
rem draw the asteroid to the screen
paste image 2 , Asteroid( n ).pos.x , Asteroid( n ).pos.y
endif
next n
endfunction
Phew, that's a lot of code. BTW, I actually can't guarantee that it will run, because I wrote this off the top of my head. The theory works though, you just might find an odd error here or there.
I'll stop here with this tutorial. I suggest you play around with the code, get to understand it etc. When you feel safe, try adding bullets next. When you make bullets, do exactly the same thing as we did with the asteroids. Create CreateBullet(), DestroyBullet(), ControlBullet() functions. This way of coding is very structured, and you can't go wrong.
Collision is pretty simple then, just check if an asteroid is near a bullet in the ControlBullet() function, if so, destroy the asteroid and the bullet.
I hope this helped!
TheComet
"Why geeks like computers: unzip, strip, touch, finger, grep, mount, fsck, more, yes, fsck, fsck, fsck, umount, sleep." - Unknown