pythonで作るフラッシュ暗算(コード全文)

昔python/pygameを使ってフラッシュ暗算を作ったのですが、披露の場がなかったので供養します。ヾ(@⌒ー⌒@)ノ

こんな感じで数字が短時間表示されるので足し合わせていく、天才の遊びですね。

私は数学が苦手なので全くできないのですが、たまに見る特技披露でかっこいいなと思って作ってみました。

↓↓コード全文↓↓

import sys 
import pygame 
import winsound
import random

#画面に文字を表示する関数
def dismessage(sf,msg,h,c):
     sysfont = pygame.font.SysFont("hg正楷書体pro", 50)###フォントの設定
     message  =sysfont.render(msg,True,c) ###文字の色
     message_rect = message.get_rect()
     message_rect.center = (350,h)###表示する位置
     sf.blit(message,message_rect)###上記の設定を反映させる
     pygame.display.update()###画面の更新

def main():
    pygame.init()
    #引数で画面の大きさを
    screen = pygame.display.set_mode((720,480))
    font = pygame.font.Font(None, 32)
    font_1 = pygame.font.SysFont(None, 100)      
    font_2 = pygame.font.SysFont("hg正楷書体pro", 40)
    surface = pygame.display.get_surface()

    #ゲーム画面時に使用
    game = True
    #リザルト画面時に使用
    result = False

    #標示させる数字を足していく
    num_list = []
    #下二つはインプットボックスで使用
    text =""
    active = False

    for i in range(3,0,-1):
        screen.fill((250,250,250))###画面の更新
        dismessage(surface,str(i),200,(250,0,0))###カウントダウンを3秒間       
        pygame.time.delay(1000)###一秒まつ

    while game:
        screen.fill((0,0,0))
        screen.blit(font_2.render("フラッシュ暗算",True,(255,255,255)),(200,20))
        #範囲選択
        number = random.randint(1,100)
        num_list.append(number)

        screen.blit(font_1.render(str(number),True,(0,255,0)),(300,200))
        pygame.display.update()

        #ここの引数の長さが標示する時間の長さ
        pygame.time.delay(500)

        #num_list の要素数が15を超えた場合答え入力画面に
        if len(num_list) > 15:
            game = False
            pygame.init()
            screen.fill((250,250,250))
            input_box = pygame.Rect(200, 200, 140, 50)
            color_inactive = pygame.Color('lightskyblue3')
            color_active = pygame.Color('dodgerblue2')
            color = color_inactive

            result = True

    while result:
        screen.fill((0,0,0))
        answer = sum(num_list)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                 result = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                 if input_box.collidepoint(event.pos):
                     active = not active
                 else:
                     active = False
                 color = color_active if active else color_inactive
            if event.type == pygame.KEYDOWN:
                 if active:
                     if event.key == pygame.K_RETURN:
                        pygame.init()
                        screen.fill((250,250,250))
                        if text != str(answer):
                            screen.fill((250,0,0))
                            dismessage(surface,"不正解です",300,(0,0,0))###カウントダウンを3秒間       
                        screen.blit(font_2.render("正解は{}です。".format(answer),True,(0,0,0)),(200,200))
                        pygame.display.update()
                        pygame.time.delay(5000)
                        result = False
        
                     elif event.key == pygame.K_BACKSPACE:
                             text = text[:-1]
                     else:
                             text += event.unicode

        screen.fill((250,250,250))
        txt_surface = font.render(text, True, color)
        width = max(200, txt_surface.get_width()+10)
        input_box.w = width
        screen.blit(txt_surface, (input_box.x+5, input_box.y+5))
        pygame.draw.rect(screen, color, input_box, 2)
        pygame.display.flip()

main()

以下詳しい説明を

画面に文字を表示する関数

ここで作った関数は、文字列を画面内に表示させるためのものです。

具体的な使用例は、最初のカウントダウンと間違えた時に「不正解です」って表示する奴です。

引数に

def dismessage(sf,msg,h,c):
sysfont = pygame.font.SysFont(“hg正楷書体pro”, 50)###フォントの設定
message =sysfont.render(msg,True,c) ###文字の色
message_rect = message.get_rect()
message_rect.center = (350,h)###表示する位置
sf.blit(message,message_rect)###上記の設定を反映させる
pygame.display.update()###画面の更新

↓↓↓↓↓↓

dismessage(surface,str(i),200,(250,0,0))###カウントダウンを3秒間

みたいに使います。

引数の説明を

・よくわからないので省略

・表示する言葉の内容

・高さの座標

・色

メイン関数

基本的な動きはゲーム画面→リザルト画面だけです。

for i in range(3,0,-1):
  screen.fill((250,250,250))###画面の更新
  dismessage(surface,str(i),200,(250,0,0))###カウントダウンを3秒間
  pygame.time.delay(1000)###一秒まつ

上のコードでカウントダウンを行っています。

カウントダウンが終わったら

while game:

から下の処理をループで行い、

if len(num_list) > 15:

15回数字が表示されたら(初めに用意したからのリストの要素数が15になったら)ループを抜け、リザルト画面のループ処理に代わる。

といったものです。

リザルト画面ではインプットボックスが使用さrていますが、ここを理解するのは非常に面倒くさいです。

以下説明

    while result:
        screen.fill((0,0,0))
        answer = sum(num_list)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                 result = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                 if input_box.collidepoint(event.pos):
                     active = not active
                 else:
                     active = False
                 color = color_active if active else color_inactive
            if event.type == pygame.KEYDOWN:
                 if active:
                     if event.key == pygame.K_RETURN:
                        pygame.init()
                        screen.fill((250,250,250))
                        if text != str(answer):
                            screen.fill((250,0,0))
                            dismessage(surface,"不正解です",300,(0,0,0))###カウントダウンを3秒間       
                        screen.blit(font_2.render("正解は{}です。".format(answer),True,(0,0,0)),(200,200))
                        pygame.display.update()
                        pygame.time.delay(5000)
                        result = False
        
                     elif event.key == pygame.K_BACKSPACE:
                             text = text[:-1]
                     else:
                             text += event.unicode

        screen.fill((250,250,250))
        txt_surface = font.render(text, True, color)
        width = max(200, txt_surface.get_width()+10)
        input_box.w = width
        screen.blit(txt_surface, (input_box.x+5, input_box.y+5))
        pygame.draw.rect(screen, color, input_box, 2)
        pygame.display.flip()

インプットボックス(入力を受けているもの)の上でクリックがされると色が変わって、入力を受け付けるようになります。

押されたキーコードを文字列のテキストに追加していく、マックスの文字の長さが定義と文字列が長くなる場合のインプットボックス拡張の処理が書かれています。

バックスペースが押された場合、一番最後の文字を取り除く処理を行います。

そして、エンターキーを押された場合正解不正解を表示した後に、5秒の時間ををおいてループを抜ける。

といった処理になっています。(~_~;)

感想

冒頭でも述べた通り私は数学が苦手なのでこのゲームはできませんが、作ることができたので、これはもう得意なことフラッシュ暗算と答えてもいいのではないのかなと思います(できるとは言ってない)。

フラッシュ暗算の部分よりも、インプットボックスの作成に苦労した記憶があります。作ったのはずいぶんと前なので覚えていませんが(笑)。

引数やif文の数字を変えるとカスタマイズできていくのでぜひやってみてください。

ばいちゃ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です