Почему стрелки моих аналоговых часов Python показывают неправильное время? - PullRequest
0 голосов
/ 03 сентября 2018

Я делаю программу аналоговых часов с 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 голосов
/ 03 сентября 2018

Есть две проблемы:

  1. Углы, которые вы передаете math.cos и math.sin, должны быть в радианах, а не в градусах, поэтому вы должны преобразовать их в math.radians.

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

  2. Ось Y в Pygame инвертирована, поэтому передайте отрицательный угол на 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...