J-Trix

Recreating the famous falling bit effect from Matrix using python and curses.
The individual bit strips are separate entities, falling to the bottom and then being moved up again with a different x value. They also get a random speed between one and five deciseconds.

20 J-Trix frames


# Python 2.7.7 Code
# Jonathan Frech 7th of September, 2016
#         edited 8th of September, 2016
#         edited 9th of September, 2016

# import
import curses, random, time

# set the cursor's visibility (sometimes does not work on Mac OS)
def curs_set(bool):
	try:
		curses.curs_set(bool)
	except:
		pass

# add a string at (y, x) with color on scr without any errors
def addstr(scr, y, x, string, color = 0):
	my, mx = scr.getmaxyx()
	if y >= 0 and x >= 0 and y < my and x < mx and not (x == mx-1 and y == my-1):
		scr.addstr(y, x, string, color)

# init
def init():
	global scr, t, my, mx
	
	# screen
	scr = curses.initscr()
	scr.keypad(True)
	scr.nodelay(True)
	
	# curses
	curses.noecho()
	curses.cbreak()
	curs_set(False)
	curses.start_color()
	curses.use_default_colors()
	
	# color used
	#curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK)
	curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
	
	# screen size
	my, mx = scr.getmaxyx()
		
	# ticks
	t = 0

# run
def run():
	global scr, seed, t, my, mx
	
	# init
	init()
	
	# strips
	strips = [strip() for _ in range(0, 100)]
	
	# while loop
	while True:
		# render strips
		for s in strips:
			s.render()
			
			# new strip
			if s.out:
				strips.remove(s)
				strips.append(strip(top = True))
		
		# get char (nodelay mode!)
		c = scr.getch()
		
		# quit
		if c == curses.KEY_F12:
			break
		
		# sleep
		time.sleep(.1)
		
		# handle resizement
		if curses.is_term_resized(my, mx):
			# update screen size
			my, mx = scr.getmaxyx()
			
			# reset
			strips = [strip() for _ in range(0, 100)]
			
			# clear
			scr.clear()
				
		# one more tick
		t += 1
	
	# cleanup
	cleanup()

# cleanup
def cleanup():
	curses.echo()
	curses.nocbreak()
	curs_set(True)
	curses.endwin()

# get a random character (string with lengh one)
def char():
	#s = "+-*%/&"
	s = "01"
	return s[random.randint(0, len(s)-1)]

# strip class
class strip():
	# init
	def __init__(self, top = False):
		global scr
		
		# defin pos, length and speed
		my, mx = scr.getmaxyx()
		self.pos = [random.randint(0, my-2), random.randint(0, mx-1)]
		self.length = random.randint(3, 10)
		if top:
			self.pos[0] = -self.length
		self.speed = random.randint(1, 5)
		
		# outside screen?
		self.out = False
		
	# render
	def render(self):
		global scr
		
		# render individual chars
		for Y in range(-1, self.length):
			y, x = self.pos[0]+Y, self.pos[1]
			addstr(scr, y, x, [char(), " "][Y == -1], curses.color_pair(1))
		
		# screen size
		my, mx = scr.getmaxyx()
		
		# move down
		if t % self.speed == 0:
			self.pos[0] += 1
			if self.pos[0] > my or self.pos[1] > mx:
				self.out = True
		
		# move cursor
		scr.move(my-1, mx-1)

# run animation
run()
Advertisements

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