Thread: Trying to start a roguelike

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    15

    Trying to start a roguelike

    I am attempting to start making my own roguelike. I'm using c++, and I know the basics, I've got a menu and whatnot working, but I don't know how to get started on making the actual game(ie. I need to start by making a @ that moves around, that's where I'm stuck)
    How would I go about drawing a level in the console and making a @ that I can control(I know how to use arrow keys and such for input already)?

  2. #2
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    Well, here are two functions which I think will come in handy -
    Code:
    // Sets the position of the text-cursor, starts at 0, 0 on the 
    // top left
    void GotoXY	( int  x, int  y ) 
    { 
        COORD Cursor_Position; 
    
        Cursor_Position.X = x; 
        Cursor_Position.Y = y; 
    
        SetConsoleCursorPosition( GetStdHandle ( STD_OUTPUT_HANDLE ), Cursor_Position ); 
    } 
    
    // Gets the current position of the text-cursor
    void GetXY	( int &x, int &y )
    {
    	CONSOLE_SCREEN_BUFFER_INFO XYInfo;
    
    	GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &XYInfo );
    
    	x = XYInfo.dwCursorPosition.X;
    	y = XYInfo.dwCursorPosition.Y;
    }

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    15
    What do I need to include to use those functions?

    EDIT: Never mind, needed windows.h. I've got an empty room with a moving @ now! Woo, haha.
    Last edited by Dark_Oppressor; 09-17-2006 at 11:17 PM.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    15
    Ok, now I am using the x and y coordinates of my @ to determine where GotoXY should center, then drawing the @. Here's my current code regarding this:
    Code:
    void drawscreen()
    {
         clrscr();
         GotoXY(p_x,p_y);
         cout<<"@";
         GotoXY(p_x,p_y);
         while ((ch=get_code())){
               switch (ch){
               case KP_UP:
                    if (p_y>0)
                    p_y=p_y-1;
                    break;
               case KP_DOWN:
                    if (p_y<23)
                    p_y=p_y+1;
                    break;
               case KP_LEFT:
                    if (p_x>0)
                    p_x=p_x-1;
                    break;
               case KP_RIGHT:
                    if (p_x<79)
                    p_x=p_x+1;
                    break;
               case ARROW_UP:
                    if (p_y>0)
                    p_y=p_y-1;
                    break;
               case ARROW_DOWN:
                    if (p_y<23)
                    p_y=p_y+1;
                    break;
               case ARROW_LEFT:
                    if (p_x>0)
                    p_x=p_x-1;
                    break;
               case ARROW_RIGHT:
                    if (p_x<79)
                    p_x=p_x+1;
                    break;
               case KP_UPLEFT:
                    if (p_y>0)
                    p_y=p_y-1;
                    if (p_x>0)
                    p_x=p_x-1;
                    break;
               case KP_UPRIGHT:
                    if (p_y>0)
                    p_y=p_y-1;
                    if (p_x<79)
                    p_x=p_x+1;
                    break;
               case KP_DOWNLEFT:
                    if (p_y<23)
                    p_y=p_y+1;
                    if (p_x>0)
                    p_x=p_x-1;
                    break;
               case KP_DOWNRIGHT:
                    if (p_y<23)
                    p_y=p_y+1;
                    if (p_x<79)
                    p_x=p_x+1;
                    break;
               case KEY_ESC:
                    return;
               }
               clrscr();
               GotoXY(p_x,p_y);
               cout<<"@";
               GotoXY(p_x,p_y);
         }
    }
    As you can see, I have determined the edges of the empty room based on the edges of my console window, but I assume that will be insufficient, because other console windows will be different sizes. Is there a way I can control the size of the console window at the beginning of the program, so all consoles will be resized to fit with my program? Or is there a better way to go about this?
    Also, I suppose I need a way to determine if a tile my @ is moving to is already occupied by a wall. Is there a way to simply determine if a tile has an ascii symbol such as \ / | or - on it?(I'll use these for walls for now I think)
    Last edited by Dark_Oppressor; 09-18-2006 at 12:16 AM.

  5. #5
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Since you're using Win 32 API here's a simple func you can use to resize the console buffer size.
    You should be aware that nothing stops the user from manually resizing the console buffer size after you run this function.
    I searched for a boolean flag or a setter function that allows the programmer to lock the size but I was unable to find anything.
    If anyone else knows of a way, I'd be happy to hear it.

    Code:
    #include <windows.h>
    
    int main()
    {
        setConsoleSize(80, 25);
        system("pause");
    }
    
    int setConsoleSize(int width, int height)
    {
        HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
        COORD scr_dim;
        
        scr_dim.X = width;
        scr_dim.Y = height;
    
        SetConsoleScreenBufferSize(hOut, scr_dim);
    }
    Last edited by MacNilly; 09-18-2006 at 08:44 AM.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    15
    Thanks, that'll do for now, anyway. Here is part of the code I'm working on to randomly generate the dungeon:
    Code:
    void Dungeon_Gen()
    {
         int i;
         int j;
         int k;
         int l;
         int mem_i;
         int mem_j;
         int mem_k;
         int mem_l;
         int o;
         int p;
         
         //Fill screen with walls
         for (i=0;i<80;i++){
             for (j=0;j<24;j++){
                 dungeon[i][j]=1;
                 }
                 }
         //i and j are the coordinates of corner 1, k and l are the coorinates of corner 2, the room should be filled in between them
         i=random_range(2,70);
         j=random_range(2,14);
         mem_i=i;
         mem_j=j;
         o=random_range(3,6);
         p=random_range(3,6);
         k=i+o;
         l=j+p;
         mem_k=k;
         mem_l=l;
         for (i;i<k;i++){
             dungeon[i][j]=0;
             }
             i=mem_i;
         for (j;j<l;j++){
             dungeon[i][j]=0;
             }
         j=mem_j;
         mem_k=k;
         mem_l=l;
         for (k;k>=i;k--){
             dungeon[k][l]=0;
             }
         k=mem_k;
         for (l;l>=j;l--){
             dungeon[k][l]=0;
             }
         dungeon[mem_k-1][mem_l-1]=2;
         p_x=mem_k-2;
         p_y=mem_l-2;
    }
    What this does, currently, is fill the screen with walls, hollow out a rectangle(but only edges, it doesn't fill in the room with floor, which is my current problem), and stick in a stair up and the @. I need to find a way to make the for loops that hollow out the edges of the rectangle hollow out a full room instead. Maybe it's because I've been sitting here working on this all day, because it seems like this should be a simple thing to do.
    Last edited by Dark_Oppressor; 09-18-2006 at 04:12 PM.

  7. #7
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    27
    Try getting your display system up and running first, and then start dealing with map generating... that's how I'm doing it. Instead of randomly generating a map, I load a map file which allows me to hardcode in any features I want to test (doors, for example, or a new terrain type). Once you've got the display system up and running (and bug free, that's the hard part :P), it's easy to add more features, and slightly easier to figure out where you've gone wrong if they don't work the way you intended. Although from the sound of it, you already have a pretty good display system.

    ...unfortunately, my screen-refreshing function isn't working quite the way I'd like it to. It sounded so easy to make it possible to have off-screen objects, but... it doesn't work out that way.

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    15
    Aye, that would be a better order to do it, I'd say.
    Ok, current issue:

    I need a way to make a type of structure Dungeonlvl, with a name of 'd' and then a number representing whatever level of the dungeon the player is on.
    In this code, what I need is a way to use a variable representing the current dungeon level in place of the number 1.

    Code:
    //create a structure with an array corresponding to the terrain tiles in the dungeon
    struct Dungeonlvl{
           int dungeon[80][24];
           };
    //create a type of array Dungeonlvl 'd'<number of current dungeon level(i have used the number one until I learn how to use a variable here)
    Dungeonlvl d1;
    //set a tile's terrain value from this dungeon level to 1
    d1.dungeon[i][j]=1;
    Last edited by Dark_Oppressor; 09-19-2006 at 01:02 PM.

  10. #10
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317
    Just a thought. If you create an array of structures, the index would be the dungeon level.

    Code:
    Dugeonlvl  CaveOfDarkness[20];  //20 being the total number of levels, you could use a vector as well
    "Knowledge is proud that she knows so much; Wisdom is humble that she knows no more."
    -- Cowper

    Operating Systems=Slackware Linux 9.1,Windows 98/Xp
    Compilers=gcc 3.2.3, Visual C++ 6.0, DevC++(Mingw)

    You may teach a person from now until doom's day, but that person will only know what he learns himself.

    Now I know what doesn't work.

    A problem is understood by solving it, not by pondering it.

    For a bit of humor check out xkcd web comic http://xkcd.com/235/

  11. #11
    Master of Puppets rwmarsh's Avatar
    Join Date
    Feb 2006
    Location
    Texas
    Posts
    96
    Also, I suppose I need a way to determine if a tile my @ is moving to is already occupied by a wall. Is there a way to simply determine if a tile has an ascii symbol such as \ / | or - on it?(I'll use these for walls for now I think)
    You could keep a 2D array to hold info on the map, each element in the array representing a square on the map. Generate the map and display it using the array. Then when the players moves you can just look at the array to see if it is a valid move, something like this
    Code:
    struct CellInfo {
        bool Wall;
        bool floor;
        bool door;
        //.......
    };
    
    CellInfo Map[20][20];
    
    WORD direction;
    COORD CurrentPosition;
    
    // get user input
    
    switch (direction) {
        case VK_UP : {
            if (CurrentPosition =>0 && !Map[CurrentPosition.X][CurrentPosition.Y-1] .Wall )
                CurrentPosition.Y--;
                MovePlayer(CurrentPosition);
            } break;
    
        // switch other directions
    
        default :
            // error, not a valid direction
    }
    just a though... This is basicaly how I did my first rogue like.
    Last edited by rwmarsh; 09-20-2006 at 07:11 AM.
    Using DEV-C++ Under Windows XP
    +------------------------------+

    "No! Do, or Do Not. There is no Try..."

  12. #12
    Registered User Frobozz's Avatar
    Join Date
    Dec 2002
    Posts
    546
    Or you could just redraw the entire thing every loop and use something besides the Win32 console. Anything I do text-based I usually do through SDL. Makes for more portable code and it can be double buffered - which is great on the eyes.

  13. #13
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317
    If you want to, you can use SDL. If you are just trying to learn Window Console, I would suggest looking up the console functions on MSDN library or google for Windows Console Functions. The function ReadConsoleOutputCharacter allows you get the sequential character'(s) at a specific location.
    Last edited by manofsteel972; 09-21-2006 at 05:05 AM.
    "Knowledge is proud that she knows so much; Wisdom is humble that she knows no more."
    -- Cowper

    Operating Systems=Slackware Linux 9.1,Windows 98/Xp
    Compilers=gcc 3.2.3, Visual C++ 6.0, DevC++(Mingw)

    You may teach a person from now until doom's day, but that person will only know what he learns himself.

    Now I know what doesn't work.

    A problem is understood by solving it, not by pondering it.

    For a bit of humor check out xkcd web comic http://xkcd.com/235/

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    15
    Thanks everyone. I've got quite a few things working now, but one thing that is killing me is random dungeon generation. I have been working on it for about 6 hours now, and I can't get the rooms I generate to not randomly overlap. I haven't even thought about halls yet. I think I'm going to take a break and try this again later, as my head is killing me now. If anyone has a good idea as to how I could do this, please let me know.

  15. #15
    Registered User
    Join Date
    May 2006
    Posts
    169
    Did you check the links Mario F. gave earlier?
    There's quite a few articles on that subject, as well as others.

    http://roguelikedevelopment.org

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. Adventures in labyrinth generation.
    By guesst in forum Game Programming
    Replies: 8
    Last Post: 10-12-2008, 01:30 PM
  3. C++ gui for windows where to start
    By prixone in forum Windows Programming
    Replies: 2
    Last Post: 12-16-2006, 11:48 PM
  4. GNOME Desktop won't start (Mandriva)
    By psychopath in forum Tech Board
    Replies: 10
    Last Post: 07-19-2006, 01:21 PM
  5. Where do I start?
    By Unregistered in forum Game Programming
    Replies: 2
    Last Post: 04-08-2002, 12:42 AM