C#, Windows Form, 重画pictureBox
C#, Windows Form, redraw pictureBox
我的 C# 游戏有问题。
有一个随机放置狼和浣熊的矩阵。当用户单击 "new game" 按钮时,我需要为动物生成新位置并重新绘制我的 canvas (PicureBox)。
所以,我生成没有问题,但是 pictureBox 中动物的位置没有改变(但它显示,当第一次生成时)。
我还尝试创建几个带有动物图标的图片框(并在游戏过程中移动它),但它们没有显示(我在 this.Controls 中添加了它,但没有任何反应)。也许浏览器中有一些表单管理器,如 web-inspector 可以查看到底发生了什么?
我不想将项目移动到 WPF 应用程序。
下面的代码片段:
private static Bitmap _gameArea = new Bitmap(_gameAreaSize, _gameAreaSize);
Painted事件(创建一个table):
private void drawTable(object sender, PaintEventArgs e)
{
Pen p = new Pen(Color.LightSlateGray);
var g = Graphics.FromImage(_gameArea);
for (int i = 0; i < Configs.MatrixSize + 1; i++)
{
float coord = i * _cellSize;
if (coord.Equals(_gameAreaSize))
coord = _gameAreaSize - 1;
g.DrawLine(p, coord, 0, coord, _gameAreaSize);
g.DrawLine(p, 0, coord, _gameAreaSize, coord);
}
pictureBox1.BackgroundImage = _gameArea;
g.Dispose();
}
游戏开始和新游戏点击:
GameLogic.InitGame(); // change positions, without threads
RefreshMap();
刷新地图:
private static void RefreshMap()
{
var g = Graphics.FromImage(_gameArea);
g.Clear(Color.White);
g.Dispose();
RefreshRacoons();
RefreshWolves();
}
我试过这样做:
private static void RefreshMap()
{
var sync = SynchronizationContext.Current;
new Thread(__ =>
sync.Post(_ =>
{
var g = Graphics.FromImage(_gameArea);
g.Clear(Color.White);
g.Dispose();
RefreshRacoons();
RefreshWolves();
}, null)).Start();
}
并刷新(使用和不使用 synContext)
private static void RefreshRacoons()
{
foreach (var racoon in GameLogic.Racoons)
{
var g = Graphics.FromImage(_gameArea);
g.DrawImage(_racoonImg,
_cellSize * racoon.X + _offsetX,
_cellSize * racoon.Y + _offsetY,
_animalIconWidth,
_animalIconHeight);
g.Dispose();
}
}
private static void RefreshWolves()
{
var sync = SynchronizationContext.Current;
foreach (var wolf in GameLogic.Wolves)
{
new Thread(__ =>
sync.Post(_ =>
{
var g = Graphics.FromImage(_gameArea);
g.DrawImage(_wolfImg,
_cellSize * wolf.X + _offsetX,
_cellSize * wolf.Y + _offsetY,
_animalIconWidth,
_animalIconHeight);
g.Dispose();
}, null)).Start();
}
}
谢谢!
我通常的免责声明是这样的:Windows Forms 不是适合游戏开发的环境。回合制单人游戏或热座多人游戏都可以,只要你不过度使用动画。但是纸牌和扫雷几乎是可能的上限。
有许多专用显示器 technologies/Engines 可用于游戏开发。但最终,任何允许您直接、低级别绘图访问并具有某种游戏循环的东西都应该可行。虽然你可以在某种程度上用 Windows 形式伪造它,但当你有一辆完全装满的汽车,点火器中的钥匙就站在那里时,你基本上最终会重新发明轮子。
对于 .NET Framework,过时的解决方案是 XNA Framework。但如果你选择 .NET Core,至少有 3 个官方解决方案:
https://www.microsoft.com/net/learn/apps/gaming
大多数都可以与 Mono 一起使用,有些甚至可以与 .NET Framework 一起使用(我自己还没有尝试过)。
我的 C# 游戏有问题。 有一个随机放置狼和浣熊的矩阵。当用户单击 "new game" 按钮时,我需要为动物生成新位置并重新绘制我的 canvas (PicureBox)。 所以,我生成没有问题,但是 pictureBox 中动物的位置没有改变(但它显示,当第一次生成时)。
我还尝试创建几个带有动物图标的图片框(并在游戏过程中移动它),但它们没有显示(我在 this.Controls 中添加了它,但没有任何反应)。也许浏览器中有一些表单管理器,如 web-inspector 可以查看到底发生了什么?
我不想将项目移动到 WPF 应用程序。
下面的代码片段:
private static Bitmap _gameArea = new Bitmap(_gameAreaSize, _gameAreaSize);
Painted事件(创建一个table):
private void drawTable(object sender, PaintEventArgs e)
{
Pen p = new Pen(Color.LightSlateGray);
var g = Graphics.FromImage(_gameArea);
for (int i = 0; i < Configs.MatrixSize + 1; i++)
{
float coord = i * _cellSize;
if (coord.Equals(_gameAreaSize))
coord = _gameAreaSize - 1;
g.DrawLine(p, coord, 0, coord, _gameAreaSize);
g.DrawLine(p, 0, coord, _gameAreaSize, coord);
}
pictureBox1.BackgroundImage = _gameArea;
g.Dispose();
}
游戏开始和新游戏点击:
GameLogic.InitGame(); // change positions, without threads
RefreshMap();
刷新地图:
private static void RefreshMap()
{
var g = Graphics.FromImage(_gameArea);
g.Clear(Color.White);
g.Dispose();
RefreshRacoons();
RefreshWolves();
}
我试过这样做:
private static void RefreshMap()
{
var sync = SynchronizationContext.Current;
new Thread(__ =>
sync.Post(_ =>
{
var g = Graphics.FromImage(_gameArea);
g.Clear(Color.White);
g.Dispose();
RefreshRacoons();
RefreshWolves();
}, null)).Start();
}
并刷新(使用和不使用 synContext)
private static void RefreshRacoons()
{
foreach (var racoon in GameLogic.Racoons)
{
var g = Graphics.FromImage(_gameArea);
g.DrawImage(_racoonImg,
_cellSize * racoon.X + _offsetX,
_cellSize * racoon.Y + _offsetY,
_animalIconWidth,
_animalIconHeight);
g.Dispose();
}
}
private static void RefreshWolves()
{
var sync = SynchronizationContext.Current;
foreach (var wolf in GameLogic.Wolves)
{
new Thread(__ =>
sync.Post(_ =>
{
var g = Graphics.FromImage(_gameArea);
g.DrawImage(_wolfImg,
_cellSize * wolf.X + _offsetX,
_cellSize * wolf.Y + _offsetY,
_animalIconWidth,
_animalIconHeight);
g.Dispose();
}, null)).Start();
}
}
谢谢!
我通常的免责声明是这样的:Windows Forms 不是适合游戏开发的环境。回合制单人游戏或热座多人游戏都可以,只要你不过度使用动画。但是纸牌和扫雷几乎是可能的上限。
有许多专用显示器 technologies/Engines 可用于游戏开发。但最终,任何允许您直接、低级别绘图访问并具有某种游戏循环的东西都应该可行。虽然你可以在某种程度上用 Windows 形式伪造它,但当你有一辆完全装满的汽车,点火器中的钥匙就站在那里时,你基本上最终会重新发明轮子。
对于 .NET Framework,过时的解决方案是 XNA Framework。但如果你选择 .NET Core,至少有 3 个官方解决方案: https://www.microsoft.com/net/learn/apps/gaming
大多数都可以与 Mono 一起使用,有些甚至可以与 .NET Framework 一起使用(我自己还没有尝试过)。