> ## Content Index
> Fetch the complete content index at: https://www.geekjp.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 【簡単？】初心者がpython３とpygameでヒット＆ブローゲーム作ってみる　#03　画面作るよ【習作？】
- URL: https://www.geekjp.com/2019-11-19-015433/
- Published: 2019-11-18T16:54:33.000Z
- Updated: 2019-11-18T16:54:33.000Z
- Description: 前回は、テキストベースで作ったヒット＆ブローゲームにpygameのガワをかぶせるべく、簡易的な状態遷移の処理を書いてみました。 今回は、画面の構成を作っていきます。
- Author: 工学じじい
- Tags: ゲームプログラミング, 技術, Pygame, Python, #Import 2026-07-19 20:21, #Import 2026-07-19 20:24

![f:id:gomta777:20191115111505p:plain](https://www.geekjp.com/content/images/import/hatena/2019/11/20191115111505-1.png "f:id:gomta777:20191115111505p:plain")

- [初心者がpython３とpygameでヒット＆ブローゲーム作ってみる #03 画面作るよ](#初心者がpython３とpygameでヒットブローゲーム作ってみる-03画面作るよ)
  - [前回から](#前回から)
  - [画面構成](#画面構成)
    - [画面の作成 その１ 入力欄](#画面の作成その１入力欄)
    - [入力欄 描画処理を書く](#入力欄描画処理を書く)
  - [入力用ボタンとなる数字画像の表示](#入力用ボタンとなる数字画像の表示)
    - [入力用数字の画像を描画するコードの追加](#入力用数字の画像を描画するコードの追加)
  - [次回](#次回)

### 前回から

[【簡単？】初心者がpython３とpygameでヒット＆ブローゲーム作ってみる【習作？】 - 工学じじいの縁側日記](https://www.geekjp.com/2019-11-16-184245/)  
[【簡単？】初心者がpython３とpygameでヒット＆ブローゲーム作ってみる #02【習作？】 - 工学じじいの縁側日記](https://www.geekjp.com/2019-11-17-133208/)

前回は、テキストベースで作ったヒット＆ブローゲームにpygameのガワをかぶせるべく、簡易的な状態遷移の処理を書いてみました。  
今回は、画面の構成を作っていきます。

### 画面構成

完成イメージは、こんな感じです。

![f:id:gomta777:20191119001414p:plain](https://www.geekjp.com/content/files/images/import/hatena/2019/11/20191119001414.png "f:id:gomta777:20191119001414p:plain")

図 完成イメージ

左側上部に、答えの入力欄が数字４桁で、画面左側下部に０～９の数字が並んでいて、押した順に上部の入力欄に入力されます。  
左側には、現在までの、解答の履歴と、その時のヒット数、ブロー数が一覧で並んでいます。  
１５回×４ページ分の履歴を保存できるようにします。それで答えられなかったらゲームオーバーです。  
まず、入力欄から作っていきます。  
  
#### 画面の作成 その１ 入力欄

今回使う画像の一覧（次に使うのも入ってます。。。）は、以下のようになっています。  
Webのフリー素材でもいいですし、適当にofficeの作図機能で作ってもいいと思います。  
githubにもあるので、僕の作ったので良ければどうぞ。

![f:id:gomta777:20191119001954p:plain](https://www.geekjp.com/content/files/images/import/hatena/2019/11/20191119001954.png "f:id:gomta777:20191119001954p:plain")

図 画像一覧

初めに読み込む画像は、数字とアスタリスクの画像 \[00.png, 11.png, 22,png ～ 99.png, kome.png\] です。  
読み込みやすいように、連番のファイル名にしておいたので、このファイル名が並んだリストを作ります。  
画像は、プロジェクトフォルダ配下の「images」フォルダに全て納めてあります。

```python
    qfilestr = [] # 画像ファイル名を生成するためのリスト
    for i in range(10): # 問題の方の画像ファイルは　00.png~99.pngの名前になっている。
        qfilestr.append(str(i)+str(i) + ".png")  # 画像ファイル名を生成

```

次に、画面上での、解答欄の貼り付け位置を表す矩形（pygame.Rect型）を用意します。

数字１個当たりの画像の大きさは（幅、高さ）＝（１００，１００）です。これを、図のように並べていきます。  
  
```python
    margin = [100, 100] # ＊を表示する位置までのマージン
    imagesize = [100,100] # 画像１個当たりの大きさ

    qbuttonrect = [] #　＊を表示するための矩形を作成　＊のサイズは（１００，１００）
    for i in range(4): #marginの位置から４つ横に画像を並べるためのもの
        qbuttonrect.append(Rect(margin[0] + i * imagesize[1], margin[1], *imagesize))

```

これらを使って、いつものpygame.image.loadで読み込んでいきます。  
ここまでの部分をまとめると以下のようになります。

```python
    margin = [100, 100] # ＊を表示する位置までのマージン
    imagesize = [100,100] # 画像１個当たりの大きさ

    qfilestr = [] # 画像ファイル名を生成するためのリスト
    qimagelist = []  # 出題用の画像を保存しておくリスト０～９＋＊の画像が収まっている。
    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 = [] #　＊を表示するための矩形を作成　＊のサイズは（１００，１００）
    for i in range(4): #marginの位置から４つ横に画像を並べるためのもの
        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\]の位置に貼り付けるだけですので簡単です。

```python
 for i in range(4):
                screen.blit(qimagelist[10], qbuttonrect[i])

```

問題はこれを**どこのタイミングで描画するか**、です。

前回やったシーン切り替えのことを考えると、スタートボタンが押されたら、ゲームが始まったほうがそれっぽいですよね。  
ということで、  
gamescene==1のとき、すなわちゲーム中の時に入力欄を表示するのが自然な気がします。  
すなわち、前回のボタンを表示した部分で、以下の様に描画処理を書きます。

```python
        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")

```

これで、ゲームスタートを押すと＊＊＊＊と、アスタリスクが４つ表示されるはずです。

![f:id:gomta777:20191119014843p:plain](https://www.geekjp.com/content/files/images/import/hatena/2019/11/20191119014843.png "f:id:gomta777:20191119014843p:plain")

図 入力欄の表示

### 入力用ボタンとなる数字画像の表示

入力用のボタンとなる数字画像（画面左側下部）を読み込んで表示します。  
処理の内容は先ほどと変わらないので、コードのみ掲載しておきます。

```python
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の時に、描画されるように、追加します。

```python
        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): # 入力のためのボタンとなる画像０～４
                screen.blit(imagelist[i], buttonrect[i])
            for i in range(5, 10): # 入力のためのボタンとなる画像５～９
                screen.blit(imagelist[i], buttonrect[i])
            screen.blit(gamebutton[1], gamebuttonrect)
        elif gamescene ==2:
            screen.blit(gamebutton[2], gamebuttonrect)
        else:
            print("error")

```

実行してみます。  
game start ボタンを押すと、以下の画面が出れば成功です。

![f:id:gomta777:20191119014708p:plain](https://www.geekjp.com/content/files/images/import/hatena/2019/11/20191119014708.png "f:id:gomta777:20191119014708p:plain")

図 入力欄と入力ボタンの描画

なんとなく、どんな感じのゲームになるか見えてきましたね。

ここまでのソースコード一覧です。

```python
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] # 画像１個当たりの大きさ

    qfilestr = [] # 画像ファイル名を生成するためのリスト
    qimagelist = []  # 出題用の画像を保存しておくリスト０～９＋＊の画像が収まっている。
    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 = [] #　＊を表示するための矩形を作成　＊のサイズは（１００，１００）
    for i in range(4): #marginの位置から４つ横に画像を並べるためのもの
        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): # 入力のためのボタンとなる画像０～４
                screen.blit(imagelist[i], buttonrect[i])
            for i in range(5, 10): # 入力のためのボタンとなる画像５～９
                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/](https://github.com/gomta777/hitandblow/?ref=geekjp.com)  
のcreategamescreenが今回のものです。

次回は、入力の処理を仕上げていきたいと思います。

よかったら、ブログ村↓のクリックお願いします。