【簡単?】初心者がpython3とpygameでヒット&ブローゲーム作ってみる #03 画面作るよ【習作?】
初心者がpython3とpygameでヒット&ブローゲーム作ってみる #03 画面作るよ
前回から
【簡単?】初心者がpython3とpygameでヒット&ブローゲーム作ってみる【習作?】 - 工学じじいの縁側日記
【簡単?】初心者がpython3とpygameでヒット&ブローゲーム作ってみる #02【習作?】 - 工学じじいの縁側日記
前回は、テキストベースで作ったヒット&ブローゲームにpygameのガワをかぶせるべく、簡易的な状態遷移の処理を書いてみました。
今回は、画面の構成を作っていきます。
画面構成
完成イメージは、こんな感じです。
左側上部に、答えの入力欄が数字4桁で、画面左側下部に0~9の数字が並んでいて、押した順に上部の入力欄に入力されます。
左側には、現在までの、解答の履歴と、その時のヒット数、ブロー数が一覧で並んでいます。
15回×4ページ分の履歴を保存できるようにします。それで答えられなかったらゲームオーバーです。
まず、入力欄から作っていきます。
画面の作成 その1 入力欄
今回使う画像の一覧(次に使うのも入ってます。。。)は、以下のようになっています。
Webのフリー素材でもいいですし、適当にofficeの作図機能で作ってもいいと思います。
githubにもあるので、僕の作ったので良ければどうぞ。
初めに読み込む画像は、数字とアスタリスクの画像 [00.png, 11.png, 22,png ~ 99.png, kome.png] です。
読み込みやすいように、連番のファイル名にしておいたので、このファイル名が並んだリストを作ります。
画像は、プロジェクトフォルダ配下の「images」フォルダに全て納めてあります。
qfilestr = [] # 画像ファイル名を生成するためのリスト for i in range(10): # 問題の方の画像ファイルは 00.png~99.pngの名前になっている。 qfilestr.append(str(i)+str(i) + ".png") # 画像ファイル名を生成
次に、画面上での、解答欄の貼り付け位置を表す矩形(pygame.Rect型)を用意します。
数字1個当たりの画像の大きさは(幅、高さ)=(100,100)です。これを、図のように並べていきます。
margin = [100, 100] # *を表示する位置までのマージン imagesize = [100,100] # 画像1個当たりの大きさ qbuttonrect = [] # *を表示するための矩形を作成 *のサイズは(100,100) for i in range(4): #marginの位置から4つ横に画像を並べるためのもの qbuttonrect.append(Rect(margin[0] + i * imagesize[1], margin[1], *imagesize))
これらを使って、いつものpygame.image.loadで読み込んでいきます。
ここまでの部分をまとめると以下のようになります。
margin = [100, 100] # *を表示する位置までのマージン imagesize = [100,100] # 画像1個当たりの大きさ qfilestr = [] # 画像ファイル名を生成するためのリスト qimagelist = [] # 出題用の画像を保存しておくリスト0~9+*の画像が収まっている。 for i in range(10): # 問題の方の画像ファイルは 00.png~99.pngの名前になっている。 qfilestr.append(str(i)+str(i) + ".png") # 画像ファイル名を生成 for i in range(10): # 画像の読み込み qimagelist.append(pygame.image.load("./images/" + qfilestr[i])) #[00.png, 11.png, 22.png … 99.png, kome.png] qimagelist.append(pygame.image.load("./images/kome.png")) # *の画像の読み込み qbuttonrect = [] # *を表示するための矩形を作成 *のサイズは(100,100) for i in range(4): #marginの位置から4つ横に画像を並べるためのもの qbuttonrect.append(Rect(margin[0] + i * imagesize[1], margin[1], *imagesize))
最後、連番の名前ではない、アスタリスクの画像(kome.png)を別口でロードしてリストに追加しているところに注意してください。
リストの中身は、[00.png, 11.png, 22.png … 99.png, kome.png] の順に並んでいます。(qimagelist[10] がkome.pngです)
入力欄 描画処理を書く
先ほどの読み込んだ画像のリスト(qimagelist)と、それを貼り付けるための位置を表す矩形(qbuttonrect)をつかって、ゲーム画面に画像を貼り付けます。
処理自体は、qimagelist[10]のアスタリスク画像を、qbuttonrect[0]~qbuttonrect[3]の位置に貼り付けるだけですので簡単です。
for i in range(4): screen.blit(qimagelist[10], qbuttonrect[i])
問題はこれをどこのタイミングで描画するか、です。
前回やったシーン切り替えのことを考えると、スタートボタンが押されたら、ゲームが始まったほうがそれっぽいですよね。
ということで、
gamescene==1のとき、すなわちゲーム中の時に入力欄を表示するのが自然な気がします。
すなわち、前回のボタンを表示した部分で、以下の様に描画処理を書きます。
if gamescene == 0: screen.blit(gamebutton[0], gamebuttonrect) elif gamescene == 1: for i in range(4): screen.blit(qimagelist[10], qbuttonrect[i]) screen.blit(gamebutton[1], gamebuttonrect) elif gamescene ==2: screen.blit(gamebutton[2], gamebuttonrect) else: print("error")
これで、ゲームスタートを押すと****と、アスタリスクが4つ表示されるはずです。
入力用ボタンとなる数字画像の表示
入力用のボタンとなる数字画像(画面左側下部)を読み込んで表示します。
処理の内容は先ほどと変わらないので、コードのみ掲載しておきます。
nmargin = [50, 350] # 入力ボタンのためのマージン filestr = [] # 画像ファイル名を収めるリスト for i in range(10): # 読み込む画像ファイル名のリストを作る filestr.append(str(i) + ".png") imagelist = [] # 読み込んだ画像のリスト for i in range(10): imagelist.append(pygame.image.load("./images/" + filestr[i])) #ファイルの読み込み buttonrect = [] # 画像ファイルの貼り付け位置が収められたリスト(Rect型) for i in range(5): # 0~4の画像の位置 buttonrect.append(Rect(nmargin[0] + i * imagesize[0], nmargin[1], *imagesize)) for i in range(5, 10): # 5~9の画像の位置 buttonrect.append(Rect(nmargin[0] + (i - 5) * imagesize[0], nmargin[1]+imagesize[1], *imagesize))
入力用数字の画像を描画するコードの追加
これも同様に
gamescene==1の時に、描画されるように、追加します。
if gamescene == 0: screen.blit(gamebutton[0], gamebuttonrect) elif gamescene == 1: for i in range(4): # 入力された数字を表示する領域 screen.blit(qimagelist[10], qbuttonrect[i]) for i in range(5): # 入力のためのボタンとなる画像0~4 screen.blit(imagelist[i], buttonrect[i]) for i in range(5, 10): # 入力のためのボタンとなる画像5~9 screen.blit(imagelist[i], buttonrect[i]) screen.blit(gamebutton[1], gamebuttonrect) elif gamescene ==2: screen.blit(gamebutton[2], gamebuttonrect) else: print("error")
実行してみます。
game start ボタンを押すと、以下の画面が出れば成功です。
なんとなく、どんな感じのゲームになるか見えてきましたね。
ここまでのソースコード一覧です。
from pygame.locals import * import pygame import sys import random def main(): gamescene = 0 # 0 タイトル、1 ゲーム中、2 ゲームオーバー、-1 エラー pygame.init() # Pygameを初期化 screen = pygame.display.set_mode((900, 600)) # 画面を作成 pygame.display.set_caption("Hit & Blow game") gamebutton = [] gamebuttonrect = Rect(200, 250, 200, 50) # 画像の表示位置を表す矩形 gamebutton.append(pygame.image.load("./images/pushstart.png")) gamebutton.append(pygame.image.load("./images/judge.png")) gamebutton.append(pygame.image.load("./images/gameover.png")) margin = [100, 100] # *を表示する位置までのマージン imagesize = [100,100] # 画像1個当たりの大きさ qfilestr = [] # 画像ファイル名を生成するためのリスト qimagelist = [] # 出題用の画像を保存しておくリスト0~9+*の画像が収まっている。 for i in range(10): # 問題の方の画像ファイルは 00.png~99.pngの名前になっている。 qfilestr.append(str(i)+str(i) + ".png") # 画像ファイル名を生成 for i in range(10): # 画像の読み込み qimagelist.append(pygame.image.load("./images/" + qfilestr[i])) qimagelist.append(pygame.image.load("./images/kome.png")) # *の画像の読み込み #[00.png, 11.png, 22.png … 99.png, kome.png] qbuttonrect = [] # *を表示するための矩形を作成 *のサイズは(100,100) for i in range(4): #marginの位置から4つ横に画像を並べるためのもの qbuttonrect.append(Rect(margin[0] + i * imagesize[1], margin[1], *imagesize)) nmargin = [50, 350] # 入力ボタンのためのマージン filestr = [] # 画像ファイル名を収めるリスト for i in range(10): # 読み込む画像ファイル名のリストを作る filestr.append(str(i) + ".png") imagelist = [] # 読み込んだ画像のリスト for i in range(10): imagelist.append(pygame.image.load("./images/" + filestr[i])) #ファイルの読み込み buttonrect = [] # 画像ファイルの貼り付け位置が収められたリスト(Rect型) for i in range(5): # 0~4の画像の位置 buttonrect.append(Rect(nmargin[0] + i * imagesize[0], nmargin[1], *imagesize)) for i in range(5, 10): # 5~9の画像の位置 buttonrect.append(Rect(nmargin[0] + (i - 5) * imagesize[0], nmargin[1]+imagesize[1], *imagesize)) running = True # メインループ while running: screen.fill((100, 100, 100)) # 背景色で塗る # この時点では、 screen.blit(gamebutton[gamescene], gamebuttonrect) で済むけど、 # とりあえずは、if文でわけておく if gamescene == 0: screen.blit(gamebutton[0], gamebuttonrect) elif gamescene == 1: for i in range(4): # 入力された数字を表示する領域 screen.blit(qimagelist[10], qbuttonrect[i]) for i in range(5): # 入力のためのボタンとなる画像0~4 screen.blit(imagelist[i], buttonrect[i]) for i in range(5, 10): # 入力のためのボタンとなる画像5~9 screen.blit(imagelist[i], buttonrect[i]) screen.blit(gamebutton[1], gamebuttonrect) elif gamescene ==2: screen.blit(gamebutton[2], gamebuttonrect) else: print("error") for event in pygame.event.get(): if event.type == QUIT: # 終了イベント running = False pygame.quit() # pygameのウィンドウを閉じる sys.exit() # システム終了 if (event.type == pygame.MOUSEBUTTONUP) and (event.button == 1): if gamebuttonrect.collidepoint(event.pos): if gamescene == 0: gamescene = 1 elif gamescene == 1: gamescene = 2 elif gamescene == 2: gamescene = 0 else: gamescene = -1 pygame.display.update() # 描画処理を実行 if __name__ == "__main__": main()
次回
今回のソースコード一式はgithubにもあります。
https://github.com/gomta777/hitandblow/
のcreategamescreenが今回のものです。
次回は、入力の処理を仕上げていきたいと思います。
よかったら、ブログ村↓のクリックお願いします。