テトリスのソースを読む(その4)
http://www.zetcode.com/wxpython/thetetrisgame/のソース解読の続き。
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)のところ。
wx.EVT_KEY_DOWNはキー入力を表す。その解説は、http://ymasuda.jp/python/wxpython/simplesample.htmlに詳しい。
ここでのイベントハンドラは、
def OnKeyDown(self, event): if not self.isStarted or self.curPiece.shape() == Tetrominoes.NoShape: event.Skip() return keycode = event.GetKeyCode() #押されたキーのコードを返す if keycode == ord('P') or keycode == ord('p'): #ordは指定された文字のアスキーコードを返す self.pause() #たぶん一時停止だろうなー return if self.isPaused: #一時停止中であったら何もしない return elif keycode == wx.WXK_LEFT: #たぶん左矢印キー self.tryMove(self.curPiece, self.curX-1, self.curY) elif keycode == wx.WXK_RIGHT: #たぶん右矢印キー self.tryMove(self.curPiece, self.curX+1, self.curY) elif keycode == wx.WXK_DOWN: #たぶん下矢印キー self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY) elif keycode == wx.WXK_UP: #たぶん上矢印キー self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY) elif keycode == wx.WXK_SPACE: #これはスペースキー間違いない self.dropDown() elif keycode == ord('D') or keycode == ord('d'): self.oneLineDown() else: event.Skip() #他のキーだったら何もしない
ここは比較的やっていることが推測しやすいのだが、実際に動かしたときには矢印キーを押してもなんの反応もない。だめじゃん。スペースキーや'P'はちゃんと動作するのだが...。
続いてself.Bind(wx.EVT_PAINT, self.OnPaint)のところ。
wx.EVT_PAINTが何なのか皆目見当がつかないが、イベントハンドラself.OnPaintをとりあえず見る。
def OnPaint(self, event): dc = wx.PaintDC(self) # これはこういうものだ、として置いておく size = self.GetClientSize() # たぶん作ったパネルのサイズだろうな boardTop = size.GetHeight() - Board.BoardHeight * self.squareHeight() # ※1 #たぶん下に堆積しているブロックを描いている for i in range(Board.BoardHeight): #高さ方向 for j in range(Board.BoardWidth): #横方向 shape = self.shapeAt(j, Board.BoardHeight-i-1) # ※2 if shape != Tetrominoes.NoShape: # NoShapeでなければ self.drawSquare(dc, 0+j*self.squareWidth(), boardTop + i*self.squareHeight(), shape) # ブロックを描くメソッドだろう if self.curPiece.shape() != Tetrominoes.NoShape: # 落ちているブロックのことかな for i in range(4): #落ちている状態のブロックを描く? x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) #xとyで符号が違う。x,yは整数なんだよな self.drawSquare(dc, 0+x*self.squareWidth(), boardTop + (Board.BoardHeight-y-1) * self.squareHeight(), self.curPiece.shape())
※1について。Board.BoardWidth=10で横方向のブロック数の最大値を与え、Board.BoardHeight=22で縦方向のブロック数の最大値を与えている(と思う)。だとすると、ブロックのサイズは以下のメソッドで求められる。これらは整数になる?
def squareWidth(self): return self.GetClientSize().GetWidth() / Board.BoardWidth #ブロックの横幅 def squareHeight(self): return self.GetClientSize().GetHeight() / Board.BoardHeight #ブロックの縦幅
とすると、※1のboardTopは0だよな。
※2のメソッドself.shapeAtは、次のように値を返すだけ。
def shapeAt(self, x, y): return self.board[(y*Board.BoardWidth) + x]
でも(y*Board.BoardWidth)+xとしている理由がわからない。とりあえずパスする。
self.drawSquareの引数を見ると、x座標 0+j*self.squareWidth()、y座標 boardTop+i*self.squareHeight()は、ブロックの左下隅の座標なのではなかろうか。