python curses tty screen blink - python

I'm writing a python curses game (https://github.com/pankshok/xoinvader).
I found a problem: in terminal emulator it works fine, but in tty screen blinks.
I tried to use curses.flash(), but it got even worse.
for example, screen field:
self.screen = curses.newwin(80, 24, 0, 0)
Main loop:
def loop(self):
while True:
self.events()
self.update()
self.render()
render: (https://github.com/pankshok/xoinvader/blob/master/xoi.py#L175)
self.screen.clear()
#draw some characters
self.screen.refresh()
time.sleep(0.03)
Constant time in sleep function is temporary, until I write 60 render calls controller.
How to implement render method correctly?
Thanks in advance,
Paul.

Don't call clear to clear the screen, use erase instead. Using clear sets a flag so that when you call refresh the first thing it does is clear the screen of the terminal. This is what is causing the terminal's screen to appear to blink. The user sees the old screen, then a completely blank screen, then your new screen. If you use erase then it will instead modify the old screen to look like the new one.
You may still see some odd flashing or other artifacts on slow terminals. Try calling screen.idcok(False) and screen.idlok(False) to stop curses from using insert and deletion operations to update the screen.

Related

Python (Turtle) reports error when application window is exited

I've been testing the turtle library for about 3 days now. One recurring 'issue' that I've been getting is the traceback error whenever I exit my application window. The terminal displays rows of details regarding the turtle update function and it ends with:
_tkinter.TclError: can't invoke "update" command: application has been destroyed
Here's my code:
import turtle
wn = turtle.Screen()
wn.title("Game Window")
wn.bgcolor("black")
wn.setup(width=1000, height=650)
wn.tracer(0)
run = True
while run:
wn.update()
I've been trying to wrap my head around the traceback report. I'm assuming it happens because the application continuously updates the window (as you can see in the while run block). So, there is a possibility that, once I exit the window, the application is already processing the wn.update() function, and it returns an error because it did not finish its operation. If that is the case, then what should I do about the update function? If not then, please, explain to me the issue and solution. Thank you!
The problem is your loop:
while run:
wn.update()
This is the wrong way to approach Python turtle programming. I see this loop often in SO questions so there must be a book ("Programming Python Turtle by Bad Example") or tutorial somewhere teaching people the wrong way to approach turtle.
Generally, I'd suggest you avoid tracer() and update() until your program is basically working and you now need to optimize its performance. If you do use tracer(), then you should only call update() when you are finished making changes and you want the user to see the current display. Something like:
from turtle import Screen, Turtle
screen = Screen()
screen.setup(width=1000, height=650)
screen.title("Game Window")
screen.tracer(0)
turtle = Turtle()
radius = 1
while radius < 300:
turtle.circle(radius, extent=1)
radius += 0.25
screen.update() # force above to be seen
screen.mainloop()
A key point to note is that our program ends with a mainloop() call which passes control onto Tk(inter)'s event loop. That's the same event loop that receives the window close event and closes down turtle cleanly.

Pygame text not updating

The following code is being looped - is in a loop - but when 'inputStr' changes, the display does not. Printing inputStr yields the expected results, though.
defFnt = pygame.font.Font("CP437.ttf", 72)
txtToRndr = defFnt.render(inputStr,False, (0,0,0))
disp.blit(txtToRndr, (100,300))
Download link; http://www.mediafire.com/download/a4hp9wgojxgiao9/functGroup.rar
If you print inputStr right before its rendered it prints for a bit then stops, meaning it isnt getting rendered after a certain point, Which i think is because this condition:
if (16-len(Gnots))>0:
it must be coming out false therefore the code to render the new text isnt being executed:
if you print Gnots after the condition, it prints it until its length is 16 items than stops
change the number 16 in the condition to say 1000 as a test than try typing and the text changes
Your code needs refactoring. As the other answer says, the main problem is that if-block (try changing it to if True:.
I would recommend capping the framerate but drawing every frame unconditionally, as this is simpler and more robust. You're also not clearing the screen each frame, and PyGame has nice key tokens (e.g. pygame.K_ESCAPE) which you should use instead of numbers. You're also loading the font each time you draw; you only need to do so once, at the top of your program.
Here's my PyGame basecode, which shows some of these best practices. In the draw() function, you'd add your fill call to clear the screen, and then all of your rendering code.
I can suggest the following after encountering similar issue.
Try updating the screen with your text by adding following line after your code:
pygame.display.update()
The issue of text not updating on screen was coming in my case as I was trying to take input from terminal and then updating in on pygame screen.

Python using turtle button

I am attempting for a homework assignment to implement Simon Says in python. I'm trying to do it using the turtle library (a requirement).
However, I've run into a stumbling block in that while I can get the screen to register click events (currently just printing the x,y coordinates) I can't get it to wait for a click event.
Specifically what I'm planning on doing is having areas on the screen that when they click within that location it is considered as if they had clicked a button. Screen clears and game does whatever.
However, in experiments in trying to get a working 'button' all that it does is set it so it prints the x,y coordinates but the rest of the program finishes. Didn't wait for the user to click anything. I tried a blocking method of...
while clicked == False:
pass
or
while clicked == False:
time.sleep(1)
but both methods hangs the program until I manually interrupt and then it'll print the clicks.
Am I missing an option somewhere?
Turtles don´t have buttons, but they do have callbacks for clicks.
Furthermore, you should use onclick for Screen to detect general clicks and onclick for turtle to detect clicking in turtles. You can, for example, make a 4 BIG turtles with different colors by using a dynamic shape.
Also, turtle is based on Tk, so you must be aware of things like mainloop()
The following program give some hints for Python 2.7.5.
import turtle as t
from random import randint
class MyTurtle(t.Turtle) :
def __init__(self,**args) :
t.Turtle.__init__(self,**args)
def mygoto(self,x,y) :
t1.goto(x,y)
print x,y
def randonics(self,x,y) :
self.left(randint(90,270))
def minegoto(x,y) :
print x,y
t1.goto(x,y)
wt=t.Screen()
t1=MyTurtle()
wt.register_shape("big",((0,0),(30,0),(30,30),(0,30)))
t1.shape("big")
wt.onclick(t1.mygoto,btn=1)
wt.onclick(minegoto,btn=2)
t1.onclick(t1.randonics,btn=3)
t1.goto(100,100)
t.mainloop()
So after extensive search there isn't necessarily a way pause execution of the code in python while using turtle to wait for some click event. Maybe in Tk I could do that but not in turtle.
However, there is a way to get around that. As an example. A method sets up the fake button on the screen, sets the click event, and terminates. The click event when clicked calls the next method needed for execution. So until the button is clicked the actual code isn't doing anything but remains in memory for use.
So more specifically.
1. Create a 'button'.
2. Have your program behave normally until it needs to wait for a click event.
3. Set up the on screen click (or on turtle) in such a way when the 'button' is clicked the next part of the code is run.
Special note. The code in question can't depend on waiting for a click event for later on in code. Instead, the click causes the next part of the execution of your code.
You can make the function registered with onclick() test the x,y position. If it is inside some region you do whatever you must.
I don´t see the difference between what you want to do and what this code does, the modification of turtle position is just an example, you can do anything when a click is captured by onclick(), even start a thread if you really need it (using Creating Threads in python)
import turtle as t
from random import randint
from threading import Thread
from time import sleep
def threaded_function(arg,t1):
for i in range(arg):
print "running",i
sleep(1)
t1.forward(i*10)
def minegoto(x,y) :
print x,y
t1.goto(x,y)
thread = Thread(target = threaded_function, args = (10,t1 ))
thread.start()
thread.join()
print "thread finished...exiting"
wt=t.Screen()
t1=t.Turtle()
wt.register_shape("big",((0,0),(30,0),(30,30),(0,30)))
t1.shape("big")
wt.onclick(minegoto,btn=1)
t1.goto(100,100)
t.mainloop()

Pygame screen crashes without error report

I have two files, one to generate a world, and another to run the main code. However, the main screen keeps crashing for no reason. I think the world gen may also be broken, but it does at least pass on valid data to the main code.
# Main loop.
while RUNNING:
# Fill the screen.
screen.fill((0,0,0))
# Event handling.
for eventa in event.get():
if eventa.type == QUIT:
RUNNING = f
screen.fill(SCREENCOLOR)
# Draw the world.
for tile in WORLD:
if tile.surface == None:
pass
else:
screen.blit(tile.surface,tile.location)
# Draw the character
screen.blit(PLAYER["image"],PLAYER["loc"])
# Pygame commands clear up.
clock.tick(FPS)
screen.flip()
This code doesn't even fill the screen with white. This may just be too much data to handle, sorry if it is.
World generator
Main code
Previous question
I'm fairly sure that you aren't inserting too many things onto the screen. I believe that the problem is far more simple. You have said screen.flip() However, a surface object has no attribute called flip. You must be confused with the function pygame.display.flip() If you use this instead, the game shall display its visual output.

Ncurses, python, and OSX Lion

I'm new to nurses, and trying it out on my OSX Lion with some python code. I've ran across a weird bug, and I don't know what I'm doing wrong. I've Googled extensively, and can't find a similar issue, even in linux. I've selectively removed lines to see if one of them is an issue, also. When I run the code below, I get nothing. No menu, and my terminal is messed up, if I hit enter, you see what I get in the picture below. I have to type a reset to make it work well again. Can anyone give me suggestions, or point me in the direction where to look? I would really appreciate it. Thanks.
Script:
import curses
screen = curses.initscr() # Init curses
curses.noecho() # Suppress key output to screen
curses.curs_set(0) # remove cursor from screen
screen.keypad(1) # set mode when capturing keypresses
top_pos = 12
left_pos = 12
screen.addstr(top_pos, left_pos, "This is a String")
Result:
BTW, I'm using the default python and libs in Lion, no macports. I'd like to use the native libraries, if possible.
You have 2 problems.
After adding the string to the screen with addstr you don't tell it to refresh the screen. Add this after the call to addstr:
screen.refresh()
You need to call endwin() at the end of you program to reset the terminal. Add this to the end of your program:
curses.endwin()
That said, after making those 2 changes when you run your program it will appear to do nothing because after displaying the string on the screen curses exits and returns the screen to the state before you ran the program.
Add this before the call to endwin():
screen.getch()
Then it will wait for you press a key before exiting.

Categories

Resources