JClock III

Inspired by a 7-segment clock I previously made a 7-segment font (used in Jong). I thought of an idea to make this simple way of displaying our ten numerals more interesting. I came up with this clock.
It uses a number of pixels, which get every second a new destination to the position that would form needed numeral. Because they always try to move to their destination – needing time to get there –, a reordering-effect occurs.
Total Chaos Nearly Assembled Assembled


# Python 2.7.7 Code
# Pygame 1.9.1 (for Python 2.7.7)
# Jonathan Frech 8th of July, 2015

# importing needed modules
import pygame, sys, time, math, os, random, datetime

""" CLASSES """
# dummy class for global variables
class dummy():
	pass

class pixel():
	# init
	def __init__(self):
		self.pos = [-1, -1]
		self.destpos = self.pos[:]
		self.color = (0, 255, 0)
		
		self.changed = False
	
	# set the destination
	def setdest(self, _dest):
		self.destpos = _dest
		self.changed = True
	
	# tick (move to destination)
	def tick(self):
		for _ in range(0, 2):
			dif = (self.destpos[_] - self.pos[_])
			if dif < 1 / 5.:
				self.pos[_] = self.destpos[_]
			else:
				self.pos[_] += dif / 5.
		
		self.changed = False
	
	# render
	def render(self, _surface):
		_surface.set_at(intpos(self.pos), self.color)

""" FUNCTIONS """
# returns an integer version of given positon
def intpos(_pos):
	return [int(_pos[0]), int(_pos[1])]

# adds two 2D positions
def addpos(_pos1, _pos2):
	return [_pos1[0] + _pos2[0], _pos1[1] + _pos2[1]]

# quits the program
def quit():
	sys.exit()

# generates positions for individual pixels from given number
def getPositions(_num, _fix):
	# turns '7' into '07'
	num = str(_num)
	while len(num) < 2:
		num = "0" + num
	
	# variables
	points = []
	fixpoint = _fix
	
	# encoding
	for n in num:
		
		# encode 7 segments
		if n == "0":
			digits = [1, 2, 3, 4, 5, 6]
		elif n == "1":
			digits = [2, 3]
		elif n == "2":
			digits = [1, 2, 4, 5, 7]
		elif n == "3":
			digits = [1, 2, 3, 4, 7]
		elif n == "4":
			digits = [2, 3, 6, 7]
		elif n == "5":
			digits = [1, 3, 4, 6, 7]
		elif n == "6":
			digits = [1, 3, 4, 5, 6, 7]
		elif n == "7":
			digits = [1, 2, 3]
		elif n == "8":
			digits = [1, 2, 3, 4, 5, 6, 7]
		elif n == "9":
			digits = [1, 2, 3, 4, 6, 7]
		
		# encode digits
		for d in digits:
			if d == 1:
				for x in range(0, 6):
					for y in range(0, 3):
						points.append(addpos(fixpoint, [x+3, y]))
			elif d == 7:
				for x in range(0, 6):
					for y in range(0, 3):
						points.append(addpos(fixpoint, [x+3, y+3+6]))
			elif d == 4:
				for x in range(0, 6):
					for y in range(0, 3):
						points.append(addpos(fixpoint, [x+3, y+3+6+3+6]))
			
			
			
			elif d == 6:
				for x in range(0, 3):
					for y in range(0, 6):
						points.append(addpos(fixpoint, [x, y+3]))
			elif d == 5:
				for x in range(0, 3):
					for y in range(0, 6):
						points.append(addpos(fixpoint, [x, y+3+6+3]))
			elif d == 2:
				for x in range(0, 3):
					for y in range(0, 6):
						points.append(addpos(fixpoint, [x+3+6, y+3]))
			elif d == 3:
				for x in range(0, 3):
					for y in range(0, 6):
						points.append(addpos(fixpoint, [x+3+6, y+3+6+3]))
		
		# shift to the right
		fixpoint[0] += 12 + 3
	
	# return
	return points

""" TICK; RENDER """
# tick function
def tick():
	# handle events
	for event in pygame.event.get():
		# quit
		if event.type == pygame.QUIT:
				quit()
		
		# keyup
		if event.type == pygame.KEYUP:
			# handle 'main.KEYSDOWN'
			if event.key in main.KEYSDOWN:
				main.KEYSDOWN.remove(event.key)
		
		# keydown
		if event.type == pygame.KEYDOWN:
			# handle 'main.KEYSDOWN'
			if event.key not in main.KEYSDOWN:
				main.KEYSDOWN.append(event.key)
	
	# get times
	now = datetime.datetime.now()
	sec = now.second
	min = now.minute
	hou = now.hour
	
	# if time changed, update every pixel
	if main.HOU != hou or main.MIN != min or main.SEC != sec:
		POINTS = []
		P1 = getPositions(hou, [3, 3])
		P2 = getPositions(min, [3 + 27 + 10, 3])
		P3 = getPositions(sec, [3 + 27 + 10 + 27 + 10, 3])
		
		for _ in P1:
			POINTS.append(_)
		for _ in P2:
			POINTS.append(_)
		for _ in P3:
			POINTS.append(_)
		
		for _ in main.PIXELS:
			if not _.changed:
				if len(POINTS) > 0:
					n = random.randint(0, len(POINTS) - 1)
					_.setdest(POINTS[n])
					POINTS.remove(POINTS[n])
				else:
					_.setdest([-1, -1])
	
	# save last time 
	main.SEC = sec
	main.MIN = min
	main.HOU = hou
	
	# tick pixels
	for _ in main.PIXELS:
		_.tick()

# render function
def render():
	# fill
	main.SURF.fill(main.COLOR)
	
	# render pixels
	for _ in main.PIXELS:
		_.render(main.SURF)
	
	# scale, blit and flip
	main.SCREEN.blit(
		pygame.transform.scale(main.SURF, main.SSIZE),
		[0, 0]
	)
	pygame.display.flip()

""" INIT """
# initialize program
def init():
	main.WIDTH, main.HEIGHT = 3 + (3*(27 + 10)) - 10 + 3, 3 + 21 + 3
	main.SIZE = [main.WIDTH, main.HEIGHT]
	main.SURF = pygame.Surface(main.SIZE)
	
	main.SCALE = 10
	main.SWIDTH, main.SHEIGHT = main.WIDTH * main.SCALE, main.HEIGHT * main.SCALE
	main.SSIZE = [main.SWIDTH, main.SHEIGHT]
	main.SCREEN = pygame.display.set_mode(main.SSIZE)
	
	main.CAPTION = "JClock II"
	main.COLOR = (0, 0, 0)
	main.TICKS = 0
	main.KEYSDOWN = []
	
	# init pixels
	main.PIXELS = []
	for _ in range(0, 756):
		main.PIXELS.append(pixel())
	
	# time variables
	main.SEC = -1
	main.MIN = -1
	main.HOU = -1
	
	# functions
	pygame.display.set_caption(main.CAPTION)

""" RUN """
# run function (uses tick() and render())
def run():
	ticksPerSecond = 60
	lastTime = time.time() * 1000000000
	nsPerTick =  1000000000.0 / float(ticksPerSecond)
	
	ticks = 0
	frames = 0
	
	lastTimer = time.time() * 1000
	delta = 0.0
	
	while True:
		now = time.time() * 1000000000
		delta += float(now - lastTime) / float(nsPerTick)
		lastTime = now
		shouldRender = False
				
		while delta >= 1:
			ticks += 1
			main.TICKS += 1
			tick()
			delta -= 1
			shouldRender = True
		
		if shouldRender:
			frames += 1
			render()
		
		if time.time() * 1000 - lastTimer >= 1000:
			lastTimer += 1000
			
			# debug
			# print("Frames: " + str(frames) + ", ticks: " + str(ticks))
			
			frames = 0
			ticks = 0

# main variable
main = dummy()
init()

# start program
run()
Advertisements

One thought on “JClock III

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s