カーソルの移動
マップを作る(2008/5/24)やマップのロード(2008/6/1)のようにマップのデータを数値で打ち込んでいくのは大変です。マップエディタ編では、お絵描きするような感じで簡単にマップを作成できるマップエディタを作っていきます。
今回はマップ内をカーソル(緑色の四角形)が移動するところまで作ってみます。Pygameではスクロールバーが使えないためカーソルでマップ内を移動します。RPG編のピクセルベーススクロール(2008/6/14)まで読んできた方なら前に似たコード見たなぁと思えるはずです。MapクラスはRPG編のMapとほとんど同じですし、CursorクラスはRPG編のPlayerにほぼ対応しています。
スクリプトを起動すると、矢印キーでカーソルが動かせます。
メイン関数
SCR_RECT = Rect(0, 0, 800, 640) GS = 32 def main(): pygame.init() screen = pygame.display.set_mode(SCR_RECT.size) pygame.display.set_caption(u"PyMap 01 カーソルの移動") # イメージをロード Map.images.append(load_image("none.png")) # 範囲外 Map.images.append(load_image("water.png")) # 海 map = Map("new.map", 64, 64) # 64x64(単位:マス)のマップ cursor = Cursor(0, 0) clock = pygame.time.Clock() while True: clock.tick(60) offset = calc_offset(cursor) cursor.update() map.draw(screen, offset) cursor.draw(screen, offset) pygame.display.update() for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: pygame.quit() sys.exit()
メイン関数では、MapオブジェクトとCursorオブジェクトを作成しています。デフォルトのマップの大きさは64x64マスです。また、カーソルは (0,0) に置いておきます。Mapのイメージには
という2つのイメージを登録しています。いずれたくさんのマップチップを使えるようにしますが、今回はこれだけです。
マップクラス
class Map: images = [] def __init__(self, name, row, col): self.name = name self.row = row self.col = col self.default = 1 # デフォルトのマップチップ番号 # デフォルトマップチップで初期化 self.map = [[self.default for c in range(self.col)] for r in range(self.row)] def __str__(self): return "%s,%d,%d,%d" % (self.name, self.row, self.col, self.default) def draw(self, screen, offset): offsetx, offsety = offset # マップの描画範囲を計算 startx = offsetx / GS endx = startx + SCR_RECT.width/GS + 2 starty = offsety / GS endy = starty + SCR_RECT.height/GS + 2 # マップの描画 for y in range(starty, endy): for x in range(startx, endx): # マップの範囲外はマップチップ番号0で描画 if x < 0 or y < 0 or x > self.col-1 or y > self.row-1: screen.blit(self.images[0], (x*GS-offsetx,y*GS-offsety)) else: screen.blit(self.images[self.map[y][x]], (x*GS-offsetx,y*GS-offsety))
Mapクラスはオフセットを使っていることも含めてタイルベーススクロール(2008/6/7)のMapクラスとよく似ています。デフォルトのマップチップ番号を1にしていますが、これは
です。起動するとマップは海で塗りつぶされてますね。またマップの範囲外は
で塗りつぶしています。self.mapがマップチップ番号が入る二次元リストです。
self.map = [[self.default for c in range(self.col)] for r in range(self.row)]
このコードは少し見慣れないかもしれませんが、Pythonで2次元リストを作るときの定石です。row行col列で0で初期化した2次元リストを作りたい場合は、
lst = [[0 for c in range(col)] for r in range(row)]
と書きます。(2,3)にアクセスしたい場合はlst[2][3]のように配列風の書き方が使えます。
カーソルクラス
class Cursor: COLOR = (0,255,0) # 緑色 WIDTH = 3 # 太さ def __init__(self, x, y): self.x, self.y = x, y self.rect = Rect(x*GS, y*GS, GS, GS) def update(self): # キー入力でカーソルを移動 pressed_keys = pygame.key.get_pressed() if pressed_keys[K_DOWN]: self.y += 1 elif pressed_keys[K_LEFT]: self.x -= 1 elif pressed_keys[K_RIGHT]: self.x += 1 elif pressed_keys[K_UP]: self.y -= 1 self.rect = Rect(self.x*GS, self.y*GS, GS, GS) def draw(self, screen, offset): # オフセットを考慮してカーソルを描画 offsetx, offsety = offset px = self.rect.topleft[0] py = self.rect.topleft[1] pygame.draw.rect(screen, self.COLOR, (px-offsetx,py-offsety,GS,GS), self.WIDTH)
最後にマップ内を移動するカーソルですが、これはRPG編のPlayerとほとんど同じです。違うところは画像で描画するのではなく、矩形で描画するところくらいです。draw()で緑色で幅が3の矩形を描いています。またupdate()でキー入力を検知して移動する処理を書いています。これでマップ内を自由に移動できるようになりました。次はマウスを使ってマップチップをお絵描きできるようにしてみます。