Pygame学习笔记4:使用Math函数绘制Analog Clock

画圆的基本数学知识

制作一个时钟,首先要解决的问题就是画一个圆,而且在众多游戏中,如炮弹的飞行轨迹,子弹的射击轨迹等,都需要用到圆的相关知识,那么由数学的参数方程有:

x = R * cost
y = R * sint

然后我们开始尝试画一个圆,源代码如下:

import math
import random
import sys
import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((600, 500))
pygame.display.set_caption("Circle Demo")
screen.fill((0, 0, 200))

pos_x = 300
pos_y = 250
radius = 200
angle = 360

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()

    keys = pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        sys.exit()

    angle = (angle + 1) % 360
    color = random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)

    x = radius * math.cos(math.radians(angle))
    y = radius * math.sin(math.radians(angle))

    pos = (int(pos_x + x), int(pos_y + y))
    pygame.draw.circle(screen, color, pos, 10, 0)

    pygame.display.update()


运行结果如下:
在这里插入图片描述

Analog Clock程序

那么将前面的代码进一步深化,就可以制作一个时钟程序。我们还有几个问题要解决,那就是时针、分针、秒针的计算方法有些不一样,时针是12小时制(或者24小时制),分针和秒针是60制的,同时要将数字转换成对应的角度以实现正确的显示。

对于时针,角度与数字之间的转换如下:

hour * (360 / 12) - 90

减去90度是因为角度0是指向x轴的正半轴的,但是角度0对应的是12点,应该指向y轴正半轴。而Pygame中画线的角度是顺时针递增的,注意!!这里与我们数学中所熟知的逆时针角度递增不一样!!例子如下:

import math
import sys
import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((600, 500))
pos_x = 300
pos_y = 250
radius = 250
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()

    keys = pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        sys.exit()

    screen.fill((0, 0, 100))
    angle = math.radians(45)
    x = math.cos(angle) * radius
    y = math.sin(angle) * radius
    pygame.draw.line(screen, (255, 255, 255), (pos_x, pos_y), (pos_x + x, pos_y + y), 20)
    pygame.display.update()

运行结果如下:
在这里插入图片描述
可以看到,45度角指向的是第四象限而不是第一象限。

而对于分针和秒针,角度与数字之间的转换一样:

minute * (360 / 60) - 90
second * (360 / 60) - 90

源代码如下:

import math
import sys
import pygame
from pygame.locals import *
from datetime import datetime


def print_text(font, x, y, text, color=(255, 255, 255), shadow=True):
    imgText = font.render(text, True, color)
    screen.blit(imgText, (x, y))


def wrap_angle(angle):
    return angle % 360


if __name__ == "__main__":
    # 初始化操作
    pygame.init()
    screen = pygame.display.set_mode((600, 500))
    pygame.display.set_caption("Analog Clock")
    font = pygame.font.Font(None, 36)
    orange = 220, 180, 0
    white = 255, 255, 255
    yellow = 255, 255, 0
    pink = 255, 100, 100
    pos_x = 300
    pos_y = 250
    radius = 250
    angle = 360

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()

        keys = pygame.key.get_pressed()
        if keys[K_ESCAPE]:
            sys.exit()

        screen.fill((0, 0, 100))
        # 画一个圆
        pygame.draw.circle(screen, white, (pos_x, pos_y), radius, 6)
        # 画数字
        for n in range(1, 13):
            angle = math.radians(n * (360 / 12) - 90)
            x = (radius - 20) * math.cos(angle) - 10
            y = (radius - 20) * math.sin(angle) - 10
            print_text(font, pos_x + x, pos_y + y, str(n))
        # 获取当前时间
        today = datetime.today()
        hour = today.hour % 12
        minute = today.minute
        second = today.second
        # 绘制时针
        hour_angle = wrap_angle(hour * (360 / 12) - 90)
        hour_angle = math.radians(hour_angle)
        hour_x = math.cos(hour_angle) * (radius - 80)
        hour_y = math.sin(hour_angle) * (radius - 80)
        target = (pos_x + hour_x, pos_y + hour_y)
        pygame.draw.line(screen, pink, (pos_x, pos_y), target, 25)
        # 绘制分针
        minute_angle = wrap_angle(minute * (360 / 60) - 90)
        minute_angle = math.radians(minute_angle)
        minute_x = math.cos(minute_angle) * (radius - 60)
        minute_y = math.sin(minute_angle) * (radius - 60)
        target = (pos_x + minute_x, pos_y + minute_y)
        pygame.draw.line(screen, orange, (pos_x, pos_y), target, 12)
        # 绘制秒针
        second_angle = wrap_angle(second * (360 / 60) - 90)
        second_angle = math.radians(second_angle)
        second_x = math.cos(second_angle) * (radius - 40)
        second_y = math.sin(second_angle) * (radius - 40)
        target = (pos_x + second_x, pos_y + second_y)
        pygame.draw.line(screen, yellow, (pos_x, pos_y), target, 6)

        pygame.draw.circle(screen, white, (pos_x, pos_y), 20)
        print_text(font, 0, 0, str(today.hour) + ":" + str(minute) + ":" + str(second))
        pygame.display.update()


运行结果如下:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花无凋零之时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值