- 題名: CreateGraphicsからPaintへの書き換え
- 日時: 2011/01/14 12:36:11
- ID: 28007
- この記事の返信元:
- (なし)
- この記事への返信:
- [28010] Re[1]: CreateGraphicsからPaintへの書き換え2011/01/14 15:01:18
- ツリーを表示
■No28007に返信(Kさんの記事) > 全てPaintで行うよう書き換えようと思ったのですが、どうするかよく判りません。 Sub 何某() 'Timer1_Tick なのかな? Dim g As Graphics = Picturebox1.CreateGraphics() Dim fnt As New Font("MS UI GOTHIC", font_size) Dim color As Brush = font_color Dim text As String = "●" g.DrawString(text, fnt, color, X, Y) fnt.Dispose() g.Dispose() End Sub という処理を、下記のように書き換えてみてください。 Sub 何某() Picturebox1.Invalidate() '再描画を依頼する ' Invalidate / Update / Refresh の違いについては下記参照 ' http://dobon.net/vb/dotnet/control/refreshupdateinvalidate.html ' http://bbs.wankuma.com/index.cgi?mode=al2&namber=55921&KLOG=94 End Sub Sub Picturebox1_Paint(…… Using fnt As New Font("MS UI Gothic", font_size) '自分で作成した Brush の場合は、使用後には Dispose が必要です。 '(ただし、SystemBrushes などの場合は扱いが異なります) Dim color As Brush = font_color Dim text As String = "●" 'e.Graphics は Dispose してはいけません e.Graphics.DrawString(text, fnt, color, X, Y) End Using End Sub
■No28014に返信(Kさんの記事) > Dim color As Brush = Brushes.Blue Brushes から得たブラシは Dispose しないでください。 Dispose 対象とすべきなのは、自分で作成・管理しているオブジェクトです。 Using x As New SolidBrush(Color.Blue) End Using この事は、Graphics や Font や Image などにおいても同様です。 CreateGraphics や Graphics.FromImage で Graphics を生成した場合は 使用後に Dispose する必要がありますが、Paint イベントで得た Graphics は 勝手に Dispose してはいけません。 Font についても、たとえば描画時に Me.Font などを使うのであれば、 それを勝手に Dispose してはいけません。ただし、描画のたびに New Font(〜〜) するようなケースにおいては、 Using F As New Font(〜〜) End Using などとして、使用後に Dispose されるようにします。 Image についても、基本的には Dispose が必要なのですが、 まだ PictureBox などに表示中の画像などは、勝手に Dispose しては いけません。すなわち、 PictureBox1.Image = tempImage tempImage.Dispose() というコードも NG というわけです。 > e.Graphics.FillPolygon(color, points, Drawing2D.FillMode.Alternate) ブラシに color という名前を付けると、Color 型と混同しやすくなるので、 動作上は問題無いにしても、別の名前にしておいた方が良いかと思います。
分類:[.NET]
【解決したい問題】
現在、簡単なシューティングゲームを作っておりますが、
描画する物が多くなるにつれ描画のちらつきが耐えられないレベルになってきました。
そこでダブルバッファリングを試してみようとしたのですが効果が無く、
調べてみたところCreateGraphicsで描画したものはダブルバッファリングの対象にならないと聞き、
全てPaintで行うよう書き換えようと思ったのですが、どうするかよく判りません。
簡略化すると以下の様なコードなのですが、どのように書き換えればよいのでしょうか?
(現状、この3つの処理が1フレーム(Timerで、Interval30として制御しています)に最大で1000回程度行われています。
また、Tickごとに1回Refresh命令を入れています)
*弾の処理…弾は全て●、★等のテキスト
Dim g As Graphics = Picturebox1.CreateGraphics()
Dim fnt As New Font("MS UI GOTHIC", font_size)
Dim color As Brush = font_color
Dim text As String = "●"
g.DrawString(text, fnt, color, X, Y)
fnt.Dispose()
g.Dispose()
*敵・自機の処理…リソースに埋め込んだ画像
Dim g As Graphics = Picturebox1.CreateGraphics()
g.DrawImage(Enemy1, X, Y, Enemy1_width, Enemy1_height)
g.Dispose()
*レーザーの処理…塗りつぶした長方形
Dim g As Graphics = Picturebox1.CreateGraphics()
Dim points As Point() = {New Point(X1, Y1), New Point(X2, Y2), New Point(X3, Y3), New Point(X4, Y4)}
'colorには既にBrush型が入っています
g.FillPolygon(color, points, Drawing2D.FillMode.Alternate)
g.Dispose()
【解決するために何をしたか】
また、
Private Sub Picturebox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Picturebox1.Paint
move_laser(e)
'レーザーの動き。
move_bullet(e)
'弾の動き。
move_enemy(e)
'敵の動き。
move_player_bullet(e)
'自機弾の動き。
hit_and_move(e)
'当たり判定・移動・自機弾射出。
End Sub
このように描画処理を行うサブルーチンを全てPaintイベントの中に入れて、
前述のg.DrawImage等をe.Graphics.Drawimage等に変えてみると一応ちらつきは収まったものの、
今度は処理がまるで正しく行われなくなりました。
(異常なスピードで動作する、規定した位置に弾が出ない、敵が規定の位置に動かなくなる、タイミングがずれる…等)