wxPython ウインドウ内をボールが跳ね回るグラフィック描画してみる
wx.Timer、wx.BufferedDCを使ってウインドウ内をボールが跳ね回るグラフィックを描画してみる。昔々に何かのプログラム例でみたような気がすることをやってみた。これを発展させればテーブルテニスゲームができるはずだなあ。ということで、いつものごとくメモしておく。
#!/usr/bin/env python # -*- coding: utf-8 -*- import wx class Ball(object): def __init__(self, panel, x, y, color): self.pos_x = x self.pos_y = y self.dir_x = 1 self.dir_y = 1 self.pos_dif = 20 self.pos_x_max, self.pos_y_max = panel.GetSize() self.color = color def Move(self): if self.dir_x > 0: self.pos_x += self.pos_dif else: self.pos_x -= self.pos_dif if self.pos_x > self.pos_x_max: self.pos_x -= self.pos_dif self.dir_x = -1 if self.pos_x < 0: self.pos_x += self.pos_dif self.dir_x = 1 if self.dir_y > 0: self.pos_y += self.pos_dif else: self.pos_y -= self.pos_dif if self.pos_y > self.pos_y_max: self.pos_y -= self.pos_dif self.dir_y = -1 if self.pos_y < 0: self.pos_y += self.pos_dif self.dir_y = 1 def Draw(self, dc): dc.SetPen(wx.Pen(self.color)) dc.SetBrush(wx.Brush(self.color)) dc.DrawCircle(self.pos_x, self.pos_y, 10) class MyWindow(wx.Frame): def __init__(self, parent=None, id=-1, title=None): wx.Frame.__init__(self, parent, id, title) self.panel = wx.Panel(self, size=(300, 200)) self.panel.SetBackgroundColour('WHITE') self.Fit() self.ball1 = Ball(self.panel, 150, 100, 'red') self.ball2 = Ball(self.panel, 100, 50, 'blue') self.ball3 = Ball(self.panel, 50, 150, 'green') self.Bind(wx.EVT_CLOSE, self.CloseWindow) self.cdc = wx.ClientDC(self.panel) w, h = self.panel.GetSize() self.bmp = wx.EmptyBitmap(w,h) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnTimer) self.timer.Start(100) def CloseWindow(self, event): self.timer.Stop() wx.Exit() def OnTimer(self, event): self.bdc = wx.BufferedDC(self.cdc, self.bmp) self.bdc.Clear() self.ball1.Move() self.ball2.Move() self.ball3.Move() self.ball1.Draw(self.bdc) self.ball2.Draw(self.bdc) self.ball3.Draw(self.bdc) self.bdc.DrawText("Moving Ball",110,70) self.cdc.DrawBitmap(self.bmp,0,0) if __name__ == '__main__': app = wx.PySimpleApp() w = MyWindow(title='wxgr-ball') w.Center() w.Show() app.MainLoop()
プログラムを実行すると
- ボールを3個にしたので、Ballクラスを作って楽できるようにした。
- self.bdc = wx.BufferedDC(self.cdc, self.bmp)はOnTime関数内に記述しないと、画面が真っ白、なんでだろう?なので、__init__に追い出すことができなかった。まだまだ理解が足りないなあ。
- 終了するときはWindow右上のXをクリックするのだが、TimerをStopさせないとエラーポップアップがものすごい勢いで表示される。EVT_CLOSEを捕捉してTimerをStopさせるようにした。
実験環境
- Windows XP
- Python 2.5.4
- wxPython 2.9.1.1