Ejemplo n.º 1
0
/* Gera um novo nivel */
Nivel genNivel(int level, Player* player, Enemy* enemies){

	Nivel nivel;

	clear();
	move(0,0);

	/* Escolhe um tamanho aleatorio para o mapa */
	do{
		nivel.tamI = rand() % 26;
	}while(nivel.tamI < 21);

	do{
		nivel.tamJ = rand() % 51;
	}while(nivel.tamJ < 46);


	int tamI = nivel.tamI;
	int tamJ = nivel.tamJ;

	for(int i = 0; i < tamI; i++){
		for(int j = 0; j < tamJ; j++)
			nivel.mapa[i][j].shown = 0;
	}

	nivel.nivel = level;
	nivel.inimigos = 0;

	/* Gera o mapa aleatoriamente (apenas muros e espacos vazios) */
	genRoom(&nivel);

	/* Inicializa as posicoes do mapa */
	for(int i = 0; i < tamI; i++){
		for(int j = 0; j < tamJ; j++){

			if(nivel.mapa[i][j].shown == 1){
				nivel.mapa[i][j].used = 1;
				nivel.mapa[i][j].enemyIndice = -1;
				nivel.mapa[i][j].itemIndice = -1;
				nivel.mapa[i][j].player = 0;
				nivel.mapa[i][j].wall = 1;
				nivel.mapa[i][j].stairs = 0;
				nivel.mapa[i][j].quantItems = 0;
			}

			else{
				nivel.mapa[i][j].used = 0;
				nivel.mapa[i][j].enemyIndice = -1;
				nivel.mapa[i][j].itemIndice = -1;
				nivel.mapa[i][j].player = 0;
				nivel.mapa[i][j].wall = 0;
				nivel.mapa[i][j].stairs = 0;
				nivel.mapa[i][j].quantItems = 0;
			}
		}
	}

	/* Posiciona a escada para o proximo nivel*/
	int stairsI, stairsJ;

	do{
		stairsI = rand() % tamI;
		stairsJ = rand() % tamJ;
	}while(nivel.mapa[stairsI][stairsJ].used == 1);

	nivel.mapa[stairsI][stairsJ].used = 1;
	nivel.mapa[stairsI][stairsJ].stairs = 1;

	for(int i = stairsI - 1; i <= stairsI + 1; i++){
		for(int j = stairsJ - 1; j <= stairsJ + 1; j++){
			if(nivel.mapa[i][j].wall == 1){
				if((i > 0) && (i < tamI - 1) && (j > 0) && (j < tamJ - 1)){
					nivel.mapa[i][j].used = 0;
					nivel.mapa[i][j].wall = 0;
				}
			}
		}
	}

	/* Posiciona boss do nivel */
	int flag = 0;

	if(flag == 0){
		if(stairsI - 1 > 0){
			nivel.mapa[stairsI - 1][stairsJ].enemyIndice = 0;
			nivel.mapa[stairsI - 1][stairsJ].used = 1;
			nivel.inimigos++;
			enemies[0] = createEnemy(1, stairsI - 1, stairsJ, nivel.nivel);
		}

		else
			flag = 1;
	}

	if(flag == 1){
		if(stairsI + 1 < tamI - 1){
			nivel.mapa[stairsI + 1][stairsJ].enemyIndice = 0;
			nivel.mapa[stairsI + 1][stairsJ].used = 1;
			nivel.inimigos++;
			enemies[0] = createEnemy(1, stairsI + 1, stairsJ, nivel.nivel);
		}

		else
			flag = 2;
	}

	if(flag == 2){
		if(stairsJ - 1 > 0){
			nivel.mapa[stairsI][stairsJ - 1].enemyIndice = 0;
			nivel.mapa[stairsI][stairsJ - 1].used = 1;
			nivel.inimigos++;
			enemies[0] = createEnemy(1, stairsI, stairsJ - 1, nivel.nivel);
		}

		else
			flag = 3;
	}

	if(flag == 3){
		if(stairsJ + 1 < tamJ - 1){
			nivel.mapa[stairsI][stairsJ + 1].enemyIndice = 0;
			nivel.mapa[stairsI][stairsJ + 1].used = 1;
			nivel.inimigos++;
			enemies[0] = createEnemy(1, stairsI, stairsJ + 1, nivel.nivel);
		}
	}

	/* Posiciona o jogador e garante que ele nao esta encostado em um muro (isso pode atrapalhar movimento em corredores) */
	do{
		(*player).y = rand() % tamI;
		(*player).x = rand() % tamJ;

	}while((nivel.mapa[player->y][player->x].used == 1) || (!distancia(player->y, player->x, stairsI, stairsJ, tamI * tamJ)));


	nivel.mapa[player->y][player->x].used = 1;
	nivel.mapa[player->y][player->x].player = 1;
	nivel.mapa[player->y][player->x].stairs = -1;

	for(int i = player->y - 1; i <= player->y + 1; i++){
		for(int j = player->x - 1; j <= player->x + 1; j++){
			if(nivel.mapa[i][j].wall == 1){
				if((i > 0) && (i < tamI - 1) && (j > 0) && (j < tamJ - 1)){
					nivel.mapa[i][j].used = 0;
					nivel.mapa[i][j].wall = 0;
				}
			}
		}
	}

	enemyPositions(nivel, enemies);
	return nivel;
}
Ejemplo n.º 2
0
void WorldGenerator::genLevelBlueprint( Level& level, Room* rooms, short roomCount )
{
    //Find the center to start so we can generate in any direction
    WallSide wallSide = (WallSide)mRand.gen(0, WallSide::Right + 1 );
    WallSide prevWallSide = (WallSide)((wallSide + 2) % 4);
    int attachedX = roomCount * ( ROOM_MAX_DIMENSION + 3 );
    int attachedY = roomCount * ( ROOM_MAX_DIMENSION + 3 );
    int attempts = 0;
    int minX = -1;
    int minY = -1;
    int maxX = -1;
    int maxY = -1;

    //Generate the rooms
    for(int i = 0; i < roomCount; i++){
        //If we have attempted and failed to many times, reset and regen
        if( attempts > WORLD_GEN_ATTEMPTS ){
            //RESET EVERYTHING and start overrr
            wallSide = (WallSide)mRand.gen(0, WallSide::Right + 1 );
            prevWallSide = (WallSide)((wallSide + 2) % 4);
            attachedX = roomCount * ( ROOM_MAX_DIMENSION + 3 );
            attachedY = roomCount * ( ROOM_MAX_DIMENSION + 3 );
            minX = -1;
            minY = -1;
            maxX = -1;
            maxY = -1;

            //Reset all doors
            for(int r = 0; r <= i; r++){
                for(int d = 0; d < ROOM_MAX_DOORS; d++){
                    rooms[r].doors[d].x = -1;
                    rooms[r].doors[d].y = -1;
                    rooms[r].doors[d].essential = false;
                }
            }

            i = -1;
            attempts = 0;

            continue;
        }

        genRoom( wallSide, attachedX, attachedY, rooms[ i ] );

        //If room collides with another room, try again to generate
        bool collidesWithOtherRoom = false;

        for(int p = 0; p < i; p++){
            //Top Left
            if( rooms[i].left >= rooms[p].left &&
                rooms[i].left <= rooms[p].right &&
                rooms[i].top >= rooms[p].top &&
                rooms[i].top <= rooms[p].bottom ){
                collidesWithOtherRoom = true;
                break;
            }

            //Top Right
            if( rooms[i].right >= rooms[p].left &&
                rooms[i].right <= rooms[p].right &&
                rooms[i].top >= rooms[p].top &&
                rooms[i].top <= rooms[p].bottom ){
                collidesWithOtherRoom = true;
                break;
            }

            //Bottom Left
            if( rooms[i].left >= rooms[p].left &&
                rooms[i].left <= rooms[p].right &&
                rooms[i].bottom >= rooms[p].top &&
                rooms[i].bottom <= rooms[p].bottom ){
                collidesWithOtherRoom = true;
                break;
            }

            //Bottom Right
            if( rooms[i].right >= rooms[p].left &&
                rooms[i].right <= rooms[p].right &&
                rooms[i].bottom >= rooms[p].top &&
                rooms[i].bottom <= rooms[p].bottom ){
                collidesWithOtherRoom = true;
                break;
            }
        }

        if( collidesWithOtherRoom ){
            attempts++;
            i--;
            continue;
        }

        //Generate a door along each wall if there is a room on the other side
        //The door along wallSide is always unScrubable
        //We only generate doors after the first room has been genned
        if( i > 0 ){
            genDoors( rooms, i, rooms[ i ], rooms[ i - 1 ], wallSide );
        }

        prevWallSide = (WallSide)((wallSide + 2) % 4);
        wallSide = prevWallSide;

        if( rooms[ i ].type == Room::Hallway ){
            wallSide = (WallSide)((prevWallSide + 2) % 4);
        }else{
            //Make sure the gen them differently
            while( prevWallSide == wallSide ){
                wallSide = (WallSide)mRand.gen(0, WallSide::Right + 1 );
            }
        }

        switch( wallSide ){
        case Front:
            attachedY = rooms[ i ].bottom + 2;
            attachedX = mRand.gen( rooms[ i ].left, rooms[ i ].right + 1 );
            break;
        case Left:
            attachedX = rooms[ i ].right + 2;
            attachedY = mRand.gen( rooms[ i ].top, rooms[ i ].bottom + 1 );
            break;
        case Back:
            attachedY = rooms[ i ].top - 2;
            attachedX = mRand.gen( rooms[ i ].left, rooms[ i ].right + 1 );
            break;
        case Right:
            attachedX = rooms[ i ].left - 2;
            attachedY = mRand.gen( rooms[ i ].top, rooms[ i ].bottom + 1 );
            break;
        default:
            break;
        }

        attempts = 0;

        if( minX < 0 ){
            minX = rooms[i].left;
        }

        if( minY < 0 ){
            minY = rooms[i].top;
        }

        if( maxX < 0 ){
            maxX = rooms[i].right;
        }

        if( maxY < 0 ){
            maxY = rooms[i].bottom;
        }

        if( minX > rooms[i].left ){
            minX = rooms[i].left;
        }

        if( maxX < rooms[i].right ){
            maxX = rooms[i].right;
        }

        if( minY > rooms[i].top ){
            minY = rooms[i].top;
        }

        if( maxY < rooms[i].bottom ){
            maxY = rooms[i].bottom;
        }
    }

    //Extend the bounds a bit
    minX-=2;
    minY-=2;

    maxX+=2;
    maxY+=2;

    //Double the scale of the generated space
    level.init( (maxX - minX) * 2, (maxY - minY) * 2, mLevelRanges->roomCeilingHeight.gen( mRand ) );

    //Initialize all to walls
    for( int i = 0; i < level.getWidth(); i++){
        for(int j = 0; j < level.getDepth(); j++){
            level.getBlock( i, j ).setWall( );
        }
    }

    //Convert the rooms from the space level to this level
    for(int i = 0; i < roomCount; i++){
        rooms[i].left -= minX; 
        rooms[i].left *= 2;

        rooms[i].right -= minX; 
        rooms[i].right *= 2;
        rooms[i].right++;

        rooms[i].top -= minY; 
        rooms[i].top *= 2;

        rooms[i].bottom -= minY; 
        rooms[i].bottom *= 2;
        rooms[i].bottom++;

        for(int w = rooms[i].left; w <= rooms[i].right; w++){
            for(int d = rooms[i].top; d <= rooms[i].bottom; d++){
                //Set inside the room to be open
                level.getBlock(w, d).setOpen();

                //Randomize the tile generated
                level.getBlock(w, d).setTileID( mRand.gen(0, 16) );
            }
        }

        //For each created door
        for(int d = 0; d < ROOM_MAX_DOORS; d++){
            if( rooms[i].doors[d].x >= 0 && rooms[i].doors[d].y >= 0 ){
                rooms[i].doors[d].x -= minX;
                rooms[i].doors[d].x *= 2;

                rooms[i].doors[d].y -= minY;
                rooms[i].doors[d].y *= 2;

                if( !rooms[i].doors[d].essential ){
                    continue;
                }
                
                if( d == 2 ){
                    rooms[i].doors[d].y++;
                }

                if( d == 3 ){
                    rooms[i].doors[d].x++;
                }

                //Create and add door
                Level::Door door;
                door.getPosition().x = ( static_cast<float>( rooms[i].doors[d].x ) * 0.3f );
                door.getPosition().y = 0.0f;
                door.getPosition().z = ( static_cast<float>( rooms[i].doors[d].y ) * 0.3f );
                door.setYRotation( static_cast<float>( rooms[i].doors[d].side ) * 3.14159f * 0.5f );
                door.state = Level::Door::State::Closed;
                door.facing = (Level::Direction)( rooms[i].doors[d].side );

                //Offset position by side
                switch( rooms[i].doors[d].side ){
                case 0:
                    door.getPosition().x += 0.3f;
                    break;
                case 1:
                    break;
                case 2:
                    door.getPosition().z += 0.3f;
                    break;
                case 3:
                    door.getPosition().z += 0.3f;
                    door.getPosition().x += 0.3f;
                    break;
                default:
                    break;
                }

                ushort id = level.addDoor( door );
                Level::Door& doorRef = level.getDoor( id );

                //Set pointer to door
                level.getBlock( rooms[i].doors[d].x, rooms[i].doors[d].y ).setDoor( &doorRef );

                switch(d){
                case 0:
                    level.getBlock( rooms[i].doors[d].x, rooms[i].doors[d].y - 1 ).setOpen();
                    break;
                case 1:
                    level.getBlock( rooms[i].doors[d].x - 1, rooms[i].doors[d].y ).setOpen();
                    break;
                case 2:
                    level.getBlock( rooms[i].doors[d].x, rooms[i].doors[d].y + 1 ).setOpen();
                    break;
                case 3:
                    level.getBlock( rooms[i].doors[d].x + 1, rooms[i].doors[d].y ).setOpen();
                    break;
                default:
                    break;
                }
            }
        }
    }
}