Neverland.Dungeon generation.Begin

» опубликован
Реализовал буквально на днях базовую генерацию подземелья,при которой создается случайное количество непересекающихся комнат различного размера,между которыми прокладываются тунели
Ниже измененные файлы с кодом
» CellManager.h
#include "main.h"
#include "Cell.h"

class CellManager
{

public:
	TileMap tileMap;

void GenRooms()
{
	vector <IntRect> rooms;
	int roomNumbers=0;
	int number=GetRandomInt(13,30);
	int x;
	int y;
	int sizeX;
	int sizeY;
	int minX=4;
	int maxX=15;
	int minY=5;
	int maxY=14;
	int exit=0;
	int bigRooms=0;
	cout<<"NUMBER OF ROOMS IS "<<number<<endl;
while (exit<number)
{
	IntRect room;
	int isContain=0;
	x=GetRandomInt(2,85);
	y=GetRandomInt(2,85);
	sizeX=GetRandomInt(minX,maxX);
	sizeY=GetRandomInt(minY,maxY);
	room=IntRect(Vector2i(x,y),Vector2i(sizeX,sizeY));
	IntRect room2;
	room2=IntRect(Vector2i(x-2,y-2),Vector2i(sizeX+2,sizeY+2));
	for (int i=0;i<roomNumbers;i++)
	{
		if(rooms[i].intersects(room)==true)
			{
				isContain=isContain+1;
			}
	}
		if (isContain==0)
		{
			if (sizeX>=7&&sizeY>=7)
			{
			bigRooms=bigRooms+1;
				if (bigRooms>=8)
				{
					maxX=5;
					maxY=5;
				}
			}
		cout<<"ROOM POSITION IS "<<x<<" "<<y<<endl;
		cout<<"ROOM SIZE IS "<<sizeX<<" "<<sizeY<<endl;
		rooms.push_back(room);
		roomNumbers=roomNumbers+1;
		exit=exit+1;
		//gen room
			for (int xx=0;xx<(sizeX);xx++)
			{
			for (int yy=0;yy<(sizeY);yy++)
			{
				tileMap.UpdateCell(x+xx,y+yy,1,0);
			}
			}
			//gen left line
			for (int yy=0;yy<=(sizeY);yy++)
			tileMap.UpdateCell(x,y+yy,1,2);
			

			//gen right line
			for (int yy=0;yy<=(sizeY);yy++)
			tileMap.UpdateCell(x+sizeX,y+yy,1,2);
			

			//gen top line
			for (int xx=0;xx<=(sizeX);xx++)
			tileMap.UpdateCell(x+xx,y,1,2);
			

			//gen down line
			for (int xx=0;xx<=(sizeX);xx++)
			tileMap.UpdateCell(x+xx,y+sizeY,1,2);
		}
}
exit=0;
//GEN TUNNELS
while (exit<number-1)
{
	IntRect room1=rooms[exit];
	IntRect room2=rooms[exit+1];
	int x1;
	int x2;
	int y1;
	int y2;
	int cx;
	int cy;
	float error=0;
	//1
	x1=GetRandomInt(room1.left,room1.left+room1.width-1);
	y1=GetRandomInt(room1.top,room1.top+room1.height-1);

	x2=GetRandomInt(room2.left,room2.left+room2.width-1);
	y2=GetRandomInt(room2.top,room2.top+room2.height-1);
	
	if (room1.contains(Vector2i(x1,y1))!=true)
		cout<<x1<<" x1| "<<y1<<" y1|| "<<room1.left<<" "<<room1.top<<" "<<room1.width<<" "<<room1.height<<endl;

	if (room2.contains(Vector2i(x2,y2))!=true)
		cout<<x2<<" x2| "<<y2<<" y2|| "<<room2.left<<" "<<room2.top<<" "<<room2.width<<" "<<room2.height<<endl;

//end of gen x1\y1 x2\y2
	cx=x1;
	cy=y1;
//gen road from x1y1 to x2y2
	
while(cx!=x2)
{
	tileMap.UpdateNearWalls(cx,cy,0,2);
	tileMap.UpdateCell(cx,cy,1,0);
	if (cx!=x2)
	{
		if (cx<x2)
		cx=cx+1;
		else if(cx>x2)
		cx=cx-1;
	}
	
}
while (cy!=y2)
{
	tileMap.UpdateNearWalls(cx,cy,0,2);
	tileMap.UpdateCell(cx,cy,1,0);
	if (cy!=y2)
	{
		if (cy<y2)
		cy=cy+1;
		else if(cy>y2)
		cy=cy-1;
	}
	
}

	tileMap.UpdateCell(x1,y1,1,0);
	tileMap.UpdateNearWalls(x1,y1,0,2);
	tileMap.UpdateCell(x2,y2,1,0);
	tileMap.UpdateNearWalls(x2,y2,0,2);
	exit=exit+1;
}

}

void GenCells()
{
	int x=0,y=0;
	for (unsigned int i=0;i<10000;i++)
	{
			if (x<19)
			{
				x=x+1;
			}
			else
			{
				x=0;
			}
			
			if (i%19==0)
			{
				y=y+1;
			}
			tileMap.cells.push_back(Cell(1,x,y,1));

	}
}
};
» Cell.h
#include "main.h"
#include "ResManager.h"

class Cell
{
public:
	unsigned int pathable;
	unsigned int x,y;
	unsigned int textureId;
	Cell(){}

Cell(unsigned int _pathable,unsigned int _x,unsigned int _y,unsigned int _textureId)
{
	pathable=_pathable;
	x=_x;
	y=_y;
	textureId=_textureId;
}

};

class TileMap : public Drawable, public Transformable
{
public:
	VertexArray vertices;
    Texture texture;
	Vector2u tileSize; 
	unsigned int width;
	unsigned int height;
	vector<Cell> cells;

unsigned int IsPathableCell(int x,int y)
{
	return cells[y*width+x].pathable;
}

Vector2f FindPathableCell(int x,int y)
{
	int tx=x;
	int ty=y;
	while(IsPathableCell(tx,ty)==0)
{
	int random=GetRandomInt(0,4);

	if (random==0&&tx+1<100&&ty+1<100)
	{
		tx=tx+1;
		ty=ty+1;
	}
	else if (random==1&&tx-1>=0&&ty-1>=0)
	{
		tx=tx-1;
		ty=ty-1;
	}
	else if (random==2&&tx+1<100&&ty-1>=0)
	{
		tx=tx+1;
		ty=ty-1;
	}
	else if (random==3&&tx-1>=0&&ty+1<100)
	{
		tx=tx-1;
		ty=ty+1;
	}
	else if (random==4&&tx-1>=0&&ty-1>=0)
	{
		tx=tx-1;
		ty=ty-1;
	}
}
	return Vector2f(tx,ty);
}



bool UpdateCell(int x,int y,int newPathable,int newTextureId)
	{
		cells[y*width+x].pathable=newPathable;
		cells[y*width+x].textureId=newTextureId;
		//cout<<x<<" "<<y<<" "<<newPathable<<" "<<newTextureId<<endl;
		int tu = cells[y*width+x].textureId % (texture.getSize().x / tileSize.x);
        int tv = cells[y*width+x].textureId / (texture.getSize().x / tileSize.x);
		
		Vertex* quad = &vertices[(x + y * width) * 4];

		// define its 4 texture coordinates
        quad[0].texCoords = Vector2f(tu * tileSize.x, tv * tileSize.y);
        quad[1].texCoords = Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
        quad[2].texCoords = Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
        quad[3].texCoords = Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
		
		return true;
	}
bool UpdateNearWalls(int x,int y,int newPathable,int newTextureId)
{
	if (cells[(y)*width+x+1].textureId==1)
		UpdateCell(x+1,y,newPathable,newTextureId);

	if (cells[(y+1)*width+x].textureId==1)
		UpdateCell(x,y+1,newPathable,newTextureId);

	if (cells[(y+1)*width+x+1].textureId==1)
		UpdateCell(x+1,y+1,newPathable,newTextureId);

	if (cells[(y-1)*width+x].textureId==1)
		UpdateCell(x,y-1,newPathable,newTextureId);

	if (cells[(y)*width+x-1].textureId==1)
		UpdateCell(x-1,y,newPathable,newTextureId);

	if (cells[(y-1)*width+x-1].textureId==1)
		UpdateCell(x-1,y-1,newPathable,newTextureId);

	if (cells[(y+1)*width+x-1].textureId==1)
		UpdateCell(x-1,y+1,newPathable,newTextureId);

	if (cells[(y-1)*width+x+1].textureId==1)
		UpdateCell(x+1,y-1,newPathable,newTextureId);
return true;
}

bool LoadTileMap(ResManager &resManager,Textures::ID id, Vector2u _tileSize,  unsigned int _width, unsigned int _height)
{
		tileSize=_tileSize;
		width=_width;
		height=_height;

		texture=resManager.Get(id);

        vertices.setPrimitiveType(Quads);
        vertices.resize(width * height * 4);

        for (unsigned int i = 0; i < width; ++i)
            for (unsigned int j = 0; j < height; ++j)
            {
				int tileNumber = cells[i + j * width].textureId;

                int tu = tileNumber % (texture.getSize().x / tileSize.x);
                int tv = tileNumber / (texture.getSize().x / tileSize.x);

                Vertex* quad = &vertices[(i + j * width) * 4];

                quad[0].position = Vector2f(i * tileSize.x, j * tileSize.y);
                quad[1].position = Vector2f((i + 1) * tileSize.x, j * tileSize.y);
                quad[2].position = Vector2f((i + 1) * tileSize.x, (j + 1) * tileSize.y);
                quad[3].position = Vector2f(i * tileSize.x, (j + 1) * tileSize.y);

                quad[0].texCoords = Vector2f(tu * tileSize.x, tv * tileSize.y);
                quad[1].texCoords = Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                quad[2].texCoords = Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                quad[3].texCoords = Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
            }

        return true;
}

virtual void draw(RenderTarget& target, RenderStates states) const
    {
        
        states.transform *= getTransform();

        states.texture = &texture;

        target.draw(vertices, states);
    }
    
};
» main.cpp
#include "main.h"
#include "Game.cpp"


int main()
{
	Game game;
	game.Init();
	
	game.cellManager.GenCells();

	game.cellManager.tileMap.LoadTileMap(game.resManager,Textures::Tileset,Vector2u(64,64),100,100);

	game.cellManager.GenRooms();

	game.unitManager.LoadUnit(game.resManager,Textures::Hero,"Nerevar",64,64,100,game.resManag​er.MainFont);
	game.unitManager.LoadUnit(game.resManager,Textures::Skeleton,"Skeleton",128,128,100,game.r​esManager.MainFont);
	

for (unsigned int i=0;i<game.unitManager.count;i++)
{
	if (game.cellManager.tileMap.IsPathableCell(game.unitManager.units[i].sprite.getPosition().x/64,game.un​itManager.units[i].sprite.getPosition().y/64)==0)
	{
	Vector2f v=game.cellManager.tileMap.FindPathableCell(game.unitManager.units[i].sprite.getPosition().x/64,game​.unitManager.units[i].sprite.getPosition().y/64);
	game.unitManager.units[i].sprite.setPosition(v.x*64,v.y*64);
	}
}

	while (game.window.isOpen())
    {

		game.Update();
		
		game.Draw();

    }
	

    return 0;
}

 

Просмотров: 1 801

Raised #1 - 6 лет назад 0
Как думаешь использовать?
Nerevar #2 - 6 лет назад 0
RiseD_Konst:
Как думаешь использовать?
в смысле?) я ведь все делаю для игры своей и используется оно в ней
в архиве можно запустить и посмотреть
прикреплены файлы
Raised #3 - 6 лет назад 0
Nerevar, пишет мол отсутствует какой-то длл.
YureZzZ #5 - 6 лет назад 0
О, я тоже рогалик пытаюсь сделать, и у меня беда с "поиском пути". Пытаюсь изобрести велосипед и что-то не совсем выходит. Уже подумываю взять существующий и реализовать.
Кет #6 - 6 лет назад 0
YureZzZ, дык так оно и надо делать, ящитаю.
Zahanc #7 - 6 лет назад 0
Брать готовое — не интересно.
GeneralElConsul #8 - 6 лет назад (отредактировано ) 0
YureZzZ, дык так оно и надо делать, ящитаю.
Кет,
Брать готовое — не интересно.
Кто-то должен сказать, что в этом нужна золотая середина.)
Nerevar #9 - 6 лет назад 0
YureZzZ, не обязательно брать готовое,в инете можно ведь посмотреть алгоритмы поиска путей,типа A* и реализовать у себя самостоятельно
GeneralElConsul #10 - 6 лет назад 0
Писано на ++, а название топика в стиле C#)