> ## 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.

# 【pygame】pythonでヒット＆ブローゲーム作る　#06　ログの表示をかっこよく【簡単】
- URL: https://www.geekjp.com/2019-11-24-023919/
- Published: 2019-11-23T17:39:19.000Z
- Updated: 2019-11-23T17:39:19.000Z
- Description: python プログラミング 入門シリーズです。 pythonとpygameを使ってとても簡単なゲームを作ってみます。 今回は、ログの表示をかっこよくタブとページで切り替えます。
- Author: 工学じじい
- Tags: ゲームプログラミング, 技術, Pygame, Python, #Import 2026-07-19 20:21, #Import 2026-07-19 20:24

【pygame】pythonでヒット＆ブローゲーム作る #06 ログの表示をかっこよく【簡単】

![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でヒット＆ブローゲーム作ってみる【習作？】 - 工学じじいの縁側日記](https://www.geekjp.com/2019-11-16-184245/)  
[【簡単？】初心者がpython３とpygameでヒット＆ブローゲーム作ってみる #02【習作？】 - 工学じじいの縁側日記](https://www.geekjp.com/2019-11-17-133208/)  
[【簡単？】初心者がpython３とpygameでヒット＆ブローゲーム作ってみる #03 画面作るよ【習作？】 - 工学じじいの縁側日記](https://www.geekjp.com/2019-11-19-015433/)  
[【pygame】pythonでヒット＆ブローゲーム作る #04 数字の入力【簡単】 - 工学じじいの縁側日記](https://www.geekjp.com/2019-11-19-170123/)  
[【python】ヒット＆ブローゲーム作る #05 正誤判定、ログの表示【プログラミング】 - 工学じじいの縁側日記](https://www.geekjp.com/2019-11-22-052748/)

前回までで、タイトル画面、ゲーム画面の状態遷移、

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

図 状態遷移

問題の出題と、解答の入力とチェック

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

図 解答の入力とチェック

最後に、ログの表示を（割と適当に）やりました。

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

図 解答ログの表示

これで一通りのゲームにはなるのですが、ログが１５、６回で画面買いに流れてしまって見えなくなってしまいます。  
今回はこれを解決するべく、**ログの表示をかっこ良いタブを使ったページ切り替えにしてみます！**

それでは、作っていくー(笑)

### ログの表示枠

まず初めに、ログの表示に枠を付けて、「それっぽく」してみます。

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

図 オブジェクトの配置

#### グリッド表示関数を作成

この配置を元に、関数を作っていきます。  
解説と異なるフォントを使った人は、少し枠の大きさの調整が必要です。  
文字を描画するのに必要な領域のサイズは、  
Font.size 命令で取得できます。(今回は高さに３０必要だったので、３０がたくさん出てきてます）  
  
```python
def draw_judgment_grid(surface):
    bias = 90
    pygame.draw.rect(surface, (255, 255, 255), (555, bias, 335, 30 * 15), 2)
    for i in range(14):
        pygame.draw.line(surface, (255, 255, 255), (555, bias + 30 * (i + 1)), (555 + 335, bias + 30 * (i + 1)), 2)
    pygame.draw.line(surface, (255, 255, 255), (630, bias), (630, 30 * 18), 2)
    pygame.draw.line(surface, (255, 255, 255), (728, bias), (728, 30 * 18), 2)
    pygame.draw.line(surface, (255, 255, 255), (800, bias), (800, 30 * 18), 2)def draw_judgment_grid(surface):
    bias = 90
    pagesize = 15
    baserect = Rect(555, 90, 335, 30)
    pygame.draw.rect(surface, (255, 255, 255), \
        (baserect.left, baserect.top, baserect.width, baserect.height * pagesize), 2)
    for i in range(pagesize):
        pygame.draw.line(surface, (255, 255, 255), \
            (baserect.left, baserect.top + baserect.height * (i + 1)), \
            (555 + 335, bias + 30 * (i + 1)), 2)
    pygame.draw.line(surface, (255, 255, 255),\
        (baserect.left + 75, baserect.top), (baserect.left + 75, baserect.top + baserect.height * pagesize), 2)
    pygame.draw.line(surface, (255, 255, 255), \
        (baserect.left + 173, baserect.top), (baserect.left + 173, baserect.top + baserect.height * pagesize), 2)
    pygame.draw.line(surface, (255, 255, 255), \
        (baserect.left + 245, baserect.top), (baserect.left + 245, baserect.top +baserect.height * pagesize), 2)

（省略）

   if gamescene == 0:
            screen.blit(title, titlepos)
            screen.blit(gamebutton[0], gamebuttonrect)
        elif gamescene == 1:
            draw_judgment_grid(screen)

（省略）

```

実行するとこんな感じになります。

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

図 ロググリッドの表示

### ページに合わせたデータ形式

これまでは、以下の様に「judgement」ボタンを押したときにリストanslogに、判断結果を順次追加していました。

```python
judge = judgement(players_input, question)
anslog.append("%02d 回目 " % turn + str(players_input) + \
"  " + str(judge[0]) + " HIT  " + str(judge[1]) + " BLOW")
turn += 1

```

これを、タブボタンによるページ切り替えで表示します。  
今回考えてるページは、

- １ページ１５回分の記録
- ４ページ
- 上部のタブボタンでページ切り替え可能

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

図 タブとページのイメージ

#### ページを表すリストを生成

１５(行）ｘ４（ページ）を表すリストを生成します。  

```python
    baserect = Rect(555, 90, 335, 30)  # ログの表示領域の一段分
    pagesize = 15 # ページ当たりのログ数
    pages = 4 #最大ページ数
    judgement_pages = [["" for i in range(pagesize)] for j in range(pages)]
    # 15x5ページ分のリストを用意します judgement_pages[ログ][ページ]
  pygame.draw.rect(surface, (0,0,0), \
        (baserect.left, baserect.top, baserect.width, baserect.height * pagesize))
    # ログ表示領域の背景を黒で初期化

```

最後の行は、表示領域を見やすいように黒で初期化しているだけです。  
次に、１次元的に、順次保存されているログを保存しているリスト(anslog)をページ分けしてあげます。  
１５個以上あった時は、次のページに保存してあげればいいですね。

 if i\*pagesize+j < len(logmsg):  
 judgement\_pages\[i\]\[j\] = logmsg\[i\*pagesize+j\]

の部分で、ページに割り振りされています。

```python
# pages = 4
# pagesize = 15
# logmsgはanslogが実引数で渡されてくるはず
    for i in range(pages):
        for j in range(pagesize):
            if i*pagesize+j < len(logmsg):
                judgement_pages[i][j] = logmsg[i*pagesize+j]
    # ログを、ページに書き写す　１次元配列→２次元配列化

```

#### 指定されたページを描画

データは準備できたので、指定されたページを描画します。  
ここが、この処理の肝になる部分ですね。

```python
for i in range(pagesize):
    if len(logmsg) != 0 and i == (len(logmsg) - 1) % pagesize:
    # ログが空じゃなくて、iが指定ページの表示できる範囲内なら描画
        pygame.draw.rect(surface, (100, 0, 0), \
            (baserect.left, baserect.top + baserect.height * i, baserect.width, baserect.height))
        # 一番新しいログは目立つように色を変える
    text1 = fnt.render(judgement_pages[pagenum][i], True, (255, 255, 255))
    surface.blit(text1, (baserect.left+5, baserect.height * i + baserect.top+10 - 3))
    # 描画テキストを生成し描画
# ４ページあるうちの指定されたページのログを描画する

```

前ページの中から指定されたページの１５個のログを表示しているだけです。ちょっと面倒ですが、よく読むとそんなに複雑ではないことがわかると思います。

これで、指定されたページのログが表示できます。

#### ページ数を表すタブを表示

タブを表示します。  
ここにきてまた新しい画像を読み込まなければならないですが、説明は最小限にします。

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

図 タブ画像

ファイル名は、オレンジの方がtab1\~tab4.png、みどりのほうがtab1a\~tab4a.pngにしていますので、for文でループを作って読み込みやすくなっています。  
処理に関しては、すでに説明済みのものばかりです。（数字ボタンの読み込みと表示の時と同じです）

```python
tabimagelist = []
tabimagename = []
for i in range(4):
    tabimagename.append("tab"+str(i+1) + ".png")
for i in range(4):
    tabimagelist.append(pygame.image.load("./images/" + tabimagename[i]))
atabimagelist = []
atabimagename = []
for i in range(4):
    atabimagename.append("tab" + str(i + 1) + "a.png")
for i in range(4):
    atabimagelist.append(pygame.image.load("./images/" + atabimagename[i]))
tabimagerect = []
for i in range(4):
    tabimagerect.append(Rect(555 + i * 83, 90 - 39, 85, 40))
# baserect = Rect(555, 90, 335, 30) 描画領域から、タブの位置を逆算してます
# tab画像の大きさは　83x39で計算　描画は85x40で描画しています。

```

#### タブ表示関数の作成

次に、タブを描画する関数draw\_tabsを作ります。

```python
def draw_tabs(surface, tabnumber, tabimage, atabimage, tabrect):
    baserect = Rect(555, 90, 335, 30)  # ログの表示領域の一段分
    tabsize = [83, 39]
    for i in range(4):
        if i == tabnumber: # 指定されたタブならば、赤いタブ画像
            # surface.blit(tabimage[i], (baserect.left + i * tabsize[0], baserect.top - tabsize[1]))
            surface.blit(tabimage[i], tabrect[i])
        else: #それ以外は緑のタブ画像で表示
            # surface.blit(atabimage[i], (baserect.left+i*tabsize[0], baserect.top - tabsize[1]))
            surface.blit(atabimage[i], tabrect[i])

```

この辺は何度も出てきている描画処理の組み合わせなので、そんなには悩むところはないと思います。

読み込んだタブ画像を、実際に表示します。  
現在表示しているタブは、オレンジで、その他のタブは緑で表示します。  
結果の表示のあたりにこっそり入れてやります。  
現在のタブは、まだ処理をしていないので、とりあえず変数current\_tab（現在のページを表す）  
を作っておいて0(１ページ目）を指定しておきます。

```python
current_tab = 0
（省略）　　　　
draw_judgement_state(screen, log_font, anslog, current_tab)
draw_tabs(screen, current_tab, tabimagelist, atabimagelist)
draw_judgment_grid(screen)

```

実行結果：

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

図 タブの表示

#### ページ切り替えの実装

ページ切り替えの実装は、タブの表示領域を苦リクしたときに、押した画像の領域によってcurrent\_tabの番号を0\~3に切り替えて、ログ表示関数であるdraw\_judgement\_stateに私直す事で実現します。

```python
for i in range(len(tabimagerect)):
    if gamescene == 1:
        if tabimagerect[i].collidepoint(event.pos):
            current_tab = i

```

また、「judgement」ボタンが正しく押されて、anslogが増えていくと自動的にcurrent\_tabを切り替えます。  
現在のページ数は、ログの数を１５で割った整数となります。

```python
 current_tab = (len(anslog) - 1) // 15

```

これでページの切り替えができます。

実行結果：

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

図 タブの切り替え

１ページ目が埋まり、２ページ目にログが表示され、３，４ページ目はまだ空なのがわかります。

### 今回のまとめ

今回はログの表示をかっこよく、タブとページで実装してみました。  
プログラム的にはちょっと面白いところだったのではないかなと思います。  
  
### 次回

今回のソースコード一式はgithubにもあります。  
[https://github.com/gomta777/hitandblow/](https://github.com/gomta777/hitandblow/?ref=geekjp.com)  
のtabpaesが今回のものです。

次回は、最終回です。  
ゲームとしてはほとんど完成したと思いますので、最後の細かいところを修正して完成としたいと思います！

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