我在winforms并且出于学校的原因试图在其中制作一个tileengine。我在Panel中绘制tileset时遇到了麻烦。而是在图表的左上角和面板后面绘图。
这是代码:
private void gfxPanel_Paint(object sender, PaintEventArgs e)
{
using (Bitmap sourceBmp = new Bitmap("../../assets/art/Tileset5.png"))
{
Size s = new Size(level.TileWidth, level.TileHeight);
Rectangle destRect = new Rectangle(Point.Empty, s);
for (int row = 0; row <= level.MapHeight; row++)
for (int col = 0; col < level.MapWidth; col++)
{
PictureBox p = new PictureBox();
p.Size = s;
Point loc = new Point(level.TileWidth * col, level.TileHeight * row);
Rectangle srcRect = new Rectangle(loc, s);
Bitmap tile = new Bitmap(level.TileWidth, level.TileHeight);
Graphics G = Graphics.FromImage(tile);
G.DrawImage(sourceBmp, destRect, srcRect, GraphicsUnit.Pixel);
p.Image = tile;
p.Location = loc;
this.Controls.Add(p);
}
}
}
这里发生了什么,我做错了什么?
答案 0 :(得分:2)
您正在将图片框添加到表单(this
)。而是将它们添加到面板中:
gfxPanel.Controls.Add(p);
注意:您正在paint事件中添加控件,这意味着您将添加多组相同的控件。只要需要在屏幕上重绘控件,就会调用paint。您应该只添加一次控件,可能在表单加载事件中。如果要使用paint事件,则应使用事件参数中发送的图形对象直接在屏幕上绘制,而不是添加包含要绘制内容的控件。
答案 1 :(得分:1)
如果您真的只想在没有互动的情况下绘制图块,可以像这样更改Paint
事件:
private void gfxPanel_Paint(object sender, PaintEventArgs e)
{
using (Bitmap sourceBmp = new Bitmap("../../assets/art/Tileset5.png"))
{
Size s = new Size(levelTile.Width, levelTile.Height);
for (int row = 0; row <= levelMap.Height; row++)
for (int col = 0; col < levelMap.Width; col++)
{
Rectangle destRect = new Rectangle(
col * levelTile.Width, row * levelTile.Height,
levelTile.Width, levelTile.Height);
Point loc = new Point(levelTile.Width * col, levelTile.Height * row);
Rectangle srcRect = new Rectangle(loc, s);
e.Graphics.DrawImage(sourceBmp, destRect, srcRect, GraphicsUnit.Pixel);
}
}
}
请注意,我没有完全重写代码。如果要以与TileSet中显示的相同的顺序和大小绘制切片,则可以直接绘制整个TileSet。