質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.99%

  • Python

    5565questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pygame python ゲーム

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 247
import pygame
from pygame.locals import *
import sys
import time
def main():

    (w,h) = (400,400)   # 画面サイズ
    (x,y) = (w/2, h/2)
    pygame.init()       # pygame初期化
    pygame.display.set_mode((w, h), 0, 32)  # 画面設定
    screen = pygame.display.get_surface()
    pygame.display.set_caption("5byoudetomete")
    # 画面設定 文字
    sysfont = pygame.font.SysFont(None, 40)
    # テキストを描画したSurface作成、画像の作成
    click_start = sysfont.render("click to start", False, (0,0,0))
    count_during = sysfont.render("in measurement", False, (0,0,0))
    tokei = pygame.image.load("tokei.png").convert_alpha()
    rect_tokei = tokei.get_rect()
    rect_tokei.center = (200, 180)
    screen.fill((255,255,255, ))          # 画面の背景色
    screen.blit(click_start, (20,350))
    pygame.display.update()             # 画面更新
    tmp = 0
    while (1):

        # 終了用のイベント処理
        for event in pygame.event.get():
            if event.type == QUIT:          # 閉じるボタンが押されたとき
                pygame.quit()
                sys.exit()
 # マウスクリック1回目の処理(カウント中) 
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                if tmp == 0:
                    t1 = time.time()
                    screen.fill((255,255,255, ))
                    screen.blit(count_during, (20,350))
                    screen.blit(tokei, rect_tokei)    # 画像の描画
                    pygame.display.update()             # 画面更新 
                    tmp = tmp+1
 #マウスクリック2回目の処理(結果の出力)
                elif tmp == 1:
                    t2 = time.time()-t1-5
                    screen.fill((255,255,255, ))
                    dif = sysfont.render("difference"+str(t2), False, (0,0,0))
                    screen.blit(dif, (20,350))
                    pygame.display.update()
                    tmp = 0

if __name__ == "__main__":
        main()

python初心者で課題としてゲーム作成をしています。

現在反射神経ゲームを作ろうとしたところ挫折し、ストップウォッチゲームに変更したのですが、複数プレイ後スコアの入出力を行いたいのですがゲームが1回しかできないため複数回できるようにご指摘お願いいたします。マウスクリック1、2回目のifがループするのは気にしないでください。
また、dif = sysfont.render("difference"+str(t2), False, (0,0,0))の文においてstr(t2)が長くなりすぎてしまうためstr型の文字列長を短くする(見た目上は小数点の切り上げ)方法でもつまづいているためアドバイスお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

クラス化及び関数化したほうがよいよ思われますが、できるだけ元ソースを残しつつ改造してみました。

  1. ハイスコア対応
  2. time.time()は精度があまりよくないので、time.perf_counter()に変更
  3. Enum型のGameStateを追加
  4. initialize(初期化処理)とon_application_exit(終了処理)を関数化
# -*- coding: UTF-8 -*
import sys
import time
import math
from enum import Enum, unique
import pygame
from pygame.locals import *


@unique
class GameState(Enum):
    START = 1
    COUNT_UP = 2
    RESULT = 3


def initialize():
    (w,h) = (400,400)   # 画面サイズ
    (x,y) = (w/2, h/2)
    pygame.init()       # pygame初期化
    pygame.display.set_mode((w, h), 0, 32)  # 画面設定
    screen = pygame.display.get_surface()
    pygame.display.set_caption("5byoudetomete")
    return screen


def on_application_exit():
    pygame.quit()
    sys.exit()


def display_high_score(screen, sysfont, high_scores, score=None):
    # ヘッダー行
    text = sysfont.render("###    High Score    ####", False, (0, 0, 0))
    screen.blit(text, (20, 0))
    # 各scoreの表示
    for i, scores in enumerate(high_scores):
        index = i + 1
        marker = ' ' * 3
        if scores == score:
            marker = '->'
        text = "{0}{1}:{2}".format(marker, index, scores)
        text_render = sysfont.render(text, False, (0, 0, 0))
        screen.blit(text_render, (20, 30 * index))


def main():
    BACKGROUND_COLOR = (255, 255, 255,)# 画面の背景色
    STATUS_BAR = (20, 350)
    screen = initialize()
    # 画面設定 文字
    sysfont = pygame.font.SysFont(None, 40)
    # テキストを描画したSurface作成、画像の作成
    click_start = sysfont.render("click to start", False, (0,0,0))
    count_during = sysfont.render("in measurement", False, (0,0,0))
    tokei = pygame.image.load("tokei.png").convert_alpha()
    rect_tokei = tokei.get_rect()
    rect_tokei.center = (200, 180)
    screen.fill(BACKGROUND_COLOR)
    screen.blit(click_start, STATUS_BAR)
    pygame.display.update()             # 画面更新
    game_state = GameState.START
    high_scores = []
    while True:
        for event in pygame.event.get():
            # 終了用のイベント処理
            if event.type == QUIT:          # 閉じるボタンが押されたとき
                on_application_exit()
                continue
 # マウスクリック1回目の処理(カウント中)
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                screen.fill(BACKGROUND_COLOR)  # 画面の背景色
                if game_state == GameState.START:
                    t1 = time.perf_counter()
                    screen.blit(count_during, STATUS_BAR)
                    screen.blit(tokei, rect_tokei)    # 画像の描画
                    game_state = GameState.COUNT_UP #ゲームの状態を「カウントアップ」に変更
 #マウスクリック2回目の処理(結果の出力)
                elif game_state == GameState.COUNT_UP:
                    # 5sec
                    t2 = time.perf_counter()-t1-5
                    score = round(t2, 4)
                    dif = sysfont.render("difference:{0}".format(score), False, (0,0,0))
                    screen.blit(dif, STATUS_BAR)
                    high_scores.append(score)
                    # math.fabsを使って0からの相対的なソートを行う
                    high_scores.sort(key=math.fabs)
                    if len(high_scores) > 5:
                        high_scores.pop() #最大5件に。
                    #ハイスコアの表示
                    display_high_score(screen, sysfont, high_scores, score)

                    game_state = GameState.RESULT #ゲームの状態を「リザルト」に変更
                elif game_state == GameState.RESULT:
                    screen.blit(click_start, STATUS_BAR)
                    game_state = GameState.START #ゲームの状態を「スタート」に変更
                else:
                    assert False, game_state
                pygame.display.update()  # 画面更新
                continue


if __name__ == "__main__":
    main()

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/19 01:22 編集

    Enum型便利そうですね。勉強になりました。m(_ _)m

    キャンセル

  • 2018/01/19 01:43

    Enum型は使える環境(3.4以降)だと使うと便利ですー。。

    キャンセル

  • 2018/01/19 03:27

    関数化によってコードを綺麗にして頂きありがとうございます。
    Enum型に関して再度質問投稿、もしくはここで尋ねさせていただくかもしれません。
    解答ありがとうございました!

    キャンセル

+2

tmpでの場合分けを0 1ではなく、0 1 2の三段階にすればいいのではないでしょうか?

試してませんけど以下のようなコードでいけると思います。

import pygame
from pygame.locals import *
import sys
import time
def main():

    (w,h) = (400,400)   # 画面サイズ
    (x,y) = (w/2, h/2)
    pygame.init()       # pygame初期化

〜〜〜〜省略〜〜〜〜

            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                if tmp == 0:
                    t1 = time.time()
                    screen.fill((255,255,255, ))
                    screen.blit(count_during, (20,350))
                    screen.blit(tokei, rect_tokei)    # 画像の描画
                    pygame.display.update()             # 画面更新 
                    #tmp = tmp+1
                    tmp += 1
 #マウスクリック2回目の処理(結果の出力)
                elif tmp == 1:
                    t2 = time.time()-t1-5
                    screen.fill((255,255,255, ))
                    dif = sysfont.render("difference"+str(t2), False, (0,0,0))
                    screen.blit(dif, (20,350))
                    pygame.display.update()
                    #tmp = 0
                    tmp += 1
                # ここから追加
                elif tmp == 2:
                    screen.fill((255,255,255, )) # 画面の背景色
                    screen.blit(click_start, (20,350))
                    pygame.display.update() # 画面更新
                    tmp = 0

if __name__ == "__main__":
        main()

またt2の長さの件ですが、
例えば小数第三位で四捨五入したいなら、

str(round(t2,2))

とすれば丸められます。

他にも切り捨てで良く、単純に長さだけで考えるなら、

str(t2)[:4]

みたいな感じでスライス機能を使うという手もあります。ちなみに上記コードの場合ドットを含めた4文字分(例えば0.114514なら0.11)になります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/19 03:14

    解答ありがとうございます
    round関数参考になりました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.99%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    5565questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。