⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dungeongenerator.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  int x = sx;  int y = sy;    //fprintf(stderr, "\tnotVisitedCount=%d x=%d y=%d\n", notVisitedCount, x, y);  int nx = x;  int ny = y;  int dir = initDirections();  // keep going while you can  int stepCount = 0;  bool reachedVisited = false;  bool inMap = false;  while(true) {    // take a step in the selected direction    switch(dir) {      case DIR_N: ny--; break;      case DIR_S: ny++; break;      case DIR_W: nx--; break;      case DIR_E: nx++; break;      default: fprintf(stderr, "ERROR: unknown direction selected: %d\n", dir);    }    // off the map or location already visited    inMap = (nx >= 0 && nx < width && ny >= 0 && ny < height);    if(!inMap ||       nodes[nx][ny] != UNVISITED ||       stepCount++ >= width / 2 ||       (curvyness > 1 && curvyness < 100 &&       (int) ((double)curvyness * rand()/RAND_MAX) == 0)) {      if(!stopAtVisited && inMap && nodes[nx][ny] != UNVISITED) {        reachedVisited = true;      } else {        // step back        nx = x;        ny = y;        // pick another direction        dir = nextDirection();        if(dir == -1) {          break;        }        stepCount = 0;                continue;      }    }    // connect to the previous cell    switch(dir) {      case DIR_N:        nodes[x][y] |= N_PASS;        if(inMap) nodes[nx][ny] |= S_PASS;        break;      case DIR_S:        nodes[x][y] |= S_PASS;        if(inMap) nodes[nx][ny] |= N_PASS;        break;      case DIR_W:        nodes[x][y] |= W_PASS;        if(inMap) nodes[nx][ny] |= E_PASS;        break;      case DIR_E:        nodes[x][y] |= E_PASS;        if(inMap) nodes[nx][ny] |= W_PASS;        break;    }    if(reachedVisited) {      reachedVisited = false;      // step back      nx = x;      ny = y;      // pick another direction      dir = nextDirection();      if(dir == -1) {        break;      }      stepCount = 0;            continue;    }        // mark the cell visited    markVisited(nx, ny);    // save last position    x = nx;    y = ny;    // debug    //printMaze();    //gets(line);  }}void DungeonGenerator::markVisited(int x, int y) {  // add to visited  int n = (y * width) + x;  // has it already been visited?  for(int i = 0; i < visitedCount; i++) {    if(visited[i] == n) return;  }  visited[visitedCount++] = n;  // remove from not visited  for(int i = 0; i < notVisitedCount; i++) {    if(notVisited[i] == n) {      notVisitedCount--;      for(int t = i; t < notVisitedCount; t++) {        notVisited[t] = notVisited[t + 1];      }      return;    }  }}bool DungeonGenerator::isVisited(int x, int y) {  int n = (y * width) + x;  for(int i = 0; i < visitedCount; i++) {    if(visited[i] == n) return true;  }  return false;}void DungeonGenerator::nextNotVisited(int *x, int *y) {  // are there no more unvisited locations?  if(notVisitedCount <= 0) {    *x = *y = -1;    return;  }  // get a random location  int index = (int) ((double)notVisitedCount * rand()/RAND_MAX);  int n = notVisited[index];  // remove from visited areas  notVisitedCount--;  for(int i = index; i < notVisitedCount; i++) {    notVisited[i] = notVisited[i + 1];  }  // break up into x,y coordinates  *y = n / width;  *x = n % width;  // add it to visited  visited[visitedCount++] = n;}void DungeonGenerator::nextVisited(int *x, int *y) {  // are there no visited locations?  if(visitedCount <= 0) {    *x = *y = -1;    return;  }  // get a random location  int index = (int) ((double)visitedCount * rand()/RAND_MAX);  int n = visited[index];  // break up into x,y coordinates  *y = n / width;  *x = n % width;}int DungeonGenerator::initDirections() {  // init all available directions  dirCount = DIR_COUNT;  for(int i = 0; i < dirCount; i++) {    dirs[i] = i;  }  return dirs[(int) ((double)dirCount * rand()/RAND_MAX)];}int DungeonGenerator::nextDirection() {  if(dirCount <= 0) return -1;  int index = (int) ((double)dirCount * rand()/RAND_MAX);  int dir = dirs[index];  dirCount--;  for(int i = index; i < dirCount; i++) {    dirs[i] = dirs[i + 1];  }  return dir;}void DungeonGenerator::printMaze() {  printf("---------------------------------------\n");  int c = 0;  for(int y = 0; y < height; y++) {        for(int i = 0; i < 3; i++) {      for(int x = 0; x < width; x++) {          switch(i) {            case 0: // top row              if((nodes[x][y] & N_PASS)) {                printf(" | ");              } else {                printf("   ");              }              break;                               case 1:              if((nodes[x][y] & W_PASS)) {                printf("-");                            } else {                printf(" ");              }              if(nodes[x][y] == UNVISITED)                printf(" ");              else if(nodes[x][y] & ROOM)                printf("*");              else                printf("O");                        if((nodes[x][y] & E_PASS)) {                printf("-");              } else {                printf(" ");              }              break;            case 2: // bottom row              if((nodes[x][y] & S_PASS)) {                printf(" | ");              } else {                printf("   ");              }              break;          }                c++;      }      printf("\n");    }    c++;      }  printf("---------------------------------------\n");}// draw a pre-rendered location on the mapvoid DungeonGenerator::constructMaze(int locationIndex) {  // create the rooms  roomCount = location[locationIndex].roomCount;  for(int i = 0; i < location[locationIndex].roomCount; i++) {	room[i].x = location[locationIndex].roomDimension[i][0];	room[i].y = location[locationIndex].roomDimension[i][1];	room[i].w = location[locationIndex].roomDimension[i][2];	room[i].h = location[locationIndex].roomDimension[i][3];  }  // turn location into nodes  for(int y = 0; y < location[locationIndex].h; y++) {	for(int x = 0; x < location[locationIndex].w; x++) {	  char c = location[locationIndex].map[y][x];	  int nx = location[locationIndex].x + x;	  int ny = location[locationIndex].y + y;	  if(nx >= width || ny >= height) {		cerr << "Warning: location doesn't fit on map! location:" << 		  location[locationIndex].w << "," << location[locationIndex].h << 		  " map:" << width << "," << height << endl;		continue;	  }	  switch(c) {	  case '#': case 'n': case 's': case 'e': case 'w': nodes[nx][ny] = ROOM; break;	  case '+': nodes[nx][ny] = PASSAGE; break;	  default: nodes[nx][ny] = UNVISITED;	  }	  // open every side for now	  if(nodes[nx][ny] != UNVISITED) nodes[nx][ny] |= (N_PASS | S_PASS | W_PASS | E_PASS);	  // add door	}  }  // build walls  for(int y = 0; y < location[locationIndex].h; y++) {	for(int x = 0; x < location[locationIndex].w; x++) {	  char c = location[locationIndex].map[y][x];	  int nx = location[locationIndex].x + x;	  int ny = location[locationIndex].y + y;	  if(nx >= width || ny >= height) {		cerr << "Warning: location doesn't fit on map! location:" << 		  location[locationIndex].w << "," << location[locationIndex].h << 		  " map:" << width << "," << height << endl;		continue;	  }	  switch(c) {	  case '#': case '+':		break;	  case 'n': 		nodes[nx][ny] |= N_DOOR; 		break;	  case 's': 		nodes[nx][ny] |= S_DOOR; 		break;	  case 'e': 		nodes[nx][ny] |= E_DOOR; 		break;	  case 'w': 		nodes[nx][ny] |= W_DOOR; 		break;	  }	}  }  // seal off some walls  for(int y = 0; y < location[locationIndex].h; y++) {	for(int x = 0; x < location[locationIndex].w; x++) {	  //char c = location[locationIndex].map[y][x];	  int nx = location[locationIndex].x + x;	  int ny = location[locationIndex].y + y;	  if(nx >= width || ny >= height) {		cerr << "Warning: location doesn't fit on map! location:" << 		  location[locationIndex].w << "," << location[locationIndex].h << 		  " map:" << width << "," << height << endl;		continue;	  }	  if(nodes[nx][ny] != UNVISITED) {		if(!(nodes[nx][ny] & W_DOOR) &&		   (!nx || nodes[nx - 1][ny] == UNVISITED || 			((nodes[nx][ny] & ROOM) && !(nodes[nx - 1][ny] & ROOM)) || 			(!(nodes[nx][ny] & ROOM) && (nodes[nx - 1][ny] & ROOM) && !(nodes[nx - 1][ny] & E_DOOR)))) {		  nodes[nx][ny] &= (0xffff - W_PASS);		}		if(!(nodes[nx][ny] & E_DOOR) && 		   (nx >= width - 1 || nodes[nx + 1][ny] == UNVISITED || 			((nodes[nx][ny] & ROOM) && !(nodes[nx + 1][ny] & ROOM)) || 			(!(nodes[nx][ny] & ROOM) && (nodes[nx + 1][ny] & ROOM) && !(nodes[nx + 1][ny] & W_DOOR)))) {		  nodes[nx][ny] &= (0xffff - E_PASS);		}		if(!(nodes[nx][ny] & N_DOOR) && 		   (!ny || nodes[nx][ny - 1] == UNVISITED ||			((nodes[nx][ny] & ROOM) && !(nodes[nx][ny - 1] & ROOM)) || 			(!(nodes[nx][ny] & ROOM) && (nodes[nx][ny - 1] & ROOM) && !(nodes[nx][ny - 1] & S_DOOR)))) {		  nodes[nx][ny] &= (0xffff - N_PASS);		}		if(!(nodes[nx][ny] & S_DOOR) && 		   (ny >= height - 1 || nodes[nx][ny + 1] == UNVISITED || 			((nodes[nx][ny] & ROOM) && !(nodes[nx][ny + 1] & ROOM)) || 			(!(nodes[nx][ny] & ROOM) && (nodes[nx][ny + 1] & ROOM) && !(nodes[nx][ny + 1] & N_DOOR)))) {		  nodes[nx][ny] &= (0xffff - S_PASS);		}	  }	}  }  // other settings  monsters = location[locationIndex].monsters;}void DungeonGenerator::updateStatus() {  glLoadIdentity();  //  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );  //  glClearColor( 0, 0, 0, 0 );  glDisable( GL_DEPTH_TEST );  glDepthMask(GL_FALSE);  glDisable( GL_BLEND );  glDisable( GL_CULL_FACE );  glDisable( GL_TEXTURE_2D );  int MAX_STATUS = 12;  int w = 10;    int h = 20;  glColor4f( 0.25f, 0.20f, 0.15f, 0.15f );  glBegin( GL_QUADS );  glVertex3f( 0, 0, 0 );  glVertex3f( 0, 35 + h + 10, 0);  glVertex3f( MAX_STATUS * 2 * w + 20, 35 + h + 10, 0 );  glVertex3f( MAX_STATUS * 2 * w + 20, 0, 0 );  glEnd();  glColor4f(1, 1, 1, 1);  scourge->getSDLHandler()->texPrint(20, 25, "Assembling Dungeon Level...");  for(int i = 0; i < MAX_STATUS; i++) {	if(i < status) glColor4f(0.7f, 0.10f, 0.15f, 1);	else glColor4f(0.5f, 0.5f, 0.5f, 1);	glPushMatrix();	glLoadIdentity();	glTranslatef( i * 2 * w + 20, 35, 0 );	glBegin( GL_QUADS );	glVertex3f( 0, 0, 0 );	glVertex3f( 0, h, 0 );	glVertex3f( w, h, 0 );	glVertex3f( w, 0, 0 );	glEnd();	glPopMatrix();  }  /* Draw it to the screen */  SDL_GL_SwapBuffers( );  status++;  //sleep(1);  glEnable( GL_DEPTH_TEST );  glDepthMask(GL_TRUE);}void DungeonGenerator::toMap(Map *map, ShapePalette *shapePal, int locationIndex) {	 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -