テトリスのソースを読む(その1)
全体で450行程度のコード(http://www.zetcode.com/wxpython/thetetrisgame/)であるが、最初から読んでいく。とりあえずはコードの解説は読まずにコードだけに注目。
import wx import random class Tetris(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, size=(180, 380)) self.statusbar = self.CreateStatusBar() # ステータスバーを作る self.statusbar.SetStatusText('0') # ステータスバーに0を表示する self.board = Board(self) # Boardクラスのインスタンスオブジェクト self.board.SetFocus() # ??? self.board.start() # クラスBoardのメソッドstart self.Centre() # 画面の表示位置を中央にする self.Show(True) ...(略)... app = wx.App() Tetris(None, -1, 'Tetris') app.MainLoop()
まずは、外枠となっているTetrisクラスから。これでメインのフレームが表示される。
ここで、self.board.SetFocus()なのだが、Boardはwx.Panelのサブクラスとなっていて、SetFocusはwx.Panelのメソッドのようだ。役割がよくわからないから後で考える。
次にBoardクラスの最初の部分(コンストラクタ)を見る。
class Board(wx.Panel): BoardWidth = 10 # クラス定数 BoardHeight = 22 Speed = 300 ID_TIMER = 1 def __init__(self, parent): wx.Panel.__init__(self, parent) self.timer = wx.Timer(self, Board.ID_TIMER) #クラス名.定数名でアトリビュートを呼び出す。タイマーらしきもの self.isWaitingAfterLine = False self.curPiece = Shape() # ※1 self.nextPiece = Shape() self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.isStarted = False self.isPaused = False self.Bind(wx.EVT_PAINT, self.OnPaint) # ※2 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_TIMER, self.OnTimer, id=Board.ID_TIMER) self.clearBoard() # ※3 ...
ここで、
- ※2のイベント、wx.EVT_PAINT、wx.EVT_KEY_DOWN、EVT_TIMERがどのような操作に対応しているか
- wxTimerの使い方
が現時点で不明な点。
※1のShapeクラスの定義とその関連部分は、
class Shape(object): coordsTable = ( # タプルのネスト。 ((0, 0), (0, 0), (0, 0), (0, 0)), # 各ブロックの要素の中心座標を与えているような感じ ((0,-1), (0, 0), (-1, 0), (-1, 1)), ((0,-1), (0, 0), (1, 0), (1, 1)), ((0,-1), (0, 0), (0, 1), (0, 2)), ((0,-1), (0, 0), (1, 0), (0, 1)), ((0, 0), (1, 0), (0, 1), (1, 1)), ((-1,-1), (0, -1), (0, 0), (0, 1), ((1,-1), (0, -1), (0, 0), (0, 1)) ) def __init__(self): self.coords = [[0,0] for i in range(4)] self.pieceShape = Tetrominoes.NoShape self.setShape(Tetrominoes.NoShape) ... def setShape(self, shape): table = Shape.coordsTable[shape] for i in range(4): for j in range(2): self.coords[i][j] = table[i][j] # ブロックを構成する要素の座標か(4つの要素の座標x,y) self.pieceShape = shape # ブロックの形の情報 ... class Tetrominoes(object): # ブロックの形を分類している NoShape = 0 ZShape = 1 SShape = 2 LineShape = 3 TShape = 4 SquareShape = 5 LShape = 6 MirroredLShape = 7
このあたりはまだ初期の定義段階。
※3のclearBoardは、Boardクラスの中のメソッドであり、以下のようになっている。
def clearBoard(self): for i in range(Board.BoardHeight * Board.BoardWidth): #22*10=220 self.board.append(Tetrominoes.NoShape) # 結構大きなリストだなー。
リストself.boardを初期化している。
”クラス名.クラス定数”という書き方をいままで自分のコードでしたことがなかったことに気づく。