Tutorial: How to write games part 2

Go to page << 1 2 3 4 5 6 7 8 9 10 11 >>

Shooting back

There's still a few things missing from our game, and the most obvious is that the aliens don't shoot back So let's make them.

As usual we first need to stop and think about how the aliens are going to shoot back, and how that can be made into specific rules that we can enter into the computer.
The rules will be quite simple.

From this we can see that we will need arrays (because we will have multiple bullets).
We need to store the position of each bullet (we will use x and y array variables) on the screen.
The bullets won't always all be on the screen at once, so we also need to store which ones are on screen and which aren't.

So we will probably store them something like this:

const bombCount = 10
dim bombx (bombCount), bomby (bombCount), bombOnScreen (bombCount)

(I've called them "bombs" because they will fall down the screen, and because I can't be bothered typing "alienBullet" each time!)

Next we need to make the aliens drop bombs randomly each time they move.
We've said they will have a 1 in 10 chance each time. We can make this work by making picking a random number from 1 to 10 each time and then checking if it equals 1. If it does we drop the bomb.

In order to drop a bomb, we need to find one that isn't already on the screen. So we need to search through all the bombs for the first one where bombOnScreen (bombCount) is false. When we find one, we will place it on the screen where the alien is.
We need something like this (in the move alien loop):

if rnd () % 10 + 1 = 1 then
    for j = 1 to bombCount
        if not bombOnScreen (j) then
            bombOnScreen (j) = true
            bombx (j) = alienx (i) + 1
            bomby (j) = alieny (i)
            j = bombCount
        endif
    next
endif

We need the new variable j because we are already using i as the alien array index.
You may be wondering about the j = bombCount line at the end, after we have put a bomb on the screen. This simply tells the computer that we don't want to repeat the instructions in the for..next anymore (because we've already found our bomb and put it on the screen). Otherwise the computer would keep on looping through the remaining bombs and putting them all underneath the current alien! That's not what we want!

The next thing we need is some code to draw the bombs on the screen.
We will put this just after the code that draws the player bullet:

color (175, 175, 175)
for i = 1 to bombCount
    if bombOnScreen (i) then
        locate bombx (i), bomby (i): print "O"
    endif
next

Here's what the program currently looks like:

const alienCount = 10
const bombCount = 10
dim score, lives, turretx
dim alienx (alienCount), alieny (alienCount), alienOnScreen (alienCount)
dim bulletx, bullety, bulletOnScreen, i, j
dim bombx (bombCount), bomby (bombCount), bombOnScreen (bombCount)
lives = 3
turretx = 19
for i = 1 to alienCount
    alienx(i) = rnd () % 37
    alieny(i) = rnd () % 22 + 1
    alienOnScreen(i) = true
next
bulletOnScreen = false

TextMode (TEXT_BUFFERED)
while true
    if ScanKeyDown (VK_LEFT) and turretx > 0 then
        turretx = turretx - 1
    endif
    if ScanKeyDown (VK_RIGHT) and turretx < 37 then 
        turretx = turretx + 1
    endif
    for i = 1 to alienCount
        if alienOnScreen (i) then 
            alienx (i) = alienx (i) + 1
            if alienx (i) > 37 then
                alienx (i) = 0
                alieny (i) = rnd () % 22 + 1
            endif
            if rnd () % 10 + 1 = 1 then
                for j = 1 to bombCount
                    if not bombOnScreen (j) then
                        bombOnScreen (j) = true
                        bombx (j) = alienx (i) + 1
                        bomby (j) = alieny (i)
                        j = bombCount
                    endif
                next
            endif
        endif
    next
    if bulletOnScreen then 
        bullety = bullety - 1
        if bullety < 1 then 
            bulletOnScreen = false
        endif
    else
        if ScanKeyDown (VK_SPACE) then
            bulletOnScreen = true
            bullety = 22
            bulletx = turretx + 1
        endif
    endif
        
    cls
    color (255, 255, 255)
    locate 0, 0: print "Score=" + score
    locate 30, 0: print "Lives=" + lives
    color (255, 50, 50)
    for i = 1 to alienCount
        if alienOnScreen (i) then
            locate alienx (i), alieny (i): print ">O<"
        endif
    next
    color (150, 150, 150)
    locate turretx, 23: print "<!>"
    if bulletOnScreen then
        color (255, 255, 50)
        locate bulletx, bullety: print "!"
    endif 
    color (175, 175, 175)
    for i = 1 to bombCount
        if bombOnScreen (i) then
            locate bombx (i), bomby (i): print "O"
        endif
    next        
    if bulletOnScreen then
        for i = 1 to alienCount
            if alienOnScreen (i) then
                if bullety = alieny (i) and bulletx >= alienx (i) and bulletx <= alienx (i) + 2 then
                    alienOnScreen (i) = false
                    bulletOnScreen = false
                    score = score + 100
                endif
            endif
        next
    endif
    DrawText ()
    Sleep (75)
wend

(Don't forget to add the j to the dim instruction at the top!)

You can see that the program actually runs, and that the aliens do make bombs.
We just need to make them fall down the screen, like this:

for i = 1 to bombCount
    if bombOnScreen (i) then
        bomby (i) = bomby (i) + 1
        if bomby (i) > 23 then
            bombOnScreen (i) = false
        endif
    endif
next

So the bomby (i) = bomby (i) is there to move the bombs down the screen.
The if bomby (i) > 23 then will check if the bomb has fallen off the bottom of the screen, and if so the bombOnScreen (i) = false will take it off the screen (so it's ready to be dropped again by another alien).

We can place this code after the code that moves the aliens. Like this:

const alienCount = 10
const bombCount = 10
dim score, lives, turretx
dim alienx (alienCount), alieny (alienCount), alienOnScreen (alienCount)
dim bulletx, bullety, bulletOnScreen, i, j
dim bombx (bombCount), bomby (bombCount), bombOnScreen (bombCount)
lives = 3
turretx = 19
for i = 1 to alienCount
    alienx(i) = rnd () % 37
    alieny(i) = rnd () % 22 + 1
    alienOnScreen(i) = true
next
bulletOnScreen = false

TextMode (TEXT_BUFFERED)
while true
    if ScanKeyDown (VK_LEFT) and turretx > 0 then
        turretx = turretx - 1
    endif
    if ScanKeyDown (VK_RIGHT) and turretx < 37 then 
        turretx = turretx + 1
    endif
    for i = 1 to alienCount
        if alienOnScreen (i) then 
            alienx (i) = alienx (i) + 1
            if alienx (i) > 37 then
                alienx (i) = 0
                alieny (i) = rnd () % 22 + 1
            endif
            if rnd () % 10 + 1 = 1 then
                for j = 1 to bombCount
                    if not bombOnScreen (j) then
                        bombOnScreen (j) = true
                        bombx (j) = alienx (i) + 1
                        bomby (j) = alieny (i)
                        j = bombCount
                    endif
                next
            endif
        endif
    next
    for i = 1 to bombCount
        if bombOnScreen (i) then
            bomby (i) = bomby (i) + 1
            if bomby (i) > 23 then
                bombOnScreen (i) = false
            endif
        endif
    next
    if bulletOnScreen then 
        bullety = bullety - 1
        if bullety < 1 then 
            bulletOnScreen = false
        endif
    else
        if ScanKeyDown (VK_SPACE) then
            bulletOnScreen = true
            bullety = 22
            bulletx = turretx + 1
        endif
    endif        
    cls
    color (255, 255, 255)
    locate 0, 0: print "Score=" + score
    locate 30, 0: print "Lives=" + lives
    color (255, 50, 50)
    for i = 1 to alienCount
        if alienOnScreen (i) then
            locate alienx (i), alieny (i): print ">O<"
        endif
    next
    color (150, 150, 150)
    locate turretx, 23: print "<!>"
    if bulletOnScreen then
        color (255, 255, 50)
        locate bulletx, bullety: print "!"
    endif 
    color (175, 175, 175)
    for i = 1 to bombCount
        if bombOnScreen (i) then
            locate bombx (i), bomby (i): print "O"
        endif
    next        
    if bulletOnScreen then
        for i = 1 to alienCount
            if alienOnScreen (i) then
                if bullety = alieny (i) and bulletx >= alienx (i) and bulletx <= alienx (i) + 2 then
                    alienOnScreen (i) = false
                    bulletOnScreen = false
                    score = score + 100
                endif
            endif
        next
    endif      
 
    DrawText ()
    Sleep (75)
wend

And the last step is to tell the computer how to check whether a bomb has hit the turret, and what to do if it has.
We want to:

We also want to remove all the bombs from the screen. This gives the player a chance to react when the game starts again.
We want to put this after we've drawn the rest of the screen.

So here's the final version.

const alienCount = 10
const bombCount = 10
dim score, lives, turretx
dim alienx (alienCount), alieny (alienCount), alienOnScreen (alienCount)
dim bulletx, bullety, bulletOnScreen, i, j
dim bombx (bombCount), bomby (bombCount), bombOnScreen (bombCount)
lives = 3
turretx = 19
for i = 1 to alienCount
    alienx(i) = rnd () % 37
    alieny(i) = rnd () % 22 + 1
    alienOnScreen(i) = true
next
bulletOnScreen = false

TextMode (TEXT_BUFFERED)
while true
    if ScanKeyDown (VK_LEFT) and turretx > 0 then
        turretx = turretx - 1
    endif
    if ScanKeyDown (VK_RIGHT) and turretx < 37 then 
        turretx = turretx + 1
    endif
    for i = 1 to alienCount
        if alienOnScreen (i) then 
            alienx (i) = alienx (i) + 1
            if alienx (i) > 37 then
                alienx (i) = 0
                alieny (i) = rnd () % 22 + 1
            endif
            if rnd () % 10 + 1 = 1 then
                for j = 1 to bombCount
                    if not bombOnScreen (j) then
                        bombOnScreen (j) = true
                        bombx (j) = alienx (i) + 1
                        bomby (j) = alieny (i)
                        j = bombCount
                    endif
                next
            endif
        endif
    next
    for i = 1 to bombCount
        if bombOnScreen (i) then
            bomby (i) = bomby (i) + 1
            if bomby (i) > 23 then
                bombOnScreen (i) = false
            endif
        endif
    next
    if bulletOnScreen then 
        bullety = bullety - 1
        if bullety < 1 then 
            bulletOnScreen = false
        endif
    else
        if ScanKeyDown (VK_SPACE) then
            bulletOnScreen = true
            bullety = 22
            bulletx = turretx + 1
        endif
    endif        
    cls
    color (255, 255, 255)
    locate 0, 0: print "Score=" + score
    locate 30, 0: print "Lives=" + lives
    color (255, 50, 50)
    for i = 1 to alienCount
        if alienOnScreen (i) then
            locate alienx (i), alieny (i): print ">O<"
        endif
    next
    color (150, 150, 150)
    locate turretx, 23: print "<!>"
    if bulletOnScreen then
        color (255, 255, 50)
        locate bulletx, bullety: print "!"
    endif 
    color (175, 175, 175)
    for i = 1 to bombCount
        if bombOnScreen (i) then
            locate bombx (i), bomby (i): print "O"
        endif
    next        
    if bulletOnScreen then
        for i = 1 to alienCount
            if alienOnScreen (i) then
                if bullety = alieny (i) and bulletx >= alienx (i) and bulletx <= alienx (i) + 2 then
                    alienOnScreen (i) = false
                    bulletOnScreen = false
                    score = score + 100
                endif
            endif
        next
    endif
    for i = 1 to bombCount
        if bombOnScreen (i) and bomby (i) = 23 and bombx (i) >= turretx and bombx (i) <= turretx + 2 then
            color (255, 255, 0)
            for j = 1 to 10
                locate turretx, 23: print "\\\"
                DrawText ()
                Sleep (75)
                locate turretx, 23: print "///"
                DrawText ()
                Sleep (75)
            next
            turretx = 19
            lives = lives - 1
            if lives = 0 then
                color (255, 255, 255)
                locate 15, 12: print "Game Over!"
                DrawText ()
                end
            endif
            for j = 1 to bombCount
                bombOnScreen (j) = false
            next
        endif
    next 
    DrawText ()
    Sleep (75)
wend
Go to page << 1 2 3 4 5 6 7 8 9 10 11 >>