1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > php制作随机地图 随机生成Roguelike游戏地图算法

php制作随机地图 随机生成Roguelike游戏地图算法

时间:2022-01-20 13:22:55

相关推荐

php制作随机地图 随机生成Roguelike游戏地图算法

有很多相关的roguelike资料 相当有价值

首先随机生成一套地图世界有几个概念。 数据结构 1.world 2.map 3.room 4.corridor

地图的类型也有很多种 1.maze 2.dungeon 3.island 4.cave 5.castle

生成房间的算法也分为很多类别 我先实现了 最简单的一个地图类型 类似于dungeon的地图类型

生成的数据大概是这样

算法逻辑 1.在world创建room 2.判断room是否碰撞 碰撞重新生成 3.房间生成门 4.查找最近的房间 使用astar 生成房间直接连通的街道。

一些c#代码

public void generatePCGBasic(byte[,] g) { base.generatePCG(g); // Init grid this.initRooms(); // Initialize rooms //this.initCorridors(); // Initialize corridors }

public void initRooms()

{

this.rooms = new ArrayList();

//room_num = 1;

// New room arraylist

//Log.info("room_num",this.room_num);

for (int n = 0; n < this.room_num; n++)

{

this.room_blocked = false;

// Unblock

Room rm = new Room(pcgrid_width, pcgrid_height, this.room_base, this.room_radix, this.corridor_num);

// Create new room

this.room_blocked = this.blockRoom(rm);

// Check if room is blocked

if (this.room_blocked)

{

n--;

// Remake room

this.redo--;

// Stops if taking too long

if ((this.redo == 0))

{

this.room_num--;

this.redo = 1000;

// Recursion limit

}

}

else {

//Log.info("room_blocked",this.room_blocked);

this.rooms.Add(rm);

// Create room

for (int j = rm.room_y1; (j <= rm.room_y2); j++)

{

for (int i = rm.room_x1; (i <= rm.room_x2); i++)

{

pcgrid[i, j] = 1;

}

}

// Create room walls

for (int i = rm.wall_x1; (i <= rm.wall_x2); i++)

{

if (pcgrid[i, rm.wall_y1] != 1)

{

pcgrid[i, rm.wall_y1] = 2;

}

if (pcgrid[i, rm.wall_y2] != 1)

{

pcgrid[i, rm.wall_y2] = 2;

}

}

for (int j = rm.wall_y1; (j <= rm.wall_y2); j++)

{

if (pcgrid[rm.wall_x1, j] != 1)

{

pcgrid[rm.wall_x1, j] = 2;

}

if (pcgrid[rm.wall_x2, j] != 1)

{

pcgrid[rm.wall_x2, j] = 2;

}

}

// Place openings

for (int k = 0; (k < rm.opening_num); k++)

{

if ((pcgrid[rm.opening[k, 0], rm.opening[k, 1]] != 1))

{

pcgrid[rm.opening[k, 0], rm.opening[k, 1]] = 3;

}

}

/*

var sb = new StringBuilder();

sb.Append("\n");

for (int i = 0; i < pcgrid.GetLength(0); i++)

{

for (int j = 0; j < pcgrid.GetLength(1); j++)

{

sb.Append( pcgrid[i, j] );

}

sb.Append("\n");

}

Log.info(sb.ToString());

*/ }

}

}

public bool blockRoom(Room rm)

{

// If outside of grid

if ((!bounded(rm.wall_x1, rm.wall_y1)

|| (!bounded(rm.wall_x2, rm.wall_y1)

|| (!bounded(rm.wall_x1, rm.wall_y2)

|| !bounded(rm.wall_x2, rm.wall_y2)))))

{

return true;

}

// If blocked by another room

if ((this.room_type != 3))

{

for (int i = (rm.wall_x1 - 1); (i

< (rm.wall_x2 + 1)); i++)

{

// Check upper and lower bound

if ((bounded(i, (rm.wall_y1 - 1))

&& !blocked(i, (rm.wall_y1 - 1), 0)))

{

return true;

}

if ((bounded(i, (rm.wall_y2 + 1))

&& !blocked(i, (rm.wall_y2 + 1), 0)))

{

return true;

}

}

for (int j = (rm.wall_y1 - 1); (j

< (rm.wall_y2 + 1)); j++)

{

// Check left and right bound

if ((bounded((rm.wall_x1 - 1), j)

&& !blocked((rm.wall_x1 - 1), j, 0)))

{

return true;

}

if ((bounded((rm.wall_x2 + 1), j)

&& !blocked((rm.wall_x2 + 1), j, 0)))

{

return true;

}

}

}

return false;

}

public void initCorridors() {

if ((this.room_type != 3)) {

for (int i = 0; (i < this.rooms.Count); i++) {

// Go through each room and connect its first opening to the first opening of the next room

Room rm1 = ((Room)(this.rooms[i]));

Room rm2;

if ((i

== (this.rooms.Count - 1))) {

rm2 = ((Room)(this.rooms[0]));

}

else {

rm2 = ((Room)(this.rooms[(i + 1)]));

}

// If not last room

// Connect rooms

//basicAStar(pcgrid, rm1.opening[0,0], rm1.opening[0,1], rm2.opening[0,0], rm2.opening[0,1], this.corridor_weight, this.turning_weight);

// Random tunneling

for (int j = 1; (j < rm1.opening_num); j++) {

this.tunnelRandom(rm1.opening[j,0], rm1.opening[j,1], rm1.opening[j,2], 3);

}

}

}

else {

// If complex

Room rm1 = ((Room)(this.rooms[0]));

for (int i = 1; (i < this.rooms.Count); i++) {

// Go through each room and connect its first opening to the first opening of the first room

Room rm2 = ((Room)(this.rooms[i]));

// Connect rooms

//basicAStar(pcgrid, rm1.opening[0,0], rm1.opening[0,1], rm2.opening[0,0], rm2.opening[0,1], this.corridor_weight, this.turning_weight);

}

// Random tunneling

for (int i = 0; (i < this.rooms.Count); i++) {

Room rm3 = ((Room)(this.rooms[i]));

for (int j = 1; (j < rm3.opening_num); j++) {

this.tunnelRandom(rm3.opening[j,0], rm3.opening[j,1], rm3.opening[j,2], 3);

}

}

}

}

public void tunnel(int x, int y, int dir)

{

if (((pcgrid[x, y] == 2)

|| (pcgrid[x, y] == 3)))

{

pcgrid[x, y] = 3;

}

// If on top of wall or door

pcgrid[x, y] = 4;

// Set cell to corridor

this.tunnelRandom(x, y, this.shuffleDir(dir, 85), 3);

// Randomly choose next cell to go to

}

public void tunnelRandom(int x, int y, int dir, int iteration)

{

if ((iteration == 0))

{

return;

}

// End of recursion iteration

// Choose a random direction and check to see if that cell is occupied, if not, head in that direction

switch (dir)

{

case 0:

if (!this.blockCorridor(x, (y - 1), 0))

{

this.tunnel(x, (y - 1), dir);

}

// North

this.tunnelRandom(x, y, this.shuffleDir(dir, 0), (iteration - 1));

// Try again

break;

case 1:

if (!this.blockCorridor((x + 1), y, 1))

{

this.tunnel((x + 1), y, dir);

}

// East

this.tunnelRandom(x, y, this.shuffleDir(dir, 0), (iteration - 1));

// Try again

break;

case 2:

if (!this.blockCorridor(x, (y + 1), 0))

{

this.tunnel(x, (y + 1), dir);

}

// South

this.tunnelRandom(x, y, this.shuffleDir(dir, 0), (iteration - 1));

// Try again

break;

case 3:

if (!this.blockCorridor((x - 1), y, 1))

{

this.tunnel((x - 1), y, dir);

}

// West

this.tunnelRandom(x, y, this.shuffleDir(dir, 0), (iteration - 1));

// Try again

break;

}

}吃的

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。