使用 Monogame 绘制平铺地图
Drawing a tiled map with Monogame
我一直在尝试实现一个功能,让我可以在分块文件 (.tmx) 中绘制分块。我环顾四周,发现了一段有效的代码,但它 stretches out the tiles.
这是我找到并编辑了一下的代码:
private void DrawLayer(int index, SpriteBatch batch) {
for (var i = 0; i < Map.Layers[index].Tiles.Count; i++) {
//Get the identification of the tile
int gid = Map.Layers[index].Tiles[i].Gid;
// Empty tile, do nothing
if (gid == 0) { }
else {
int tileFrame = gid - 1 ;
int column = tileFrame % (tileset.Width / tileWidth);
int row = tileFrame / (tileset.Height / tileHeight);
float x = (i % Map.Width) * Map.TileWidth;
float y = (float)Math.Floor(i / (double)Map.Width) * Map.TileHeight;
//Put all the data together in a new rectangle
Rectangle tilesetRec = new Rectangle(tileWidth * column, tileHeight * row, tileWidth, tileHeight);
//Draw the tile that is within the tilesetRec
batch.Draw(tileset, new Rectangle((int)x, (int)y, tileWidth, tileHeight), tilesetRec, Color.White);
}
}
}
MonoGame.Extended 库支持加载和渲染平铺 (.tmx) 地图。它是开源的,因此您可以根据需要查看它的工作原理。
layer rendering code 支持不同的地图类型(正交、等距)、不同的渲染顺序(右下、右上、左下、左上)和多个图块集,因此它不会被归结为单一方法,例如你的。
如果你在哪里提取相关的代码位,你可能会得到这样的结果:
for (var y = 0; y < layerHeight; y++)
{
for (var x = 0; x < layerWidth; x++)
{
var region = tile.Id == 0 ? null : _regions[tile.Id];
if (region != null)
{
var tx = tile.X * _map.TileWidth;
var ty = tile.Y * _map.TileHeight;
var sourceRectangle = region.Bounds;
var destinationRectangle = new Rectangle(tx, ty, region.Width, region.Height);
_spriteBatch.Draw(region.Texture, destinationRectangle, sourceRectangle, Color.White);
}
}
}
当然,还有一些遗漏的地方,比如加载图块集时创建的纹理区域字典。
_regions = new Dictionary<int, TextureRegion2D>();
for (var y = Margin; y < texture.Height - Margin; y += TileHeight + Spacing)
{
for (var x = Margin; x < texture.Width - Margin; x += TileWidth + Spacing)
{
_regions.Add(id, new TextureRegion2D(Texture, x, y, TileWidth, TileHeight));
id++;
}
}
以及纹理区域的实际定义。
public class TextureRegion2D
{
public Texture2D Texture { get; protected set; }
public int X { get; private set; }
public int Y { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public Rectangle Bounds { get { return new Rectangle(X, Y, Width, Height); } }
}
请记住,我主要是从 MonoGame.Extended 中复制和粘贴代码。它不会完全像这里写的那样工作,但我想我已经提供了足够的细节来弄清楚如果您想编写自己的 Tiled 渲染代码,所有其他变量的作用。
我一直在尝试实现一个功能,让我可以在分块文件 (.tmx) 中绘制分块。我环顾四周,发现了一段有效的代码,但它 stretches out the tiles.
这是我找到并编辑了一下的代码:
private void DrawLayer(int index, SpriteBatch batch) {
for (var i = 0; i < Map.Layers[index].Tiles.Count; i++) {
//Get the identification of the tile
int gid = Map.Layers[index].Tiles[i].Gid;
// Empty tile, do nothing
if (gid == 0) { }
else {
int tileFrame = gid - 1 ;
int column = tileFrame % (tileset.Width / tileWidth);
int row = tileFrame / (tileset.Height / tileHeight);
float x = (i % Map.Width) * Map.TileWidth;
float y = (float)Math.Floor(i / (double)Map.Width) * Map.TileHeight;
//Put all the data together in a new rectangle
Rectangle tilesetRec = new Rectangle(tileWidth * column, tileHeight * row, tileWidth, tileHeight);
//Draw the tile that is within the tilesetRec
batch.Draw(tileset, new Rectangle((int)x, (int)y, tileWidth, tileHeight), tilesetRec, Color.White);
}
}
}
MonoGame.Extended 库支持加载和渲染平铺 (.tmx) 地图。它是开源的,因此您可以根据需要查看它的工作原理。
layer rendering code 支持不同的地图类型(正交、等距)、不同的渲染顺序(右下、右上、左下、左上)和多个图块集,因此它不会被归结为单一方法,例如你的。
如果你在哪里提取相关的代码位,你可能会得到这样的结果:
for (var y = 0; y < layerHeight; y++)
{
for (var x = 0; x < layerWidth; x++)
{
var region = tile.Id == 0 ? null : _regions[tile.Id];
if (region != null)
{
var tx = tile.X * _map.TileWidth;
var ty = tile.Y * _map.TileHeight;
var sourceRectangle = region.Bounds;
var destinationRectangle = new Rectangle(tx, ty, region.Width, region.Height);
_spriteBatch.Draw(region.Texture, destinationRectangle, sourceRectangle, Color.White);
}
}
}
当然,还有一些遗漏的地方,比如加载图块集时创建的纹理区域字典。
_regions = new Dictionary<int, TextureRegion2D>();
for (var y = Margin; y < texture.Height - Margin; y += TileHeight + Spacing)
{
for (var x = Margin; x < texture.Width - Margin; x += TileWidth + Spacing)
{
_regions.Add(id, new TextureRegion2D(Texture, x, y, TileWidth, TileHeight));
id++;
}
}
以及纹理区域的实际定义。
public class TextureRegion2D
{
public Texture2D Texture { get; protected set; }
public int X { get; private set; }
public int Y { get; private set; }
public int Width { get; private set; }
public int Height { get; private set; }
public Rectangle Bounds { get { return new Rectangle(X, Y, Width, Height); } }
}
请记住,我主要是从 MonoGame.Extended 中复制和粘贴代码。它不会完全像这里写的那样工作,但我想我已经提供了足够的细节来弄清楚如果您想编写自己的 Tiled 渲染代码,所有其他变量的作用。