+ All Categories
Home > Documents > Quick Start Tutorial 6 - Huge Dungeons

Quick Start Tutorial 6 - Huge Dungeons

Date post: 29-Nov-2014
Category:
Upload: plmanon123
View: 34 times
Download: 2 times
Share this document with a friend
11
DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons © Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5 th Feb 2003 Page 1 of 11 DarkBASIC Professional QuickStart Tutorial All rights reserved. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photo-copying, recording, or by any information storage and retrieval system, without written permission from Dark Basic Software Limited, except for the inclusion of brief quotations in a review. Copyright © 2003 by Dark Basic Software Limited Warning and Disclaimer This tutorial is designed to provide information about DarkBASIC Professional. Every effort has been made to make this tutorial as complete and as accurate as possible, but no warranty or fitness is implied. The information is provided on an “as is” basis. The author(s) and Dark Basic Software Limited shall have neither liability nor responsibility to any person or entity with respect to any loss or damage arising from the information contained in this document or from the use of the programs or source code that may accompany it.
Transcript
Page 1: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 1 of 11

DarkBASIC Professional QuickStart Tutorial

All rights reserved. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photo-copying, recording, or by any information storage and retrieval system, without written permission from Dark Basic Software Limited, except for the inclusion of brief quotations in a review. Copyright © 2003 by Dark Basic Software Limited

Warning and Disclaimer This tutorial is designed to provide information about DarkBASIC Professional. Every effort has been made to make this tutorial as complete and as accurate as possible, but no warranty or fitness is implied. The information is provided on an “as is” basis. The author(s) and Dark Basic Software Limited shall have neither liability nor responsibility to any person or entity with respect to any loss or damage arising from the information contained in this document or from the use of the programs or source code that may accompany it.

Page 2: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 2 of 11

Huge Dungeons

Creating huge dungeons/mazes in DarkBASIC Professional Who hasn’t ever dreamed about creating your own Role Playing Game? In this tutorial we’ll cover building one of the most important aspects of any RPG – a nice huge dungeon to explore!

Making the Map There are many methods available that you can use to build your original map, however the method we’re going to use is one found at http://roguelikedevelopment.org (original author: Mike Anderson). To start with we need a map data file. You can create one of these with Notepad or the tool included with this tutorial (Dungeon Creator). The map format is very straight forward and consists of ASCII characters representing various parts of your dungeon (doors, walls, stairs, etc). Here you can see an example of the map data:

........#:::::::::::#.###:##:#......##########.....#:#:#.#:::::#

........#:::::::::::#...#:##:#..###.#:::##:::#.....###:#.#:::::#

........#######D#########:##:#..#:####:####:##########:######D## #############:::::::::::#:##:#..#::::::::::::::::::::::::::::::# #:::::::::::#:::::::::::#:####..#:#############D#####:#####D#### #:::::::::::#:::::::::::#:#.....###....#:::::::::::##:#..#:::::# #:::::::::::#:::::::::::#:#....#######.#:::::::::::##:#..#:::::# #:::::::::::#:::::::::::#:#....#:::::###:::::::::::##:#..#:::::# #:::::::::::#:::::::::::#:######:::::#:#:::::::::::####..#:::::# #:::::::::::#:::::::::::D:##:::D:::::D:D:::::::::::#.....#:::::# #:::::::::::D:::::::::::#:######:::::#:#:::::::::::###...####D## #::::::::O::#:::::::::::#:#....#:::::###:::::::::::#:#......#:#. #:::::::::::###S#########:#....#######.#:::::::::::D:#......#:#. #:::::::::::##:::::######:#........#####:::::::::::#:#......#:#. #:::::::::::##:::::#:##:#:#........#:::D:::::::::::###......###. ##############:::::D:##:::#........#####:::::::::::#............ .............#:::::#:##:#:#.....###.#######D########............ .............#:::::######:#.....#:#.#:::::::::::#.......#######. ........############....#:#.....#:#.#:::::::::::#########:::::#. ........#:::#...........#:#.....#:#.#:::::::::::#:::::::#:::::#.

This section of our ASCII File contains all the values of the map. The # character denotes a wall – the : is the floor and periods/full stops are unused or blank space. This map format has a nice advantage for when we start to optimize our code later because we don’t have to show all the objects of the world – only the one’s which are used.

Stairs Before we can start walking around in our dungeon we need a few other things first. The ability to go up and down levels is important so we’ll add 2 new characters to our ASCII map above, a “O” and a “U” for up and down stairs respectively. As you can start to see

Page 3: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 3 of 11

DB

V1

toD

BP

RO

you could use different characters to signify any element you wish (monsters starting locations, wells, traps, etc). To put this into practise here is some code to initialise DarkBASIC with: set display mode 800,600,16

sync on sync rate 0 hide mouse

backcolor=rgb(0,0,0)

backdrop on color backdrop backcolor cls That is our initialization over with – all we are doing is setting a resolution, making the program run as fast as possible (sync rate 0), hiding the mouse and colouring the background. We have put our background colour into a separate variable (backcolor) so we can change it easily later and also use it for the fog effect.

Define Values The next part of our program will define the size of the map. In this example we are using a 512x512 dimension map which will show you a really huge dungeon! We set the dimensions for the map array so it is possible to keep the whole map in memory at once – in this code we should how to use a string array for learning purposes: mapsize=512 dim map$(mapsize,mapsize)

maxcubes=16 cubesize=200 collisionstep=int(cubesize/10)

It is perfectly possible to use smaller maps but we wanted this demonstration to be more impressive – you could also use a dungeon larger than 512 for a truly big level. The maxcubes variable contains the row/column number of the viewable objects around the player. In our case it’s set to 16 – you can imagine this as a small 16x16 unit map surrounding the player at any one time:

Although we recommend that you always use the resolution settings found in the IDE rather than using “set display mode” in your programs – this command has been left in for backward compatibility. The final CLS in the code is just to solve a problem with flickering and GeForce cards.

Page 4: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 4 of 11

................

.............###

.............#::

.............#::

.............#::

...###########::

...#::::::::::::

...#::::::::::::

...#::::S ::::::

...#::::::::::::

...#::::::::::::

...#::::::::::::

...#::::::::::::

...#::::::::::::

...#######::::::

..........#:::::

..........###D##

................

................

................ The player is located in the middle of this mini-map. The units around the player are the one’s we’ll have to display onscreen. That means that in this example we have to show 256 objects at once (16x16). However we stated earlier the unit’s in the map displayed as a period/full stop are blank and therefore do not need to be shown so we will hide them. This hiding will speed up our program and the display speed because we won’t have to draw 3072 faces each frame. DarkBASIC has another tool in its arsenal when it comes to getting more speed out of large scenes – back face culling. This is an optimisation command which will perform the complicated task of sorting out all of the faces which can’t actually be seen by the player (i.e. walls behind them). The value cubesize will set the size (in 3D units) of the wall blocks. The final variable collisionstep holds a special value we will use later when we create a simple math based collision system.

Enter the Darkness Dungeons are dank and dark places, full of hidden traps and treasures. We need to get the player into the right mood and atmosphere so let’s set up some environment values: fog on fog color backcolor fog distance (int(maxcubes)*cubesize) set camera range 1,(maxcubes*cubesize) Here we’ve set the fog and the camera viewing distance to be calculated from the values entered before.

Reading in the Map data file

Page 5: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 5 of 11

We already know that the data for our dungeon is stored in ASCII format and that you can create this file yourself with Notepad or the supplied utility. What we need to do now however is actually load that data file and extract the values from it into an array. The array has been defined already as map$(mapsize, mapsize) which means we have created an array in memory which is mapsize * mapsize big. That is enough for the complete map data in our text file. Our mapfile should be an ASCII file without carriage return or line feed characters (click “Save as ASCII map” in Dungeon Creator to do this). One you understand how this system works it is very easy to change the loader so it can handle all sorts of ASCII files. The loading routine is a function. We can use a function here because Arrays in DarkBASIC are treated as “global” (i.e. they can be accessed from the main program or from functions). It also keeps our code neat and organised. function loadmap(filename$,size)

open to read 1,filename$ for y=1 to size for x=1 to size

read byte 1,tmp map$(x,y)=chr$(tmp)

next x next y close file 1

endfunction The function expects two parameters. The first is the name of the map data file (filename$) and the second is the size of the map in units (this is the mapsize value from before). First we open the file for reading and then we read the whole file in byte by byte. This byte (it’s a numeric value between 0 and 255) is then converted to a character using the CHR$ command. When everything has finished what we end up with is the corresponding character in our array. When it completes the whole map data will be in memory. With the function complete we can now load our map with the command: loadmap(“dungeon.map”, mapsize)

From ASCII to 3D With the map data now held in memory we can set about turning it into a 3D scene. First we need to load up some textures for use on the floor, ceiling and walls: load image "wall2.jpg",1 load image "ground.jpg",2 load image "wall.jpg",3

Page 6: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 6 of 11

With the textures loaded we can create the 3D objects themselves using the primitives that are part of DarkBASIC – cubes for the walls and plain objects for the floor and ceiling: ` Wall for i=1 to maxcubes*maxcubes

make object cube 100+i,cubesize texture object 100+i,1

next i

` Floor for i=1 to maxcubes*maxcubes

make object plain 10000+i,cubesize,cubesize rotate object 10000+i,90,0,0 texture object 10000+i,2

next i

` Ceiling for i=1 to maxcubes*maxcubes

make object plain 20000+i,cubesize,cubesize rotate object 20000+i,270,0,0 texture object 20000+i,3

next i This will literally create enough cubes and plains for our entire map. Now it’s time for a little more dungeon atmosphere and some lights: set ambient light 30 make light 1 make light 2 set point light 1,0,0,0 set spot light 2,45,90 color light 2,RGB(252,216,141) color light 1,RGB(236,182,100) color light 0,RGB(0,0,0) What we also need is the right starting point within the current map. So we search the map data for the “O” and calculate the value for the camera position: for z=1 to mapsize for x=1 to mapsize

if map$(x,z)="O" cx=x*cubesize cz=z*cubesize

endif next x next z position camera cx,0,cz

Main Loop

Page 7: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 7 of 11

Now we are near our main loop. As we need a small and easy collision system we need another two variables which contain the last camera position. oldpositionx#=camera position x() oldpositionz#=camera position z() As we are creating an easy version of a dungeon we don’t need to save the last Y coordinate of the camera because we have just one height for everything. In this example we just need the X and Z axis coordinate. Now to the difficult part of this tutorial - our main loop! First here is some pseudo code so you’ll understand what we are trying to do:

DO 1. Move the camera 2. Calculate the current map view 3. Check for wall collision 4. Render the current map 5. Animate lights SYNC LOOP

Let’s begin with the camera movement. In this example the player uses the mouse to move through the dungeon. A left mouse click will make them go forward and a right one will go backwards. Moving the mouse will rotate the player. The easiest code for this is as follows: if mouseclick()=1 then move camera maxcubes if mouseclick()=2 then move camera maxcubes*(-1) ry#=wrapvalue(ry#+mousemovex()) rotate camera 0,ry#,0 With this the player can move around (only on a single height but that’s what we wanted) Now we’ll try to calculate the current map location (the small 16x16 units part as mentioned previously) Here is the code: cx#=int(camera position x()/cubesize)-int(maxcubes/2) cz#=int(camera position z()/cubesize)-int(maxcubes/2)

tx#=camera position x() tz#=camera position z()

zzz=0

Page 8: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 8 of 11

for zz=1 to maxcubes for xx=1 to maxcubes

zzz=zzz+1 curposx=int(cx#)+xx curposz=int(cz#)+zz if curposx<=1 then curposx=1 if curposx>=mapsize then curposx=mapsize if curposz<=1 then curposz=1 if curposz>=mapsize then curposz=mapsize ` Wand if map$(int(curposx),int(curposz))="#" or

map$(int(curposx),int(curposz))="S" show object 100+zzz position object 100+zzz,curposx*cubesize,0.0,curposz*cubesize

else hide object 100+zzz

endif ` Boden if map$(int(curposx),int(curposz))=":" or

map$(int(curposx),int(curposz))="D" or map$(int(curposx),int(curposz))="S" or map$(int(curposx),int(curposz))="T"

show object 10000+zzz position object 10000+zzz,curposx*cubesize,(cubesize/2)*(-

1),curposz*cubesize else

hide object 10000+zzz endif ` Decke if map$(int(curposx),int(curposz))=":" or

map$(int(curposx),int(curposz))="D" or map$(int(curposx),int(curposz))="S" or map$(int(curposx),int(curposz))="T"

show object 20000+zzz position object

20000+zzz,curposx*cubesize,(cubesize/2),curposz*cubesize else

hide object 20000+zzz endif

next xx# next yy#

oldpositionx#=camera position x() oldpositionz#=camera position z() Wow! That’s quite a lot of code but we will explain it for you. The code calculates the current coordinates of the player, the current camera position and the units in the map array where we located. To get the right values we must divide the current camera position through the cubesize and then we decrement this value with the half of the value from the current viewable map (maxcubes).

Page 9: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 9 of 11

This value is exactly the middle of the small map (16x16) the player is in. We have to test that these map values are not out of the array bounds (not <0 and not >512). The next two loops, xx# and yy# calculate the current scene with all objects which are in the small map (16x16) around the player. We check the map$ array and if we find e.g. a # character then we know to show a cube there else we hide it. As we know the x and y coordinates of the cubes it’s easy to get their positions in the viewable small map. position object 100+zzz,curposx*cubesize,0.0,curposz*cubesize The objects position is x*cubesize,0,z*cubesize. We save the current camera coordinates so we can set it back if there is a collision. Ah yes collision! We’ll need a simple math collision system. To get this in we change the wall showing code a little bit to the following:

` Wall if map$(int(curposx),int(curposz))="#" or

map$(int(curposx),int(curposz))="S" show object 100+zzz position object 100+zzz,curposx*cubesize,0.0,curposz*cubesize

` Collision detection if map$(int(curposx),int(curposz))="#" if tx#>=((curposx*cubesize)-(cubesize/2))-collisionstep and

tx#<=((curposx*cubesize)+(cubesize/2))+collisionstep and tz#>=((curposz*cubesize)-(cubesize/2))-collisionstep and tz#<=((curposz*cubesize)+(cubesize/2))+collisionstep

position camera oldpositionx#,camera position y(),oldpositionz#

oldpositionx#=camera position x() oldpositionz#=camera position z()

endif endif

else hide object 100+zzz

endif Again, this looks quite complicated but it’s pretty easy to understand. As we only use a single height we can think of a “from the top down viewed 2D map” (as seen in the example at the beginning). We create a simple test if the players x and zposition is within a square (we use squares here because the walls are simple cubes.) If that’s true then we change the camera position to its old value (otherwise you’d walk through the walls!). This is just a check if the player is in a certain area or not. To get a better collision we have defined our collisionstep variable and it’s time to use it - we add this value to all sides of our square so the test square are is a bit bigger then the cube. This has the end result of much better camera collision because we’re stopping a bit before the wall and not slap bang against it (so close we can put our nose on it!). This

Page 10: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 10 of 11

simply looks and plays better. If you want to see the basic collision without the bounding box then change collisionstep to zero. Last but not least we add some effects to our lights. position light 1,camera position x(),camera position y(),camera position z() position light 2,camera position x(),camera position y(),camera position z() color light 1,RGB(200+int(rnd(50)-25),120,60) rotate light 2,camera angle x(),camera angle y(),camera angle z() This gives us the effect of a flickering torch with a flashlight before the player. That was the main loop. ☺ So not as difficult as you perhaps thought eh? Here a small screenshot how it’ll look running:

Hint! Check out the directories included with the tutorial code and also the Dungeon Creator Tool. To create Maps with it just click “save as ascii map” and you should also have a look at the size of the map so you define the right one.

Page 11: Quick Start Tutorial 6 - Huge Dungeons

DarkBASIC Professional QuickStart Tutorial 6 Huge Dungeons

© Copyright 2003 Dark Basic Software Limited / Thomas Görtler / Color Arts Version 1.0 5th Feb 2003 Page 11 of 11

Suggestions

• In order to use less memory why not try using an integer/byte array to save the map into. You will have to deal with ASCII translation of the values but it will take up less RAM.

• Add in some error checking – for example if the map file exists or not.

• Try adding in some higher and lower floors and stairs leading from one to the

other.

• Why not replace the basic math collision with some sliding collision?

• Add a radar map (which could be grabbed from the Map Tool)

• Add some enemies!

• Use different ASCII characters to denote different wall textures.


Recommended