Добавлен Nerevar,
опубликован
Реализовал буквально на днях базовую генерацию подземелья,при которой создается случайное количество непересекающихся комнат различного размера,между которыми прокладываются тунели
Ниже измененные файлы с кодом
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.resManager.MainFont);
game.unitManager.LoadUnit(game.resManager,Textures::Skeleton,"Skeleton",128,128,100,game.resManager.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.unitManager.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;
}
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован AsagiriGen