Name: Anonymous 2012-06-11 9:55
found an old roguelike tutorial that teaches the basics but its code was written for some simplified windows console library. i redid the tutorial using curses for a game im working on. here is the code if anyone wants a template to experiment with roguelike stuff.
#include <curses.h>
// Map dimensions
#define MAP_WIDTH 20
#define MAP_HEIGHT 15
// Tile definitions
#define TILE_FLOOR 0
#define TILE_WALL 1
#define TILE_GRASS 2
#define TILE_OPENDOOR 3
// Map array
int MapArray[MAP_HEIGHT][MAP_WIDTH] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
// Map drawing function
void DrawMap( void ) {
for( int y = 0; y < MAP_HEIGHT; y++ ) {
// Jump to next line
move( y, 0 );
for( int x = 0; x < MAP_WIDTH; x++ ) {
switch( MapArray[y][x] ) {
// Draw tiles
case TILE_FLOOR:
attron( COLOR_PAIR(3) );
addch('.');
attroff( COLOR_PAIR(3) );
break;
case TILE_WALL:
addch('#');
break;
}
}
}
}
// Collision detect function
bool IsPassable( int MapX, int MapY ) {
// Make area outside map impassible
if( MapX < 0 || MapX >= MAP_WIDTH || MapY < 0 || MapY >= MAP_HEIGHT )
return false;
// Store the value of the tile specified
int TileValue = MapArray[MapY][MapX];
// Return true if it's passable
if( TileValue == TILE_FLOOR || TileValue == TILE_GRASS || TileValue == TILE_OPENDOOR )
return true;
// If execution gets here, it's not passable
return false;
}
int main( void ) {
// Init curses
keypad( initscr(), 1 );
curs_set( 0 );
// Init colors
start_color();
init_pair( 1, COLOR_RED, COLOR_BLACK );
init_pair( 2, COLOR_YELLOW, COLOR_BLACK );
init_pair( 3, COLOR_GREEN, COLOR_BLACK );
init_pair( 4, COLOR_BLUE, COLOR_BLACK );
// Init start position
int PlayerX = 4;
int PlayerY = 4;
// Game Loop
while( true ) {
// Refresh screen
refresh();
// Draw map
DrawMap();
// Draw player
attron( COLOR_PAIR(2) );
mvaddch( PlayerY, PlayerX, '@' );
attroff( COLOR_PAIR(2) );
// Wait for input
char PlayerKey = getch();
// Process input
switch( PlayerKey ) {
case 'k': // Up
if( IsPassable( PlayerX, PlayerY - 1 ) ) {
PlayerY--;
}
break;
case 'j': // Down
if( IsPassable( PlayerX, PlayerY + 1 ) ) {
PlayerY++;
}
break;
case 'h': // Left
if( IsPassable( PlayerX - 1, PlayerY ) ) {
PlayerX--;
}
break;
case 'l': // Right
if( IsPassable( PlayerX + 1, PlayerY ) ) {
PlayerX++;
}
break;
case 'q': // Quit
return endwin();
}
}
}
#include <curses.h>
// Map dimensions
#define MAP_WIDTH 20
#define MAP_HEIGHT 15
// Tile definitions
#define TILE_FLOOR 0
#define TILE_WALL 1
#define TILE_GRASS 2
#define TILE_OPENDOOR 3
// Map array
int MapArray[MAP_HEIGHT][MAP_WIDTH] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
// Map drawing function
void DrawMap( void ) {
for( int y = 0; y < MAP_HEIGHT; y++ ) {
// Jump to next line
move( y, 0 );
for( int x = 0; x < MAP_WIDTH; x++ ) {
switch( MapArray[y][x] ) {
// Draw tiles
case TILE_FLOOR:
attron( COLOR_PAIR(3) );
addch('.');
attroff( COLOR_PAIR(3) );
break;
case TILE_WALL:
addch('#');
break;
}
}
}
}
// Collision detect function
bool IsPassable( int MapX, int MapY ) {
// Make area outside map impassible
if( MapX < 0 || MapX >= MAP_WIDTH || MapY < 0 || MapY >= MAP_HEIGHT )
return false;
// Store the value of the tile specified
int TileValue = MapArray[MapY][MapX];
// Return true if it's passable
if( TileValue == TILE_FLOOR || TileValue == TILE_GRASS || TileValue == TILE_OPENDOOR )
return true;
// If execution gets here, it's not passable
return false;
}
int main( void ) {
// Init curses
keypad( initscr(), 1 );
curs_set( 0 );
// Init colors
start_color();
init_pair( 1, COLOR_RED, COLOR_BLACK );
init_pair( 2, COLOR_YELLOW, COLOR_BLACK );
init_pair( 3, COLOR_GREEN, COLOR_BLACK );
init_pair( 4, COLOR_BLUE, COLOR_BLACK );
// Init start position
int PlayerX = 4;
int PlayerY = 4;
// Game Loop
while( true ) {
// Refresh screen
refresh();
// Draw map
DrawMap();
// Draw player
attron( COLOR_PAIR(2) );
mvaddch( PlayerY, PlayerX, '@' );
attroff( COLOR_PAIR(2) );
// Wait for input
char PlayerKey = getch();
// Process input
switch( PlayerKey ) {
case 'k': // Up
if( IsPassable( PlayerX, PlayerY - 1 ) ) {
PlayerY--;
}
break;
case 'j': // Down
if( IsPassable( PlayerX, PlayerY + 1 ) ) {
PlayerY++;
}
break;
case 'h': // Left
if( IsPassable( PlayerX - 1, PlayerY ) ) {
PlayerX--;
}
break;
case 'l': // Right
if( IsPassable( PlayerX + 1, PlayerY ) ) {
PlayerX++;
}
break;
case 'q': // Quit
return endwin();
}
}
}