TGC Codebase Backup



Night by malcolm

1st Mar 2004 8:00
Summary

I HAVE USED Martijn van Sliedregt SOURCE CODE Night-Forest Hunter



Description

I HAVE USED Martijn van Sliedregt SOURCE CODE Night-Forest Hunter
WHICH IS A GREAT PROGRAM TO SHOW YOU HOW TO WRITE A 2D GAME IN 3D
HAVE HAVE CHANGE SOME PARTS BUT MOST OF THE CODE WAS WRITEN BY martijn van Sliedregt
WHICH YOU WILL NEED TO RUN THIS PROGRAM

WHAT I DID TO THE SOUCE CODE
I HAVE CONVERTED IT TO RUN ON DB PRO
I CONVERTED THE SOURCE CODE TO THE WAY I PROGRAM
WHICH IS TO USE GOSUBS

WHEN YOU SHOT THE ENEMY THEY WILL NOW RESPAWN
WHEN YOU WALK OFF THE MAP YOU WILL BE PLACED ON THE OTHER SIDE OF THE MAP



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    rem Night-Forest Shooter
rem 500-lines game/tutorial.
rem Martijn van Sliedregt, zodsteels@yahoo.com (artwork and music/sounds are free to use)

REM I HAVE USED Martijn van Sliedregt SOURCE CODE Night-Forest Hunter
REM WHICH IS A GREAT PROGRAM TO SHOW YOU HOW TO WRITE A 2D GAME IN 3D
REM HAVE HAVE CHANGE SOME PARTS BUT MOST OF THE CODE WAS WRITEN BY martijn van Sliedregt
REM WHICH YOU WILL NEED TO RUN THIS PROGRAM

REM WHAT I DID TO THE SOUCE CODE
REM I HAVE CONVERTED IT TO RUN ON DB PRO
REM WHEN YOU SHOT THE ENEMY THEY WILL NOW RESPAWN
REM WHEN YOU WALK OFF THE MAP YOU WILL BE PLACED ON THE OTHER SIDE OF THE MAP
REM I CONVERTED THE SOURCE CODE TO THE WAY I PROGRAM
REM WHICH IS TO USE GOSUBS
REM TO SEE ALL THE MAP IN GAME PRESS THE RETURN KEY
REM THIS IS FOR DEBUGING

rem First we check the display modes, the higher, the better
rem so we use  CHECK DISPLAY MODE  to search for the optimal
rem resolution. We will not use a "chose" screen, but remember
rem to make on if you are planning to release your game (LCD|FLAT|TFT monitors
rem use "optimal" resolutions instead of maximum, and it can mess up the graphics)

displayflag=0
if check display mode(1280,1024,32)=1 and displayflag=0
   set display mode 1280,1024,32
   displayflag=1
endif

if check display mode(1024,768,32)=1 and displayflag=0
   set display mode 1024,768,32
   displayflag=1
endif

if check display mode(800,600,32)=1 and displayflag=0
   set display mode 800,600,32
   displayflag=1
endif

if check display mode(640,480,32)=1 and displayflag=0
   set display mode 640,480,32
   displayflag=1
endif

SET AMBIENT LIGHT 50
SET IMAGE COLORKEY 0,0,0
hide mouse
randomize timer()

rem This is important for a fast game, it sets the maximum refreshing
rem to 60 FPS
sync on
sync rate 60

rem Lets setup the arrays and variables
rem For the enemies
dim ai_status(256,2)

rem For the items
dim item_slot(5)
dim item_stat(500)

item_slot(1)=23
item_slot(2)=21
item_slot(3)=21
item_slot(4)=21
item_slot(5)=21

rem For the player and gun
health# = 100
bullets = 10
selection = 1

rem object numbers
`player = 1
`image of player on panel =2
`floor object =10
enemystart=20
enemyend=80
bulletnumber=100
bulletflash=101
treestart=102
treeend=200
pickupstart=300
pickupend=330
`Selection box 500 - 505

rem We'll make the backdrop black
color backdrop 0
set text size 32

rem load all objects
gosub setuplevel

rem Lovely music
load music "mediasounds8.mid", 1
rem Repeat the midi
loop music 1

rem the main game loop
repeat

   rem check what to do with players
   gosub checkkeys

   rem enemy ai
   gosub ai

   rem object that you can pick up
   gosub pickupobjects:

   rem update players position and object icons
   gosub positionmainplayer

   rem Draw everything
   sync

rem Bingo, the end :)
until game_over=1

rem I hope this tutorial helped you (or will help you). Im dutch and my english isnt super. If you have questions or suggestions
rem then email me. Zodsteels@Yahoo.com  -or-  GOTO http://darkbasic.thegamecreators.com/?m=forum
gosub gameover
end

positionmainplayer:
rem Put the camera above the player, dont worry, we are allmost at the end :)
if returnkey()=0
   position camera object position x(1),60,object position z(1)
else
   rem debug only
   position camera object position x(1),1200,object position z(1)
endif

point camera object position x(1),0,object position z(1)

rem Lets help the player, shall we. We will display the text near the face so he knows how many HP and BULLETS he has.
text screen width()/2+70,screen height()-80,"BULLETS: "+str$(bullets)
text screen width()/2+70,screen height()-40,"HEALTH:  "+str$(health#)+"%"
rem Put the icons at the right place, these are the item_slots
rem The selection box
position object 500,(object position x(1)-45)+(selection*7.5),5.01,object position z(1)-30
rem The slots
position object 501,object position x(1)-37.5,5,object position z(1)-30
position object 502,object position x(1)-30,5,object position z(1)-30
position object 503,object position x(1)-22.5,5,object position z(1)-30
position object 504,object position x(1)-15,5,object position z(1)-30
position object 505,object position x(1)-7.5,5,object position z(1)-30

rem The player's face
position object 2,object position x(1),5,object position z(1)-30
return

pickupobjects:
rem Easy ey?
if health#<=0.0 then game_over=1
rem For the items on the floor
for a=pickupstart to pickupend
rem If an item is picked up, its deleted, so checking if it exists is crucial for no errors.
if object exist(a)=1
rem Pytha's way again :)
distance#=sqrt((object position x(1)-object position x(a))^2+(object position z(1)-object position z(a))^2)
 if distance#<5
  rem Okay, now we will look for an empty item_slot, if they are all full the item remains on the floor.
  if item_slot(1)=21
     item_slot(1)=item_stat(a)
     delete object a
     for a=501 to 505
       texture object a,item_slot(a-500)
     next a
  else
   if item_slot(2)=21
      item_slot(2)=item_stat(a)
      delete object a
      for a=501 to 505
        texture object a,item_slot(a-500)
      next a
   else
    if item_slot(3)=21
       item_slot(3)=item_stat(a)
       delete object a
       for a=501 to 505
         texture object a,item_slot(a-500)
       next a
    else
     if item_slot(4)=21
        item_slot(4)=item_stat(a)
        delete object a
        for a=501 to 505
          texture object a,item_slot(a-500)
        next a
     else
        if item_slot(5)=21
         item_slot(5)=item_stat(a)
         delete object a
         for a=501 to 505
           texture object a,item_slot(a-500)
         next a
        endif
     endif
    endif
   endif
  endif
 endif
endif
next a
return

ai:
rem AI
for a=enemystart to enemyend
 rem Important, this means he's idle and not dead
 if ai_status(a,1)=1
      rem Rotate them, ATANFULL is our biggest friend :)
      dx#=object position x(1)-object position x(a)
      dy#=object position z(1)-object position z(a)
      angle#=atanfull(dx#,dy#)

      rem rotation enemy towards player
      yrotate object a,angle#

      rem Check for distance, using Pytha's way :), if the enemy is closer than 50 units it will attack the player
      if sqrt((dx#^2)+(dy#^2))<50 and ai_status(a)=0 then ai_status(a,0)=1

      rem If its closer than 2 units (ouch) it will attack the player
      if sqrt((dx#^2)+(dy#^2))<2
       dec health#
       if sound playing(11)=0 then play sound 11

       rem Update the face of the player
       if health#<25
          load image "mediaplayerface_04.bmp",6,1
          texture object 2,6
       else
         if health#<50
             load image "mediaplayerface_03.bmp", 6,1
             texture object 2,6
         else
           if health#<75
             load image "mediaplayerface_02.bmp", 6,1
             texture object 2,6
           endif
         endif
       endif
      endif

      rem Scare the player using the PSYCHO sound
      if ai_status(a,0)=1
         play sound 3
         ai_status(a,0)=2
      endif

      rem Move the enemy
      if ai_status(a,0)=2
         rem Oh my, look how fast you are!
         x#=object position x(a)
         y#=object position y(a)
         z#=object position z(a)
         x1#=newxvalue(x#,object angle y(a),0.5)
         z1#=newzvalue(z#,object angle y(a),0.5)
         position object a,x1#,y#,z1#
      endif

      rem Bullet Collision, Pytha's way again :)
      dx#=object position x(bulletnumber)-object position x(a)
      dy#=object position z(bulletnumber)-object position z(a)
      rem He's been hit if this is true
      if sqrt((dx#^2)+(dy#^2))<4 and object position y(bulletnumber)<>-2
         rem He's dead, so we set its variables in the array to 0 (non-active in this game)
         ai_status(a,0)=0 : ai_status(a,1)=0
         rem Give it the dead-body texture
         texture object a,4
         bullet_flag=0
         hide object bulletnumber
         play sound 4
         position object a,object position x(a),0,object position z(a)
      endif
 else
    rem respawn enemy
    rem is the enemy off screen
    if OBJECT IN SCREEN(a)=0
      rem bring him back form the dead
       ai_status(a,1)=1
       texture object a,3
       rem place him on the map
       repeat
             position object a,rnd(600)-300,1,rnd(600)-300
       until abs(getdistance(1,a))>50
    endif
 endif
next a
return

checkkeys:
rem keys have been changed
rem movement keys
`UP=W
`DOWN=S
`ROTATE LEFT=A
`ROTATE RIGHT=D
`SLIDE LEFT = Q
`SLIDE RIGHT = E
`CURSOR KEYS ASWELL

rem PICK AND USE OBJECTS
`< = MOVE DOWN ITEM LIST
`> = MOVE UP ITEM LIST
`? = USE OBJECT

REM FIRE GUN AND RELOAD
`LEFT MOUSE BUTTON = FIRE
`RIGHT MOUSE BUTTON = USE CURRENT OBJECT

x#=object position x(1)
y#=object position y(1)
z#=object position z(1)
oldx#=x#
oldz#=z#

rem Player rotation, when the leftkey | rightkey | A | D | is pressed the player will rotate 2 degrees
if scancode()=30 then yrotate object 1,wrapvalue(object angle y(1)-2.0)
if scancode()=32 then yrotate object 1,wrapvalue(object angle y(1)+2.0)

rem Moving the player
rem up
if scancode()=17
   x#=newxvalue(x#,object angle y(1),0.5)
   z#=newzvalue(z#,object angle y(1),0.5)
endif
rem down
if scancode()=31
   x#=newxvalue(x#,wrapvalue(object angle y(1)+180),0.5)
   z#=newzvalue(z#,wrapvalue(object angle y(1)+180),0.5)
endif
rem slide left
if scancode()=16
   x#=newxvalue(x#,wrapvalue(object angle y(1)-90),0.5)
   z#=newzvalue(z#,wrapvalue(object angle y(1)-90),0.5)
endif
rem slide right
if scancode()=18
   x#=newxvalue(x#,wrapvalue(object angle y(1)+90),0.5)
   z#=newzvalue(z#,wrapvalue(object angle y(1)+90),0.5)
endif

rem check if we are moving to the left of the screen
if x#<oldx#
   rem have you walk of map
   if x#<-400.0
      rem make number a + number
      x#=(x#*-1)
      rem find out are far past 400 object is
      ncb#=400.0-x#
      rem place object on other side of map
      x#=500.0+ncb#
      oldx#=x#
   endif
endif

rem check if we are moving to the right of the screen
if x#>oldx#
   rem have you walk of map
   if x#>400.0
      rem find out are far past 400 object is
      ncb#=400.0-x#
      rem place object on other side of map
      x#=(500.0+ncb#)*-1
      oldx#=x#
   endif
endif

rem check if we are moving to the up of the screen
if z#<oldz#
   rem have you walk of map
   if z#<-400.0
      rem make number a + number
      z#=(z#*-1)
      rem find out are far past 400 object is
      ncb#=400.0-z#
      rem place object on other side of map
      z#=500.0+ncb#
      oldz#=z#
   endif
endif

rem check if we are moving to the down of the screen
if z#>oldz#
   rem have you walk of map
   if z#>400.0
      rem find out are far past 400 object is
      ncb#=400.0-z#
      rem place object on other side of map
      z#=(500.0+ncb#)*-1
      oldz#=z#
   endif
endif

rem position player
position object 1,x#,y#,z#

rem Selection, when the < > keys is pressed, the selection box will go to another item_slot, selection_flag is used to
rem delay this command. Without it, it would be impossible to select something (super-fast)
if scancode()=51 and selection_flag=0
   dec selection
   selection_flag=10
   if selection = 0 then selection = 5
endif
if scancode()=52 and selection_flag=0
   inc selection
   selection_flag=10
   if selection = 6 then selection = 1
endif

rem Use item, when the ? key is pressed, it will check:
rem If the item_slot contains an item, sorry, no cheating ;)
if scancode()=53 or mouseclick()=2 and selection_flag=0

 rem Item_slot contains a healthkit
 if item_slot(selection)=22 then health#=100.0 : play sound 13
 rem Item_slot contains a ammo box
 if item_slot(selection)=23 then bullets=10 : play sound 12

 rem Make it empty
 item_slot(selection)=21

 rem Re-texture the item_slots
  for a=501 to 505
      texture object a,item_slot(a-500)
  next a
  selection_flag=10
  if health#<=25 then load image "mediaplayerface_04.bmp",6,1:texture object 2,6
  if health#<=50 then load image "mediaplayerface_03.bmp", 6,1:texture object 2,6
  if health#<=75 then load image "mediaplayerface_02.bmp", 6,1:texture object 2,6
endif

rem Selection_flag is, as a said earlier, the delay for the E and R key, it should
rem be decreased, or the buttons will only work once!
if selection_flag<>0 then dec selection_flag

rem Set the bullet flag when the mousekey is hit, this will show the bullet and rotate it
rem correctly. First we will check if there are bullets left and the bullet isnt fired before.
if mouseclick()=1
   if bullet_flag=0 and bullets>0
   rem remove one bullet
   dec bullets
   bullet_flag=100
   rem Show the bullet
   show object bulletnumber
   rem Show the fire
   show object bulletnumber+1

   rem the rotation player
   bullet_direction = object angle y(1)

   rem Position the bullet at the players position
   position object bulletnumber,object position x(1),0,object position z(1)
   bx1#=newxvalue(x#,bullet_direction,3)
   bz1#=newzvalue(z#,bullet_direction,3)
   rem Position the gunfire
   position object bulletnumber+1,bx1#,1,bz1#
   rem Rotate it
   yrotate object bulletnumber+1,object angle y(1)
   rem BANG!
   play sound 2
   endif
endif

rem If this is true, then there's a bullet in the air
rem so movew it
if bullet_flag<>0
   rem Now we will hide the gunfire.
   if bullet_flag=98 then hide object bulletnumber+1
   dec bullet_flag
   bx#=object position x(bulletnumber)
   bz#=object position z(bulletnumber)
   bx1#=newxvalue(bx#,bullet_direction,1)
   bz1#=newzvalue(bz#,bullet_direction,1)
   rem Move the bullet
   position object bulletnumber,bx1#,1,bz1#
   rem The bullet is not necessary anymore
   if bullet_flag=0 then hide object bulletnumber
else
   rem When the bullet isnt in the air we need to position it to Y -2, so that the enemy<>bullet collision is ignored
   position object bulletnumber,0,-2,0
endif
return

setuplevel:
rem Now we load the objects
rem Player first, this one is the for the guy who walks around
load image "mediaplayerbody.bmp",1,1
rem This one is for his face
load image "mediaplayerface_01.bmp",6,1

rem We use plains instead of sprites much faster and better rotation
rem For the real dude
make object plain 1,5,5
rem For the face
make object plain 2,7,7

rem First we texture the dude with the body.bmp texture
texture object 1,1
rem Now we will texture the face with the face_01.bmp texture
texture object 2,6

rem Put the dude on the landscape
position object 1,0,1,0

rem Plains needs to be xrotated 90 degrees when you put the camera above them or they wont be visible
xrotate object 1,90
xrotate object 2,90
yrotate object 1,0
yrotate object 2,0

rem Remove the black color of the body texture (transparent)
SET OBJECT TRANSPARENCY 1,1

rem Bullet
make object sphere bulletnumber,0.5
rem Grey color
color object bulletnumber,rgb(128,128,128)
rem Its not fired yet, so we hide it
hide object bulletnumber

rem Fire from the gun
load image "mediaplayergunfire.bmp",2,1
make object plain bulletflash,1,1
texture object bulletflash,2
SET OBJECT TRANSPARENCY bulletflash,1
xrotate object bulletflash,90
yrotate object bulletflash,0
hide object bulletflash

rem Monster body
load image "mediamonstermonster_01.bmp",3,1
rem Monster dead-body
load image "mediamonsterdead_01.bmp",4,1
rem Lets put some monsters on the landscape
for a=enemystart to enemyend
    rem Again we use plains
    make object plain a,5,5
    texture object a,3
    repeat
       position object a,rnd(600)-300,1,rnd(600)-300
    until abs(getdistance(1,a))>50
    xrotate object a,90
    yrotate object a,0
    SET OBJECT TRANSPARENCY a,1
    rem This is a little more difficult to understand, I use the array ai_status to check
    rem If the monster should attack the enemy, ai_status(a,1)=1 means that it should stay idle
    ai_status(a,1)=1
next a

rem Landscape
load object "medialevellevel.3ds",10
position object 10,0,-1,0
set object 10,1,1,0
rem Its not big enough, this will make the X and Z 10 times bigger
scale object 10,1000,100,1000
rem Because we've scaled the landscape, we also need to scale the texture
scale object texture 10,4.0,4.0

rem Tree
load image "medialeveltree_01.bmp",5,1
rem Now we will place some trees to fill up the landscape
treenumber=treestart
for a=treestart to treeend-1

    rem place a tree on the map
    make object plain treenumber,50,50
    repeat
       position object treenumber,rnd(900)-450,2,rnd(900)-450
    until abs(getdistance(1,treenumber))>15
    texture object treenumber,5
    SET OBJECT TRANSPARENCY treenumber,1
    xrotate object treenumber,90
    rem rotate the tree so that all three do not look the same
    yrotate object treenumber,rnd(360)
    inc treenumber

    rem if a trees x or z position is past 350 then place another tree on the other
    rem side of the map
    rem that go for -350
    newx#=object position x(treenumber-1)
    newz#=object position z(treenumber-1)
    nx#=newx#
    nz#=newz#
    do_new_tree=0

    rem check left and place trees on right
    rem any tree that is less than -350
    rem will be copyed on to the right hand side
    if newx#<-350
       rem make number a + number
       nx#=(newx#*-1)
       rem find out are far past 400 object is
       ncb#=350-nx#
       rem place object on other side of map
       nx#=550+ncb#
       do_new_tree=1
    endif

    rem check right and place left
    if newx#>350
       rem copy positionr into nx#
       nx#=newx#
       rem find out are far past 400 object is
       ncb#=350-nx#
       rem place object on other side of map
       nx#=(550+ncb#)*-1
       do_new_tree=1
     endif

     rem check up and place down
     if newz#<-350
       rem make number a + number
       nz#=(newz#*-1)
       rem find out are far past 400 object is
       ncb#=350-nz#
       rem place object on other side of map
       nz#=550+ncb#
       do_new_tree=1
    endif

    rem check down and place up
    if newz#>350
       rem copy positionr into nx#
       nz#=newz#
       rem find out are far past 400 object is
       ncb#=350-nz#
       rem place object on other side of map
       nz#=(550+ncb#)*-1
       do_new_tree=1
     endif

    rem make new tree
    if do_new_tree=1
       make object plain treenumber,50,50
       position object treenumber,nx#,2,nz#
       texture object treenumber,5
       SET OBJECT TRANSPARENCY treenumber,1
       xrotate object treenumber,90
       yrotate object treenumber,object angle y(treenumber-1)
       rem for debuging only
       `ghost object on treenumber
       inc treenumber
    endif

next a

rem Now we will load the HUD (heads up display) textures and images
rem Selection box texture
load image "mediahudselector.bmp",20,1
rem Empty slot texture
load image "mediahudhud_01.bmp",21,1
rem Slot with health kit texture
load image "mediahudhud_02.bmp",22,1
rem Slot with ammo box texture
load image "mediahudhud_03.bmp",23,1

rem Selection box plain
make object plain 500,7,7
xrotate object 500,90
texture object 500,20
SET OBJECT TRANSPARENCY 500,1

rem Lets create the 5 item slots
for a = 501 to 505
  make object plain a,7,7
  xrotate object a,90
  yrotate object a,0
  rem item_slot holds the texture, 21=empty, 22=health, 23=ammo
  texture object a,item_slot(a-500)
next a

rem Items on the ground
rem Health
load image "mediahuditem_01.bmp",11,1
rem Ammo
load image "mediahuditem_02.bmp",12,1

rem Lets place them
for a=pickupstart to pickupend
    make object plain a,5,5
    buffer = rnd(1)+1
    texture object a,buffer+10
    repeat
       position object a,rnd(600)-300,1,rnd(600)-300
    until abs(getdistance(1,a))>10
    SET OBJECT ROTATION ZYX a
    xrotate object a,260
    zrotate object a,180
    yrotate object a,0
    SET OBJECT TRANSPARENCY a,1
    item_stat(a)=buffer+21
next a

rem sounds
rem Gunshot
load sound "mediasoundsshoot.wav", 2
rem Psycho sound
load sound "mediasoundsscare.wav", 3
rem Monster dies
load sound "mediasoundsm_die.wav", 4
rem Player dies
load sound "mediasoundsp_die.wav", 10
rem Monster attack
load sound "mediasoundsallosy.wav", 11
rem Reloadin gun
load sound "mediasoundsreload.wav", 12
rem Health Kit
load sound "mediasoundsheal.wav", 13
return

gameover:
rem If the game reaches this command, then the player has died, so we will clear the screen.
cls
rem A good way to clear the memory, most people dont do this, but it will prevent leaks and is
rem an example of good programming :)
for a=1 to 600
if object exist(a)=1 then delete object a
next a
rem Turn off the ugly music!
stop music 1
rem We dont need any 3D stuff anymore
backdrop off
rem Clear the screen again
sync
rem Lets make the "YOU DIED" screen, with white text and some sounds.
ink rgb(255,255,255),0
center text screen width()/2,screen height()/2-10,"YOU DIED"
sync
sync
play sound 11
wait 1000
play sound 10
wait 3000
rem Delete the sounds and music, and we are finished :)
for a=1 to 20
    if sound exist(a)=1 then delete sound a
next a
for a=1 to 32
    if music exist(a)=1 then delete music a
next a
return

function getdistance(a,b)
         dx#=object position x(a)-object position x(b)
         dy#=object position z(a)-object position z(b)
endfunction sqrt(dx#+dy#)