[英]XNA C# 2D Tile Engine
我决定尝试使用Xna框架制作地下城爬虫游戏。 我是计算机科学专业的学生,并且对c#和.net框架非常熟悉。 我对引擎开发的不同部分有一些疑问。
我有一个图块类,用于存储图块的vector2位置,2dtexture和尺寸。 我还有一个名为tilemap的类,该类具有按位置索引的图块列表。 我正在从上面的数字格式的文本文件中读取,该文本文件将数字与瓦片列表中的索引匹配,并创建具有正确纹理和位置的新瓦片,并将其存储到另一个瓦片列表中。
public List<Tile> tiles = new List<Tile>(); // List of tiles that I have added to the game public List<TileRow> testTiles = new List<TileRow>(); // Tilerow contains a list of tiles along the x axis along with there vector2 position.
读取和存储地图图块。
using (StreamReader stream = new StreamReader("TextFile1.txt"))
{
while (stream.EndOfStream != true)
{
line = stream.ReadLine().Trim(' ');
lineArray = line.Split(' ');
TileRow tileRow = new TileRow();
for (int x = 0; x < lineArray.Length; x++)
{
tileXCo = x * tiles[int.Parse(lineArray[x])].width;
tileYCo = yCo * tiles[int.Parse(lineArray[x])].height;
tileRow.tileList.Add(new Tile(tiles[int.Parse(lineArray[x])].titleTexture, new Vector2(tileXCo,tileYCo)));
}
testTiles.Add(tileRow);
yCo++;
}
}
用于绘制地图。
public void Draw(SpriteBatch spriteBatch, GameTime gameTime) { foreach (TileRow tes in testTiles) { foreach (Tile t in tes.tileList) { spriteBatch.Draw(t.titleTexture, t.position, Color.White); } } }
问题:这是我应该做的正确方法,还是应该只存储引用我的图块列表的列表?
我将如何处理多层地图?
目前,我有一个方法可以遍历存储在testTiles列表中的每个图块,并检查其尺寸是否与播放器尺寸相交,然后返回所有图块的列表。 我有一个名为CollisionTile的瓦片类的派生类,当玩家和该矩形相交时会触发碰撞。 (公共类CollisionTile:图块)
public List<Tile> playerArrayPosition(TileMap tileMap)
{
List<Tile> list = new List<Tile>();
foreach (TileRow test in tileMap.testTiles)
{
foreach (Tile t in test.tileList)
{
Rectangle rectangle = new Rectangle((int)tempPosition.X, (int)tempPosition.Y, (int)playerImage.Width / 4, (int)playerImage.Height / 4);
Rectangle rectangle2 = new Rectangle((int)t.position.X, (int)t.position.Y, t.width, t.height);
if (rectangle.Intersects(rectangle2))
{
list.Add(t);
}
}
}
return list;
}
是的,我很确定这不是检查瓷砖碰撞的正确方法。 任何帮助都会很棒。
抱歉,很长的帖子,我们将不胜感激。
你是对的。 这是一种在瓷砖上绘制和检查碰撞的效率很低的方法。 您应该查看的是Quadtree数据结构。
四叉树将以某种方式存储您的图块,使您可以使用Rectangle查询世界,并且四叉树将返回该Rectangle中包含的所有图块。
List<Tiles> tiles = Quadtree.GetObjects(rectangle);
这允许您仅选择需要处理的图块。 例如,在绘制图块时,可以指定视口大小的Rectangle,仅绘制(图块)这些图块。
另一个示例是,您可以使用玩家的Rectangle查询世界,并且仅检查在该部分世界中返回的图块上是否存在碰撞。
为了加载您的图块,您可能需要考虑加载到二维数组中,而不是列表中。 这样,您就可以根据其位置获取图块,而不必在两个列表之间交叉引用。
Tile[,] tiles = new Tile[,]
Tile tile = tiles[x,y];
同样,在这种情况下,数组数据结构比使用列表要有效得多。
对于具有标准宽度和高度的统一的图块集,很容易计算出屏幕上可见的图块,并确定角色与哪些图块重叠。 即使我在乔恩的答案中写了QuadTree,我认为这也太过分了。 通常,公式为:
tileX = someXCoordinate % tileWidth;
tileY = someYCoordinate % tileHeight;
然后,您可以在2D数组tiles[tileX, tileY]
。 对于绘制,这可以用来找出屏幕左上角的图块,然后对右下(+1)再次执行相同操作,或者在左上角添加图块以填充屏幕。 然后您的循环将更像:
leftmostTile = screenX % tileWidth; // screenX is the left edge of the screen in world coords
topmostTile = screenY % tileHeight;
rightmostTile = (screenX + screenWidth) % tileWidth;
bottommostTile = (screenY + screenHeight) % tileHeight;
for(int tileX = leftmostTile; tileX <= rightmostTile; tileX++)
{
for(int tileY = topmostTile; tileY <= bottommostTile; tileY++)
{
Tile t = tiles[tileX][tileY];
// ... more stuff
}
}
可以使用相同的简单公式快速确定矩形区域下的哪些图块。
但是,如果您的图块不均匀,或者具有等轴测视图,或者您想要QuadTree提供的其他功能,那么我会考虑Jon的回答并使用QuadTree 。 如果可以的话,我会尝试将图块保留在QuadTree中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.