为什么我的python模拟时钟的指针显示错误的时间?

时间:2018-09-03 14:58:27

标签: python python-3.x datetime pygame

我正在用pygame,datetime和math制作一个模拟时钟程序,但是指针的角度都已断开,而第二只手的走得太快了。这是代码:

import pygame
from datetime import datetime
from datetime import time
from datetime import timedelta
import math
import time

pygame.init()

white = (255, 255, 255)
black = (0, 0, 0)

display_width = 400
display_height = 400

gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Clock')

gameDisplay.fill(white)

clock = pygame.time.Clock()

clock_radius = 200
clock_center = int(display_width / 2), int(display_height / 2)


def main():
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()

    # Drawing the clock and its center.
    pygame.draw.circle(gameDisplay, black, clock_center, clock_radius, 5)
    pygame.draw.circle(gameDisplay, black, clock_center, 5, 0)
    pygame.display.update()

    # I move the hands by drawing a white line over the previous line
    # and then drawing the new line (which is a hand), so I need a
    # variable equal to the time one second ago (for the white line) as
    # well as the current time (for the current hand).
    now_hour = int(datetime.now().strftime('%I'))
    now_minute = int(datetime.now().strftime('%M'))
    now_second = int(datetime.now(). strftime('%S'))

    one_sec_ago_hour = int((datetime.now() - timedelta(seconds=1)).strftime('%I'))
    one_sec_ago_minute = int((datetime.now() - timedelta(seconds=1)).strftime('%M'))
    one_sec_ago_second = int((datetime.now() - timedelta(seconds=1)).strftime('%S'))

    # Drawing the lines/defining the endpoints with math.
    pygame.draw.line(gameDisplay, white, clock_center, ((clock_radius * (3 / 5)) * math.cos(90 - one_sec_ago_hour * 30) + 200, (clock_radius * (3 / 5)) * math.sin(90 - one_sec_ago_hour * 30) + 200), 10)
    pygame.draw.line(gameDisplay, white, clock_center, (clock_radius * (4 / 5) * math.cos(90 - one_sec_ago_minute * 6) + 200, clock_radius * (4 / 5) * math.sin(90 - one_sec_ago_minute * 6) + 200), 3)
    pygame.draw.line(gameDisplay, white, clock_center, (clock_radius * math.cos(90 - one_sec_ago_second * 6) + 200, clock_radius * math.sin(90 - one_sec_ago_second * 6) + 200), 1)
    pygame.display.update()

    pygame.draw.line(gameDisplay, black, clock_center, ((clock_radius * (3 / 5)) * math.cos(90 - now_hour * 30) + 200, (clock_radius * (3 / 5)) * math.sin(90 - now_hour * 30) + 200), 10)
    pygame.draw.line(gameDisplay, black, clock_center, (clock_radius * (4 / 5) * math.cos(90 - now_minute * 6) + 200, clock_radius * (4 / 5) * math.sin(90 - now_minute * 6) + 200), 3)
    pygame.draw.line(gameDisplay, black, clock_center, (clock_radius * math.cos(90 - now_second * 6) + 200, clock_radius * math.sin(90 - now_second * 6) + 200), 1)
    pygame.display.update()

    # Making the loop one second long.
    time.sleep(1)

1 个答案:

答案 0 :(得分:2)

有两个问题:

  1. 您传递给math.cosmath.sin的角度必须是弧度而非角度,因此必须使用math.radians进行转换。

    x = clock_radius * (3 / 5) * math.cos(math.radians(90 - now_hour * 30)) + 200

  2. Pygame的y轴是倒置的,因此请将负角传递到math.sin

    y = clock_radius * (3 / 5) * math.sin(-math.radians(90 - now_hour * 30)) + 200


您还可以通过以下方法简化代码:每帧用white填充屏幕并重画圆和手,然后不必计算以前的手就可以删除它们。另外,缺少while循环。这是更新后的main函数:

def main():
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return

        now_hour = int(datetime.now().strftime('%I'))
        now_minute = int(datetime.now().strftime('%M'))
        now_second = int(datetime.now(). strftime('%S'))

        gameDisplay.fill(white)
        pygame.draw.circle(gameDisplay, black, clock_center, clock_radius, 5)
        pygame.draw.circle(gameDisplay, black, clock_center, 5, 0)
        # Hour hand.
        x = clock_radius * (3 / 5) * math.cos(math.radians(90 - now_hour * 30)) + 200
        y = clock_radius * (3 / 5) * math.sin(-math.radians(90 - now_hour * 30)) + 200
        pygame.draw.line(gameDisplay, black, clock_center, (x, y), 10)
        # Minute hand.
        x = clock_radius * (4 / 5) * math.cos(math.radians(90 - now_minute * 6)) + 200
        y = clock_radius * (4 / 5) * math.sin(-math.radians(90 - now_minute * 6)) + 200
        pygame.draw.line(gameDisplay, black, clock_center, (x, y), 3)
        # Second hand.
        x = clock_radius * math.cos(math.radians(90 - now_second * 6)) + 200
        y = clock_radius * math.sin(-math.radians(90 - now_second * 6)) + 200
        pygame.draw.line(gameDisplay, black, clock_center, (x, y), 1)

        pygame.display.update()
        # Making the loop one second long
        time.sleep(1)