Clock in Python

2019-07-27 02:34发布

问题:

I am currently working on creating a clock using python 2.7.5 and pygame. Here is my code so far:

screen = display.set_mode((800,600))



running=True
while running:
    for e in event.get():
        if e.type == QUIT:
            running = False
    screen.fill((0,0,0))
    draw.circle(screen,(255,255,255),(400,300),100,3)
    ang = 270
    def clock(secs, mins, hours):
        ang = 270+6*secs
        dx = int(cos(radians(-ang))*100)
        dy = int(sin(radians(-ang))*100)
        draw.line(screen,(255,0,255),(400,300),(400+dx,300-dy),1)
        time.wait(1000)
    ang+=6
    clock(1,1,1)
    display.flip()
quit()

I am currently having problems with the adding the minutes and hours hands. What I would like to have happen I would like to be able to set any parameter(within 0,60) in the secs so that the seconds hand on the clock can begin from that point on the clock and continue to move 6 degrees clockwise from that point every second. I can currently only have either the hand moving every second but only starting from 0 degrees (the 12 on the clock) or I can have it start according to the parameters that are imputed but it does not move. I would also like to know how I would set different time.waits for different hands on the clock if that is possible. Thanks.

回答1:

Working example. I use clock.tick(1) to wait 1 second.

Use code from comments to get smoother move.

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

#----------------------------------------------------------------------

init()

screen = display.set_mode((800,600))

clock = time.Clock()

hours = 5
minutes = 59
seconds = 50

running=True
while running:

    # events 

    for e in event.get():
        if e.type == QUIT:
            running = False

    # (variable) modifications

    seconds_ang = 270 + 6 * seconds

    seconds_dx = int(cos(radians(-seconds_ang))*200)
    seconds_dy = int(sin(radians(-seconds_ang))*200)

    minutes_ang = 270 + 6 * minutes
    #minutes_ang = 270 + 6 * (minutes + seconds/60.) # smoother move

    minutes_dx = int(cos(radians(-minutes_ang))*200)
    minutes_dy = int(sin(radians(-minutes_ang))*200)

    hours_ang = 270 + 30 * hours
    #hours_ang = 270 + 30 * (hours + minutes/60.) # smoother move

    hours_dx = int(cos(radians(-hours_ang))*150)
    hours_dy = int(sin(radians(-hours_ang))*150)

    seconds += 1

    if seconds == 60:
        seconds = 0
        minutes += 1

        if minutes == 60:
            minutes = 0
            hours += 1

            if hours == 12:
                hours = 0

    # draw

    screen.fill((0,0,0))
    draw.circle(screen, (255,255,255), (400,300), 200, 3)
    draw.line(screen,(0,255,255), (400,300), (400 + hours_dx, 300 - hours_dy), 5)
    draw.line(screen,(255,255,0), (400,300), (400 + minutes_dx, 300 - minutes_dy), 2)
    draw.line(screen,(255,0,255), (400,300), (400 + seconds_dx, 300 - seconds_dy), 1)

    # flip

    display.flip()

    # FPS (Frames Per Seconds)

    clock.tick(1)

quit()

Using get_ticks() I can set any FPS and I can have second clock working 10 times faster :)

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

#----------------------------------------------------------------------

init()

screen = display.set_mode((800,600))

clock = time.Clock()

hours = 5
minutes = 59
seconds = 50

hours2 = 5
minutes2 = 59
seconds2 = 50

time_to_move_clock_1 = time.get_ticks()
time_to_move_clock_2 = time.get_ticks()

running=True
while running:

    # events 

    for e in event.get():
        if e.type == QUIT:
            running = False

    # (variable) modifications

    if time_to_move_clock_1 <= time.get_ticks():
        time_to_move_clock_1 += 1000 # 1000ms = 1s

        seconds_ang = 270 + 6 * seconds

        seconds_dx = int(cos(radians(-seconds_ang))*200)
        seconds_dy = int(sin(radians(-seconds_ang))*200)

        minutes_ang = 270 + 6 * (minutes + seconds/60.)

        minutes_dx = int(cos(radians(-minutes_ang))*200)
        minutes_dy = int(sin(radians(-minutes_ang))*200)

        hours_ang = 270 + 30 * (hours + minutes/60.)

        hours_dx = int(cos(radians(-hours_ang))*150)
        hours_dy = int(sin(radians(-hours_ang))*150)

        seconds += 1

        if seconds == 60:
            seconds = 0
            minutes += 1

            if minutes == 60:
                minutes = 0
                hours += 1

                if hours == 12:
                    hours = 0

    if time_to_move_clock_2 <= time.get_ticks():
        time_to_move_clock_2 += 100 # 100ms = 0.1s (10 times faster)

        seconds_ang2 = 270 + 6 * seconds2

        seconds_dx2 = int(cos(radians(-seconds_ang2))*100)
        seconds_dy2 = int(sin(radians(-seconds_ang2))*100)

        minutes_ang2 = 270 + 6 * (minutes2 + seconds2/60.)

        minutes_dx2 = int(cos(radians(-minutes_ang2))*100)
        minutes_dy2 = int(sin(radians(-minutes_ang2))*100)

        hours_ang2 = 270 + 30 * (hours2 + minutes2/60.)

        hours_dx2 = int(cos(radians(-hours_ang2))*75)
        hours_dy2 = int(sin(radians(-hours_ang2))*75)

        seconds2 += 1

        if seconds2 == 60:
            seconds2 = 0
            minutes2 += 1

            if minutes2 == 60:
                minutes2 = 0
                hours2 += 1

                if hours2 == 12:
                    hours2 = 0

    # draw

    screen.fill((0,0,0))
    draw.circle(screen, (255,255,255), (400,300), 200, 3)
    draw.line(screen,(0,255,255), (400,300), (400 + hours_dx, 300 - hours_dy), 5)
    draw.line(screen,(255,255,0), (400,300), (400 + minutes_dx, 300 - minutes_dy), 2)
    draw.line(screen,(255,0,255), (400,300), (400 + seconds_dx, 300 - seconds_dy), 1)

    draw.circle(screen, (255,255,255), (100,100), 100, 3)
    draw.line(screen,(0,255,255), (100,100), (100 + hours_dx2, 100 - hours_dy2), 5)
    draw.line(screen,(255,255,0), (100,100), (100 + minutes_dx2, 100 - minutes_dy2), 2)
    draw.line(screen,(255,0,255), (100,100), (100 + seconds_dx2, 100 - seconds_dy2), 1)

    # flip

    display.flip()

    # FPS (Frames Per Seconds)

    clock.tick(25)

quit()

Using class I can get more clocks :)

I removed clock.tick(60) to get faster clocks but it makes my CPU very hot.

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

#----------------------------------------------------------------------

class Clock(object):

    def __init__(self, hours, minutes, seconds, cx, cy, r, ticks):

        self.hours = hours
        self.minutes = minutes
        self.seconds = seconds
        self.cx = cx
        self.cy = cy
        self.r = r
        self.ticks = ticks
        self.time_to_move = 0

    def update(self, current_ticks):

        if current_ticks > self.time_to_move:
            self.time_to_move += self.ticks

            self.seconds_ang = 270 + 6 * self.seconds

            self.seconds_dx = self.cx + int(cos(radians(-self.seconds_ang))*self.r)
            self.seconds_dy = self.cy - int(sin(radians(-self.seconds_ang))*self.r)

            self.minutes_ang = 270 + 6 * (self.minutes + self.seconds/60.)

            self.minutes_dx = self.cx + int(cos(radians(-self.minutes_ang))*self.r)
            self.minutes_dy = self.cy - int(sin(radians(-self.minutes_ang))*self.r)

            self.hours_ang = 270 + 30 * (self.hours + self.minutes/60.)

            self.hours_dx = self.cx + int(cos(radians(-self.hours_ang))*self.r*.75)
            self.hours_dy = self.cy - int(sin(radians(-self.hours_ang))*self.r*.75)

            self.seconds += 1

            if self.seconds == 60:
                self.seconds = 0
                self.minutes += 1

                if self.minutes == 60:
                    self.minutes = 0
                    self.hours += 1

                    if self.hours == 12:
                        self.hours = 0      

    def draw(self, screen):
        draw.circle(screen, (255,255,255), (self.cx,self.cy), self.r, 3)
        draw.line(screen, (0,255,255), (self.cx,self.cy), (self.hours_dx, self.hours_dy), 5)
        draw.line(screen, (255,255,0), (self.cx,self.cy), (self.minutes_dx, self.minutes_dy), 2)
        draw.line(screen, (255,0,255), (self.cx,self.cy), (self.seconds_dx, self.seconds_dy), 1)

#----------------------------------------------------------------------

init()

screen = display.set_mode((800,600))

clock = time.Clock()

clock1 = Clock(5, 59, 0, 400, 300, 200, 1000)
clock2 = Clock(5, 59, 0, 100, 100, 100, 100)
clock3 = Clock(3, 9, 0, 700, 100, 100, 100)
clock4 = Clock(7, 24, 0, 100, 500, 100, 10)
clock5 = Clock(11, 30, 0, 700, 500, 100, 10)

running=True
while running:

    # events 

    for e in event.get():
        if e.type == QUIT:
            running = False

    # (variable) modifications

    clock1.update(time.get_ticks())
    clock2.update(time.get_ticks())
    clock3.update(time.get_ticks())
    clock4.update(time.get_ticks())
    clock5.update(time.get_ticks())

    # draw

    screen.fill((0,0,0))

    clock1.draw(screen)
    clock2.draw(screen)
    clock3.draw(screen)
    clock4.draw(screen)
    clock5.draw(screen)

    # flip

    display.flip()

    # FPS (Frames Per Seconds)

    #clock.tick(60)

quit()

And the same with timers (time.set_timer())

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

#----------------------------------------------------------------------

class Clock(object):

    def __init__(self, hours, minutes, seconds, cx, cy, r):

        self.hours = hours
        self.minutes = minutes
        self.seconds = seconds
        self.cx = cx
        self.cy = cy
        self.r = r

        self.hours_dx = self.cx
        self.hours_dy = self.cy - self.r*.75
        self.minutes_dx = self.cx
        self.minutes_dy = self.cy - self.r
        self.seconds_dx = self.cx
        self.seconds_dy = self.cy - self.r

    def update(self):

        self.seconds_ang = 270 + 6 * self.seconds

        self.seconds_dx = self.cx + int(cos(radians(-self.seconds_ang))*self.r)
        self.seconds_dy = self.cy - int(sin(radians(-self.seconds_ang))*self.r)

        self.minutes_ang = 270 + 6 * (self.minutes + self.seconds/60.)

        self.minutes_dx = self.cx + int(cos(radians(-self.minutes_ang))*self.r)
        self.minutes_dy = self.cy - int(sin(radians(-self.minutes_ang))*self.r)

        self.hours_ang = 270 + 30 * (self.hours + self.minutes/60.)

        self.hours_dx = self.cx + int(cos(radians(-self.hours_ang))*self.r*.75)
        self.hours_dy = self.cy - int(sin(radians(-self.hours_ang))*self.r*.75)

        self.seconds += 1

        if self.seconds == 60:
            self.seconds = 0
            self.minutes += 1

            if self.minutes == 60:
                self.minutes = 0
                self.hours += 1

                if self.hours == 12:
                    self.hours = 0      

    def draw(self, screen):
        draw.circle(screen, (255,255,255), (self.cx,self.cy), self.r, 3)
        draw.line(screen, (0,255,255), (self.cx,self.cy), (self.hours_dx, self.hours_dy), 5)
        draw.line(screen, (255,255,0), (self.cx,self.cy), (self.minutes_dx, self.minutes_dy), 2)
        draw.line(screen, (255,0,255), (self.cx,self.cy), (self.seconds_dx, self.seconds_dy), 1)

#----------------------------------------------------------------------

init()

screen = display.set_mode((800,600))

clock = time.Clock()

clock1 = Clock(5, 59, 0, 400, 300, 200)
clock2 = Clock(5, 59, 0, 100, 100, 100)
clock3 = Clock(3, 9, 0, 700, 100, 100)
clock4 = Clock(7, 24, 0, 100, 500, 100)
clock5 = Clock(11, 30, 0, 700, 500, 100)

CLOCK1 = USEREVENT+1
CLOCK2 = USEREVENT+2
CLOCK3 = USEREVENT+3
CLOCK4 = USEREVENT+4
CLOCK5 = USEREVENT+5

timer1 = time.set_timer(CLOCK1, 1000)
timer2 = time.set_timer(CLOCK2, 100)
timer3 = time.set_timer(CLOCK3, 100)
timer4 = time.set_timer(CLOCK4, 10)
timer5 = time.set_timer(CLOCK5, 10)


running=True
while running:

    # events 

    for e in event.get():
        if e.type == QUIT:
            running = False

        elif e.type == CLOCK1:
            clock1.update()
        elif e.type == CLOCK2:
            clock2.update()
        elif e.type == CLOCK3:
            clock3.update()
        elif e.type == CLOCK4:
            clock4.update()
        elif e.type == CLOCK5:
            clock5.update()

    # (variable) modifications

    # draw

    screen.fill((0,0,0))

    clock1.draw(screen)
    clock2.draw(screen)
    clock3.draw(screen)
    clock4.draw(screen)
    clock5.draw(screen)

    # flip

    display.flip()

    # FPS (Frames Per Seconds)

    clock.tick(60)

quit()