アナログ時計に時字を表示しよう
前回はアナログ時計に目盛りを表示しましたが、今回は目盛りの代わりに時字を表示しましょう。
時字とはアナログ時計の時間を表す数字のことです。
アナログ時計に時字を表示するプログラム
先に時字を表示するプログラムを提示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
### インポート import math import datetime import pygame from pygame.locals import * ### 定数 WIDTH = 400 # 幅 HEIGHT = 400 # 高さ RADIUS = 180 # 半径 NEEDLE_H = 120 # 短針 NEEDLE_M = 160 # 長針 NEEDLE_S = 150 # 秒針 MARK = 160 # 時字 BASE_AGL = 90 # 基準角度 CENTER = int(WIDTH/2),int(HEIGHT/2) ### モジュール初期化 pygame.init() ### 時間オブジェクト生成 clock = pygame.time.Clock() ### 画面設定 surface = pygame.display.set_mode((WIDTH,HEIGHT)) ### 無限ループ while True: ### 画面初期化 surface.fill((0,0,0)) ### 円表示 pygame.draw.circle(surface, (255,0,0), (CENTER), RADIUS, 2) ### 時字表示 dic = {"1":300,"2":330,"3":0,"4":30,"5":60,"6":90,"7":120,"8":150,"9":180,"10":210,"11":240,"12":270} for mark,angle in dic.items(): ### 時字作成 font = pygame.font.Font(None, 32) text = font.render(mark, True, (255,255,255)) ### 座標設定 mark_x = round(math.cos(math.radians(angle))*MARK)+CENTER[0]-int(font.size(mark)[0]/2) mark_y = round(math.sin(math.radians(angle))*MARK)+CENTER[1]-int(font.size(mark)[1]/2) ### 時字表示 surface.blit(text, (mark_x,mark_y)) ### 現在時刻取得 now = datetime.datetime.now() ### 角度計算 angle_h = float(BASE_AGL - 30 * now.hour - 0.5 * now.minute) # 時 angle_m = int(BASE_AGL - 6 * now.minute) # 分 angle_s = int(BASE_AGL - 6 * now.second) # 秒 ### 針の終端位置 pos_hx = round(math.cos(math.radians(angle_h))*NEEDLE_H) # 時のX座標 pos_hy = round(math.sin(math.radians(angle_h))*NEEDLE_H) # 時のY座標 pos_mx = round(math.cos(math.radians(angle_m))*NEEDLE_M) # 分のX座標 pos_my = round(math.sin(math.radians(angle_m))*NEEDLE_M) # 分のY座標 pos_sx = round(math.cos(math.radians(angle_s))*NEEDLE_S) # 秒のX座標 pos_sy = round(math.sin(math.radians(angle_s))*NEEDLE_S) # 秒のY座標 ### 針表示 pygame.draw.line(surface, (255,255,255), (CENTER), (CENTER[0]+pos_hx,CENTER[1]-pos_hy), 9) pygame.draw.line(surface, (255,255,255), (CENTER), (CENTER[0]+pos_mx,CENTER[1]-pos_my), 7) pygame.draw.line(surface, (255,255,255), (CENTER), (CENTER[0]+pos_sx,CENTER[1]-pos_sy), 2) ### 画面更新 pygame.display.update() ### フレームレート設定 clock.tick(100) ### イベント処理 for event in pygame.event.get(): if event.type == KEYDOWN and event.key == K_ESCAPE: break else: continue ### whileループ終了 break ### 終了処理 pygame.quit() |
プログラムを実行すると、アナログ時計に時字が表示されます。
時字の座標を調整する
45、46行目で表示する時字の座標をずらしているのが、このプログラムのポイントです。
座標の終端位置にそのまま時字を表示させると、以下のようなイメージになってしまいます。
これだと時字がずれてしまい見栄えが悪いので、以下のように時字の中心が終端座標の位置になるようにします。
時字の位置をフォントの幅と高さの半分のサイズでマイナスにすると、終端座標の位置が時字の中心になります。
時字をローマ数字にしよう
上記のプログラムで定義した辞書の時字部分をローマ数字に書き替えれば、そのままローマ数字が表示されます。
また、フォントもローマ数字に似合うものに変えてみましょう。
フォントに関しては、こちらの記事を参考にしてください。
ここでは、以下のように変更しました。
pygame.font.Font(None, 32) → pygame.font.SysFont("yumincho", 32)
ローマ数字は幅を取るので、表示する時字の座標を若干円の内側にしています。(MARK = 160 → MARK = 155)
また、ローマ数字は機種依存文字なので、フォントによっては対応していない場合があります。
プログラムを実行すると、時字がローマ数字になります。