Beispiel #1
0
void Level::generate(GameState* state)
{
	// Create the starting room.
	rooms.push_back(new Room((m_width/2)-10, (m_height/2)-10, 10, 10, nullptr));
	
	// Add it to the list of rooms.
	Room* currentRoom = rooms.back();

	// Generate the room.
	currentRoom->fill(tiles);
	
	// Create other rooms.
	while( true )
	{
		// Get a direction to generate a new room in.
		Direction direction = currentRoom->getPossibleDirection();

		// Setup variables to generate doors and rooms.
		int doorAX, doorAY, roomX, roomY, roomW, roomH;
		
		// Get Width and Height of the room.
		roomW = 5 + rand() % 10;
		roomH = 5 + rand() % 10;
		
		// Depending on direction, roomX and roomY is altered, as with Doors.
		switch((int)direction)
		{
			case 0:
				doorAX = (currentRoom->getX()+1) + rand() % (currentRoom->getWidth()-2);
				doorAY = currentRoom->getY();
				
				roomX = doorAX - roomW/2;
				roomY = doorAY - roomH + 1;
			break;
				
			case 1:
				doorAX = (currentRoom->getX()+1) + rand() % (currentRoom->getWidth()-2);
				doorAY = currentRoom->getY()+currentRoom->getHeight()-1;
				
				roomX = doorAX - roomW/2;
				roomY = doorAY;
			break;
				
			case 2:
				doorAX = currentRoom->getX();
				doorAY = (currentRoom->getY()+1) + rand() % (currentRoom->getHeight()-2);
				
				roomX = doorAX - roomW + 1;
				roomY = doorAY - roomH/2;
			break;
				
			case 3:
				doorAX = currentRoom->getX()+currentRoom->getWidth()-1;
				doorAY = (currentRoom->getY()+1) + rand() % (currentRoom->getHeight()-2);
				
				roomX = doorAX;
				roomY = doorAY - roomH/2;
			break;
			
			default:
			break;
		}
		
		// Adjust coordinates accordingly, else room placement will freak out.
		if( roomY < 0 ) roomY = 0;
		if( roomX < 0 ) roomX = 0;
		if( roomX >= static_cast<int>(m_width) ) roomX = m_width - 1;
		if( roomY >= static_cast<int>(m_height) ) roomX = m_height - 1;
		
		// Make the new room.
		Room* newRoom = new Room(roomX, roomY, roomW, roomH, currentRoom);
		
		// Check if it's valid placement.
		if(newRoom->validPlacement(tiles, m_width, m_height))
		{
			// Fill the tiles with the room.
			newRoom->fill(tiles);
			fillAreaWithFog(newRoom);
			
			// Add the room to the vector.
			rooms.push_back(newRoom);
			
			// Remove the succeded Direction, because it's not available again.
			//currentRoom->removeDirection(direction);
			
			// Remove the opposite direction of current room.
			
			switch((int)direction)
			{
				case 0: newRoom->removeDirection(Direction::DOWN);  break;
				case 1: newRoom->removeDirection(Direction::UPP);   break;
				case 2: newRoom->removeDirection(Direction::RIGHT); break;
				case 3: newRoom->removeDirection(Direction::LEFT);  break;
			}
			
			// Set the current room to the new room.
			currentRoom = newRoom;
			
			// Alter the supposedly connected walls so a pathway is formed.
			Door* door = static_cast<Door*>( EntityFactory::get()->createEntity("door") );
			door->setX(doorAX*32);
			door->setY(doorAY*32);
			door->setConnectedRoom(currentRoom);
			door->setFogmap(&m_fogmap);
			
			tiles[doorAX][doorAY] = 1;
		}
		else
		{
			// Remove the room that failed.
			delete newRoom;

			// Remove the direction that failed
			currentRoom->removeDirection(direction);
			
			// If there are no more directions to go in the current room.
			if(currentRoom->possibleDirections() == 0)
			{
				// Move back one room and try to generate rooms in other directions
				Room* connectedRoom = currentRoom->getConnected();
				
				// If the connected room is start room then there is NO more to be done.
				if(connectedRoom == nullptr)
				{
					break;
				}
				
				// Set the current room to the room before.
				currentRoom = connectedRoom;
			}
		}
		
	}
	rooms[0]->showRoom(m_fogmap);
	
	int stairIndex = rand() % rooms.size();
	float stx = rooms[stairIndex]->getX() + rooms[stairIndex]->getWidth() / 2;
	float sty = rooms[stairIndex]->getY() + rooms[stairIndex]->getHeight()/ 2;
	
	Stairway* stairway = static_cast<Stairway*>(EntityFactory::get()->createEntity("stairway"));
	stairway->setX(stx*32);
	stairway->setY(sty*32);
	stairway->setGameState(state);
	
	std::ofstream ofs;
	ofs.open("level.txt");
	
	for( unsigned int y = 0; y < m_height; y++ )
	{
		for( unsigned int x = 0; x < m_width; x++ )
		{
			if( tiles[x][y] == 0)
				ofs << " ";
			else if ( tiles[x][y] == 2 || tiles[x][y] == 3 || tiles[x][y] == 4 )
				ofs << "W";
			else if ( tiles[x][y] == 5 )
				ofs << "D";
			else
				ofs << "#";
		}
		ofs << "\n";
	}
	ofs.close();
}