Currently, I know only one way to show strings using ncurses library, like as below:
import curses
stdscr = curses.initscr()
stdscr.addch(0,0,'x')
stdscr.getch()
But I've met a problem when I want to make a falling function of string.
import curses
import time
stdscr = curses.initscr()
y=1
def fall():
global y
stdscr.addstr(y,0,'x')
stdscr.move(y-1,0)
stdscr.clrtoeol()
y += 1
stdscr.getch()
while True:
time.sleep(0.2)
fall()
If I remove this getch()
function, I can't see the ncurses screen. But if I put it in. I have to touch some key on my keyboard then the string could fall.
Is there a way I can make the string automatically falling without hit keyboard or mouse?
You have to explicitly update the screen, either by calling the refresh()
method on the window (stdscr
in your example) or by calling curses.doupdate()
.
This is due to the fact that curses
was written years ago, when terminal where pretty slow and it was really important to make modifications efficiently. With an explicit update you can first change the screen how you want and then update it in a single operation, instead of doing an update for every single operation.
Refresh at the point you wants to reflect changes on your screen.
I am not rectifying but modifying my draw square code in previous answer, below my own code using curses library(added comments so that it can be helpful for someone new):
from curses import *
import random, time
def main(stdscr):
start_color() # call after initscr(), to use color, not needed with wrapper
stdscr.clear() # clear above line.
stdscr.addstr(1, 3, "Fig: RAINING", A_UNDERLINE|A_BOLD)
# init some color pairs:
init_pair(10, COLOR_WHITE, COLOR_WHITE) # BG color
init_pair(1, COLOR_RED, COLOR_WHITE)
init_pair(2, COLOR_BLUE, COLOR_WHITE)
init_pair(3, COLOR_YELLOW, COLOR_WHITE)
init_pair(4, COLOR_MAGENTA, COLOR_WHITE)
init_pair(5, COLOR_CYAN, COLOR_WHITE)
# First draw a white square as 'background'
bg = ' ' # background is blank
for x in range(3, 3 + 75): # horizontal c: x-axis
for y in range(4, 4 + 20): # vertical r: y-axis
stdscr.addstr(y, x, bg, color_pair(10))
stdscr.refresh() # refresh screen to reflect
stdscr.addstr(28, 0, 'Press Key to exit: ')
# Raining
drop = '#' # drop is #
while True: # runs infinitely
xl = random.sample(range(3, 3+75), 25) # generate 25 random x-positions
for y in range(5, 4 + 20): # vertical
for x in xl:
stdscr.addstr(y-1, x, bg, color_pair(10)) #clear drops @previous row
stdscr.addstr(y, x, drop, color_pair(random.randint(1, 5)))
stdscr.refresh() # refresh each time, # ^^ add drops at next row
time.sleep(0.5) #sleep for moving..
for x in xl: # clear last row, make blank
stdscr.addstr(23, x, ' ', color_pair(10))
stdscr.getkey() # it doesn't work in this code
wrapper(main) #Initialize curses and call another callable object, func,
Snap-sort of one iteration:
two iterations: http://s1.postimg.org/ehnvucp1p/rain.gif