【发布时间】:2013-04-10 13:41:14
【问题描述】:
我目前正在开发一款使用图形类创建游戏中所有图片的游戏,我还尝试从单独的线程绘制图片以阻止我的主线程冻结。但是每次我尝试运行该程序时,窗体上什么都没有出现,并且我收到此错误...
System.NullReferenceException:对象引用未设置为对象的实例。
在 c:\users\samuel\documents\visual studio 2012\Projects\Single_Player\Single_Player\Form1.vb:line 12 中的 Single_Player.Form1.mainPaint(PaintEventArgs e) 处
如果我的代码确实有效,我希望它会在屏幕上移动一个椭圆,无论如何这是我的代码...
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim paintT As New Threading.Thread(AddressOf mainPaint)
paintT.Start()
End Sub
Private Sub mainPaint(e As PaintEventArgs)
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
e.Graphics.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
Dim playerX As Integer = 0
Dim playerY As Integer = 206
Do While 0 / 0
e.Graphics.DrawRectangle(New Pen(Color.FromArgb(128, Color.Black)), 0, 0, 884, 24)
e.Graphics.FillRectangle(New SolidBrush(Color.FromArgb(128, Color.Black)), 0, 0, 884, 24)
e.Graphics.DrawString("Life: 5", New Font("DigifaceWide", 20, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(191, Color.Green)), 2, 0)
e.Graphics.DrawString("Score: 0", New Font("DigifaceWide", 20, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(191, Color.White)), 100, 0)
e.Graphics.FillEllipse(New SolidBrush(Color.FromArgb(128, Color.Blue)), playerX, playerY, 24, 24)
playerX = playerX + 1
playerY = playerY + 1
e.Graphics.Clear(Color.Transparent)
Threading.Thread.Sleep(50)
Loop
End Sub
更新(再次) 到目前为止我的代码(这次我通过设计窗口添加了一个计时器)...
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Timer1.Interval = 50
Timer1.Start()
End Sub
Private Sub mainBackgroundPB_Paint(sender As Object, e As PaintEventArgs) Handles Timer1.Tick
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
e.Graphics.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
e.Graphics.DrawRectangle(New Pen(Color.FromArgb(128, Color.Black)), 0, 0, 884, 24)
e.Graphics.FillRectangle(New SolidBrush(Color.FromArgb(128, Color.Black)), 0, 0, 884, 24)
e.Graphics.DrawString("Life: 5", New Font("DigifaceWide", 20, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(191, Color.Green)), 2, 0)
e.Graphics.DrawString("Score: 0", New Font("DigifaceWide", 20, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(191, Color.White)), 100, 0)
e.Graphics.FillEllipse(New SolidBrush(Color.FromArgb(128, Color.Blue)), playerX, playerY, 24, 24)
playerX = playerX + 1
playerY = playerY + 1
e.Graphics.Clear(Color.Transparent)
End Sub
【问题讨论】:
-
这是因为
PaintEventArgs为空,你没有从调用者线程将它传递给mainPaint -
还有你为什么要在不同的线程上绘画,如果你想重复发生某些事情,只需使用计时器,因为你不能从另一个线程绘画。
-
Do while 0/0是一个奇怪的结构。这首先生成Double.Infinity,然后将其转换为布尔值。为什么不只使用 while true -
@Sam stackoverflow.com/a/11753379/1112547 将绘画移至另一个方法并参考
mainPaint中的该方法创建新线程 -
处理
Timer.Tick事件而不是.paint事件
标签: .net vb.net multithreading winforms graphics