题
我试图为一个项目完成一个RPG游戏,但不知道如何制作游戏地图。 它不需要是图形的,但整个地图和每个图块的代码必须正确。
到目前为止,我考虑使用包含所有链接图块的ArrayList来制作非母版地图(作为教授的请求)。
public abstract class Casella {
/**
* @uml.property name="tabellone"
* @uml.associationEnd multiplicity="(1 1)" inverse="casella:Tabellone"
* @uml.association name="contains"
*/
private int id;
private boolean free = true;
private List adjacent;
private List items;
private Tabellone tabellone = null;
public void in(){
free = false;
}
public void out(){
free = true;
}
}
这是单个磁贴的代码(有3个扩展它的类)。我仍然不知道如何组合并生成地图。
感谢您的时间。
解决方案 6
我通过使用邻接列表来管理这个。 每个单元格都有一个包含相邻单元格索引的ArrayList。那些索引是所述单元格在单元格的映射ArrayList中具有的索引。
其他提示
不要从实现开始,从您希望如何使用地图开始。这将为您提供一些约束如何实现它。例如:
绘制地图时,如何访问地图?通过协调?或者通过“从瓷砖X向西走”?
[编辑]我建议从RPG游戏的主循环开始。你需要将字符/标记放在某处(即它需要与图块有某种关系)。
然后你需要移动角色。角色必须能够检查当前的牌(对手,物品,类型)。它需要一种方法来了解它是如何移动的(即右边有一堵墙吗?)
这为您提供了一个地图界面:它为游戏中的其他对象渲染的服务。当您了解接口需要提供的内容时,应该可以了解如何实现映射(数据结构)。
至于生成地图,使用随机数生成器加上一些“常识”。看看相邻的瓷砖:当它们都是城市时,这个瓷砖也可能是城市。平原也一样。丘陵是一些奇特的物品,它们最不常见。
运行此代码,将地图打印为ASCII(“C”ity,“P”lain,“H”ill)以查看是否有效。
要在不使用矩阵的情况下生成这样的地图,我建议从中心区块开始,然后使用修改后的广度优先搜索算法向外填充地图。首先,我们需要比相邻瓷砖列表更好的东西。您可以简单地使用四个变量,每个变量用于存储下一个磁贴的每个方向,如下所示:
private Tabellone up = null;
private Tabellone down = null;
private Tabellone left = null;
private Tabellone right = null;
假设我们从最中心的瓷砖开始。您现在要做的就是弄清楚有多少方向是null,并为每个方向创建一个新的Tablellone对象,确保在当前对象中设置每个变量并在创建的对象中设置相应的相反变量
Tabellone adj = new Tabellone();
up = adj;
adj.setDown(this);
一旦您填写了此图块上的所有方向,您就可以选择已创建的其他图块之一并执行相同的操作。这是广度优先搜索算法的用武之地。您可以使用队列浏览您创建的每个图块并填写指示。要使算法停止,只需设置要创建的切片数量限制,并使用计数器跟踪已创建的切片数量。
int count = 0;
ArrayList<Tabellone> queue = new ArrayList<Tabellone>()
queue.add(/*center tile*/);
while (count < 100) { //if we want 100 tiles
//take out the center tile from the beginning of the array list, create a tile for each direction and add those tiles to the array list, then increment count by 1.
}
注意:此算法将创建一个菱形地图,如果你想要一个正方形,你需要为每个对角线方向都有一个变量。
当然,如果这看起来比你想要的复杂一点,我建议使用坐标系。
墙壁,袋子和区域是特殊的容器,可以容纳游戏的所有墙壁,袋子和区域。
private String level =
" ######\n"
+ " ## #\n"
+ " ##$ #\n"
+ " #### $##\n"
+ " ## $ $ #\n"
+ "#### # ## # ######\n"
+ "## # ## ##### ..#\n"
+ "## $ $ ..#\n"
+ "###### ### #@## ..#\n"
+ " ## #########\n"
+ " ########\n";
这是游戏的等级。除了空间,有五个字符。哈希(#)代表墙。美元($)代表要移动的方框。点(。)字符代表我们必须移动框的位置。 at字符(@)是推箱子。最后,新行字符(\ n)开始了一个新的世界行。
速度或记忆是否是这个项目的一大问题?如果没有,为什么不使用二维阵列?
像
这样的东西Casella map [][] = new Casella[xSize][ySize];
从这里可以很容易地概念化,只需将其描绘成一个excel电子表格,其中每个单元格都是地图上的图块。
你前进的方式很好,但有时难以概念化。你有一个相邻的瓷砖列表。因此,在创建地图时,您可以从某处开始,可能是左上角,然后从那里开始。
您可以使用嵌套for循环来设置地图,并帮助确定边缘项。
for(int i = 0; i < XSIZE ; ++i)
for(int j = 0; j < YSIZE ; ++j)
if(j==0) //found left edge (i.e. no adjacent ones to the left)
if(j==(YSIZE)) //found right edge (you get the picture)
使用循环和检查边缘的关键是,除了边缘之外,你需要为每个瓷砖向后和向前,向上和向下链接,在那里你将有2或3个链接而不是4。
代码需要正确,实际上并不是功能要求,因此如果不了解更多关于游戏/地图的信息,很难准确说出什么是正确的。
假设你有一个具有X个图块且没有有序邻接的地图,非基质解决方案是最好的,一个常见的解决方案就是使用非对称邻接的邻接列表或对称邻接的入射列表将其建模为图形。如果您使用入射列表,则需要包含边连接顶点的边对象,如果使用邻接列表a multimap 可能很酷。
如果你想要一个有序邻接的非矩阵解决方案,AlbertoPL可以为你提供解决方案。
假设你的地图有X个瓷砖宽,Y个瓷砖很高,而且彼此相邻的瓷砖是相邻的,所以每个瓷砖最多有4个和2个相邻的瓷砖,你可以使用矩阵来访问瓷砖并且还通过matricial adjacency代表邻接。想法是地图[Y] [X]与地图[Y + 1] [X]和地图[Y] [X + 1]相反并且相反。 如果tile [Y + 1] [X + 1]与tile [Y] [X]相邻,则该解决方案还可以适合max 6和min 3 tile邻接。 这样做的好处是你可以轻松地解析地图,因为它有2个维度,所以很自然地像这样建模。 缺点是,一旦设置了瓷砖,您就无法在不更改矩阵的情况下更改其邻接关系。因为这不是你教授建议你可能不想这样做的,但如果你有(静态的)有序邻接,这可能是最简单的方法。
如果是基于图块的地图,则每个房间与其相邻房间具有固定关系。您可能不需要担心坐标(尽管如果瓷砖是正方形可能更简单),但您需要担心方向。
如果瓷砖是方形的,那么您可能需要关注基本方向(n,s,e,w)。如果它们是十六进制图块,则可以对出口编号为1-6(可能具有静态最终常量)。然后,每个相邻的图块可以与它的出口链接到该图块。
如 Aaron 所述,您需要先确定maping坐标的位置。
但是你不受X-Y-Z坐标系的限制。例如,每个图块可以链接到地图上的任何其他图块。这一切都取决于你想要如何构建它。
你说你正在构建一个RPG游戏,然后你需要很好地了解角色周围的地形。这是多层次的吗?角色如何从一个瓷砖移动到另一个瓷砖?运动是单向的吗?
在设计游戏地图时,确实存在数十个问题。
在开始编码之前,你需要先做好计划。