Night by malcolm1st 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 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#) |