我创建了一个基于totorial的游戏来开始学习,我用renderScreen()渲染我的游戏,当我在屏幕上移动我的窗口时我得到了这个异常" Object目前正在其他地方使用" 。我知道错误的原因,但我无法解决它,因为我不知道该怎么做。 我能做什么 ?如果问题很愚蠢,请原谅我。
engine.cs
//MEMBERS
public static Graphics drawHandle;
private Thread renderThread;
public engine(Graphics g)
{
drawHandle = g;
}
private object bufferLock = new object();
public void init()
{
renderThread = new Thread(new ThreadStart(renderScreen));
renderThread.Start();
}
public void stop()
{
renderThread.Abort();
}
public static Bitmap frame = new Bitmap(Globals.CANVAS_WIDTH, Globals.CANVAS_HEIGHT);
Rectangle rect = new Rectangle(0, 0, frame.Width, frame.Height);
private void renderScreen()
{
int framesRendered = 0;
long startTime = Environment.TickCount;
Graphics frameGraphics = Graphics.FromImage(frame);
Unit1 unit1 = new Unit1("test1");
Unit1 unit2 = new Unit1("test2");unit2.x = 250; unit2.y = 100;
Globals.GameUnitsList.Add(unit1); Globals.GameUnitsList.Add(unit2);
while (true)
{
//BACKGROUND
frameGraphics.FillRectangle(new SolidBrush(Color.DarkBlue),0,0, Globals.CANVAS_WIDTH, Globals.CANVAS_HEIGHT);
//BOXES
Rectangle rect = new Rectangle(unit1.x, unit1.y, 50, 50);
unit1.rectangle = rect;
unit1.fillColor = Brushes.LightBlue;
unit1.hitPoints = 100;
unit1.Health = 10;
frameGraphics.FillRectangle(unit1.fillColor, unit1.rectangle);
frameGraphics.FillRectangle(unit1.fillColor, unit1.rectangle);
Rectangle rect2 = new Rectangle(unit2.x, unit2.y, 50, 50);
unit2.rectangle = rect2;
unit2.fillColor = Brushes.LightBlue;
unit2.hitPoints = 100;
unit2.Health = 50;
frameGraphics.FillRectangle(unit2.fillColor, unit2.rectangle);
frameGraphics.FillRectangle(unit2.fillColor, unit2.rectangle);
//HEALTH BAR
HealthBar hb = new HealthBar();
hb.barColor = Brushes.YellowGreen;
hb.damageColor = Brushes.Red;
frameGraphics.FillRectangle(hb.damageColor, hb.Draw(unit1, unit1.x, unit1.y)[1]);
frameGraphics.FillRectangle(hb.barColor, hb.Draw(unit1, unit1.x, unit1.y)[0]);
HealthBar hb2 = new HealthBar();
hb2.barColor = Brushes.YellowGreen;
hb2.damageColor = Brushes.Red;
frameGraphics.FillRectangle(hb2.damageColor, hb2.Draw(unit2, unit2.x, unit2.y)[1]);
frameGraphics.FillRectangle(hb2.barColor, hb2.Draw(unit2, unit2.x, unit2.y)[0]);
//UNIT NAMES
frameGraphics.DrawString(unit1.unitName, new Font("Arial", 24, FontStyle.Bold), Brushes.Yellow, unit1.x + 50, unit1.y + 50);
frameGraphics.DrawString(unit2.unitName, new Font("Arial", 24, FontStyle.Bold), Brushes.Yellow, unit2.x + 50, unit2.y + 50);
drawHandle.DrawImage(frame, 0, 0);
//BENCHMARKING
if (Environment.TickCount >= startTime + 750)
{
framesRendered++;
}
if (Environment.TickCount>=startTime+1000)
{
Console.WriteLine("Gomi-Invade Plan Game:"+framesRendered +"fps "+ Environment.TickCount);
framesRendered = 0;
startTime = Environment.TickCount;
}
}
}
gamewindow.cs
...
public static GameWindow gameW;
Game game = new Game();
...
//I have this code inside it but is this wrong ?
private void canvas_Paint(object sender, PaintEventArgs e)
{
Graphics g = canvas.CreateGraphics();
game.startGraphics(g);
}
...
game.cs
private engine Gengine;
public void startGraphics(Graphics g)
{
Gengine = new GomiEngine(g);
Gengine.init();
}
public void stopGame()
{
Gengine.stop();
}
答案 0 :(得分:0)
你不能在你自己的线程中渲染屏幕,你需要在调用中调用invalidate,这会将windows消息排入windows消息循环,这将在主线程上处理。
private void DoWorkInThread(object sender, EventArgs e)
{
while (true)
{
lock(this)
{
//update member properties
}
if (this.InvokeRequired)
this.Invoke((MethodInvoker)delegate void ()
{
//this.Invalidate(); //if you don't need to render every frame, invalidate is better then refresh
this.Refresh(); //call refresh for immediate update
});
}
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
lock(this)
{
//read your member which are modifies by the thread
}
//do rendering
e.Graphics.Draw(...);
}