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

