I found this input box module on the internet but it only allows lower case no upper. So could someone tell me what to change in the module to allow caps as im creating a small multiplayer game and i need login system and chatbox.
Here is the code example I am working with
# by Timothy Downs, inputbox written for my map editor
# This program needs a little cleaning up
# It ignores the shift key
# And, for reasons of my own, this program converts "-" to "_"
# A program to get user input, allowing backspace etc
# shown in a box in the middle of the screen
# Called by:
# import inputbox
# answer = inputbox.ask(screen, "Your name")
#
# Only near the center of the screen is blitted to
import pygame, pygame.font, pygame.event, pygame.draw, string
from pygame.locals import *
def get_key():
while 1:
event = pygame.event.poll()
if event.type == KEYDOWN:
return event.key
else:
pass
def display_box(screen, message):
"Print a message in a box in the middle of the screen"
fontobject = pygame.font.Font(None,18)
pygame.draw.rect(screen, (0,0,0),
((screen.get_width() / 2) - 100,
(screen.get_height() / 2) - 10,
200,20), 0)
pygame.draw.rect(screen, (255,255,255),
((screen.get_width() / 2) - 102,
(screen.get_height() / 2) - 12,
204,24), 1)
if len(message) != 0:
screen.blit(fontobject.render(message, 1, (255,255,255)),
((screen.get_width() / 2) - 100, (screen.get_height() / 2) - 10))
pygame.display.flip()
def ask(screen, question):
"ask(screen, question) -> answer"
pygame.font.init()
current_string = []
display_box(screen, question + ": " + string.join(current_string,""))
while 1:
inkey = get_key()
if inkey == K_BACKSPACE:
current_string = current_string[0:-1]
elif inkey == K_RETURN:
break
elif inkey == K_MINUS:
current_string.append("_")
elif inkey <= 127:
current_string.append(chr(inkey))
display_box(screen, question + ": " + string.join(current_string,""))
return string.join(current_string,"")
def main():
screen = pygame.display.set_mode((320,240))
print ask(screen, "Name") + " was entered"
if __name__ == '__main__': main()
Thx!
If you change the corresponding code to:
elif inkey <= 127:
if pygame.key.get_mods() & KMOD_SHIFT or pygame.key.get_mods() & KMOD_CAPS: # if shift is pressed or caps is on
current_string.append(chr(inkey).upper()) # make string uppercase
else:
current_string.append(chr(inkey)) # else input is lower
That should work.
If you want more info on keyboard modifier states look here
Related
I have made a game HANGMAN. I want to restart the game with user input if they want to. I have many fuctions so while loops would not work. I have to keep the record of the score also. I have also variables which need to be reset. Like this one.
word = random.choice(words.final_words).upper()
It choose a word from a huge list of words. That list is in another file named words.py.
hangman_status = 6
This tells at which stage the hangman is. It need to be reset to 0.
There are many variables like this.
This is the whole code if you are intersted to see.
import pygame, math, random, words
# setup display
pygame.init()
WIDTH, HEIGHT = 800, 500
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Hangman')
# load images
images = []
for i in range(7):
image = pygame.image.load(r'C:\Users\hp\Pygame\Hangman\hangman' + str(i) + '.png')
images.append(image)
# colours
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# game variables
hangman_status = 0
word = random.choice(words.final_words).upper()
guessed = []
# fonts
LETTER_FONT = pygame.font.Font(r'C:\Users\hp\AppData\Local\Microsoft\Windows\Fonts\Azonix.otf', 30)
WORD_FONT = pygame.font.Font(r'C:\Users\hp\AppData\Local\Microsoft\Windows\Fonts\Azonix.otf', 35)
RESULT_FONT = pygame.font.Font(r'C:\Users\hp\AppData\Local\Microsoft\Windows\Fonts\Azonix.otf', 45)
# button variables
RADIUS = 20
GAP = 15
let_pos = []
startx = round((WIDTH - (GAP + RADIUS * 2) * 13) / 2)
starty = 380
A = 65
for i in range(26):
x = startx + GAP * 2 + ((RADIUS * 2 + GAP) * (i % 13))
y = starty + ((i // 13) * (GAP + RADIUS * 2))
let_pos.append([x, y, chr(A + i), True])
# setup game loop
FPS = 60
clock = pygame.time.Clock()
run = True
# draw
def draw():
win.fill(WHITE)
text = RESULT_FONT.render('Hangman', 1, BLACK)
win.blit(text, (int(WIDTH/2) - int(text.get_width()/2), 20))
# draw word
display_word = ""
for letter in word:
if letter in guessed:
display_word += letter + ' '
else:
display_word += '_ '
text = WORD_FONT.render(display_word, 1, BLACK)
win.blit(text, (340, 200))
# draw buttons
for letter in let_pos:
x, y, ltr, visible = letter
if visible:
pygame.draw.circle(win, BLACK, (x, y), RADIUS, 2)
text = LETTER_FONT.render(ltr, 1, BLACK)
win.blit(text, (x - int(text.get_width()/2), y - int(text.get_height()/2)))
win.blit(images[hangman_status], (100, 80))
pygame.display.update()
# display word
def last_word():
win.fill(BLACK)
text = RESULT_FONT.render(f'The word was: {word}', 1, WHITE)
win.blit(text, (int(WIDTH/2 - int(text.get_width()/2)), int(HEIGHT/2) - int(text.get_height()/2)))
pygame.display.update()
# result
def display_message(message):
win.fill(BLACK)
text = RESULT_FONT.render(message, 5, WHITE)
win.blit(text, (int(WIDTH/2) - int(text.get_width()/2), int(HEIGHT/2) - int(text.get_height()/2)))
pygame.display.update()
pygame.time.delay(3000)
# game loop
while run:
clock.tick(FPS)
draw()
# events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
m_x, m_y = pygame.mouse.get_pos()
for letter in let_pos:
x, y, ltr, visible = letter
if visible:
dis = math.sqrt((m_x- x)**2 + (m_y - y)**2)
if dis <= RADIUS:
letter[3] = False
guessed.append(ltr)
if ltr not in word:
hangman_status += 1
won = True
for letter in word:
if letter not in guessed:
won = False
# check if the player lost won
if won:
last_word()
pygame.time.delay(2000)
display_message('You WON!')
break
# check if the player lost
if hangman_status == 6:
pygame.time.delay(1000)
last_word()
pygame.time.delay(4000)
display_message('You Lost.')
break
pygame.quit()
print(' '.join(word.split(' ')).title())
Why don't you make your entire game/round run inside a function?
You could pass in whatever arguments you need to.
eg:
def game_round():
# Preset initial vars if not passing to func:
total_score = 0
while run:
# Have run_game return score and a bool indicating user wants to restart/not.
round_score, restart = run_game()
if restart:
total_score = 0
# Whatever variables you want to reset, do this here too
else:
total_score += round_score
I'm fairly new to coding (like 3 weeks in) and I've been trying to make a turn-based RPG battle system using pygame. I've encountered a problem involving pygame's key.get_pressed. I'm making a dropdown menu thing where if you press ENTER, a smaller black box should appear and when you press ENTER again, the box should disappear. Unfortunately, the black box appears but disappears almost immediately. I used the print function as a debug to find the error and it seems that the program registers the second ENTER press (the one that should close the box) without it ever being pressed. Any help would be greatly appreciated. I am also using windows 10 and python 3.6
import pygame
pygame.init()
win = pygame.display.set_mode((820,567))
pygame.display.set_caption('Basic battle')
drop_menu_attack = pygame.image.load('drop menu attack.png')
health_pp = pygame.image.load('hp and pp.png')
menu_img = pygame.image.load('menu.png')
attack_img = pygame.image.load('attack.png')
defend_img = pygame.image.load('defend.png')
bag_img = pygame.image.load('bag.png')
background_img = pygame.image.load('rpg background.gif')
Snake_enemy_img = pygame.image.load('pixil-frame-0.png')
clock = pygame.time.Clock()
class player(object):
def __init__ (self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.cursor_state = 1
self.attack_x = 100
self.defend_x = 325
self.bag_x = 575
self.top_menu_y = 70
class drop_menu(object):
def __init__ (self, x, y):
self.x = x
self.y = y
self.drop_menu_state = False
def cursor_position():
if c_p.cursor_state == 1:
print ('it should be on attack')
c_p.x = c_p.attack_x
c_p.y = c_p.top_menu_y
elif c_p.cursor_state == 2:
print ('it hould be on defend')
c_p.x = c_p.defend_x
c_p.y = c_p.top_menu_y
elif c_p.cursor_state == 3:
print ('it should be on bag')
c_p.x = c_p.bag_x
c_p.y = c_p.top_menu_y
elif c_p.cursor_state > 3:
c_p.cursor_state = 3
print ('it should be on bag')
c_p.x = c_p.bag_x
c_p.y = c_p.top_menu_y
elif c_p.cursor_state < 1:
c_p.cursor_state = 1
print ('it should be on attack')
c_p.x = c_p.attack_x
c_p.y = c_p.top_menu_y
def select():
if c_p.cursor_state == 1:
d_m.drop_menu_state = True
print (d_m.y)
while d_m.drop_menu_state:
pygame.time.delay(150)
win.blit (drop_menu_attack, (d_m.x, d_m.y))
pygame.display.update()
print ('dooooog')
keys = pygame.key.get_pressed()
if d_m.drop_menu_state == True:
if keys[pygame.K_RETURN]:
d_m.drop_menu_state = False
print('SSSSSS')
pygame.event.pump()
def redraw_gamewindow():
win.blit (background_img, (0,0))
win.blit (Snake_enemy_img, (300, 174))
win.blit (menu_img, (25, 425 ))
win.blit (menu_img, (25, 10))
win.blit (health_pp, (70, 450))
win.blit (attack_img, (c_p.attack_x + 30, c_p.top_menu_y - 15))
win.blit (defend_img, (c_p.defend_x + 30, c_p.top_menu_y - 15))
win.blit (bag_img, (c_p.bag_x + 30, c_p.top_menu_y - 15))
pygame.draw.rect(win, (255, 255, 255), (c_p.x, c_p.y, 7 , 7))
pygame.display.update()
d_m = drop_menu(25, 125)
print (d_m.x)
c_p = player(100, 70, 7,7)
run = True
while run:
clock.tick(27)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
c_p.cursor_state = c_p.cursor_state + 1
cursor_position()
pygame.time.delay(150)
if keys[pygame.K_LEFT]:
c_p.cursor_state = c_p.cursor_state -1
cursor_position()
pygame.time.delay(150)
if keys[pygame.K_RETURN]:
select()
pygame.time.delay(500)
redraw_gamewindow()
So what's happening is that you're holding the ENTER button. In the while loop, when you press enter, it calls the select() function, which then detects the ENTER that is still being pressed. Let me draw a visual-ish:
ENTER is pressed -> select() is called, drop_menu_state turns True -> select() detects ENTER still being pressed -> drop_menu_state turns false
You may be asking, how does it detect? Well the frames are running at a wanted 27 frames per second. So it will change the state of drop menu state every 1/27 of a second while the ENTER key is being pressed. If you are able to press and release the ENTER key for less than 1/27 of a second, it will work properly.
There are 3 solutions. Either bind the closing of the menu to another key, add a short timer, or use an event loop. My style of programming would be to add a timer.
import time
pre_time = time.time()
def select():
... # code in select()
if d_m.drop_menu_state and pre_time + 5 > time.time() and keys[pygame.K_RETURN]:
pre_time = time.time()
d_m.drop_menu_state = False
I simplified your code a bit (no == True) What the pre_time + 5 > time.time() is saying is has it been five seconds since the last time pre_time has been defined as the current time.
I hope this helps!
I've written a simple RPG battle system. I want whatever is being printed to appear in a black text box on a pygame window. I've done that and written a function called TEXT(X) to display text on 3 different lines, but dispite me calling it after every print command it only runs once and displays only the first message.
If you run the program and compare it to the command prompt you'll know what I mean.
from pygame import *
from userInterface import Title, Dead
WIN_WIDTH = 640
WIN_HEIGHT = 400
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
init()
screen = display.set_mode(DISPLAY, FLAGS, DEPTH)
saveState = False
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (30, 30, 30)
FONT = font.SysFont("Courier New", 15)
heroHP = 1000
hero={'name' : 'Hero',
'height':4,
'lvl': 1,
'xp' : 0,
'reward' : 0,
'lvlNext':25,
'stats': {'str' : 12, # strength
'dex' : 4, # dexterity
'int' : 15, # intelligence
'hp' : heroHP, # health
'atk' : [250,350]}} # range of attack values
boss1={'name' : 'Imp',
'xp' : 0,
'lvlNext':25,
'reward' : 25,
'stats': {'hp' :400,
'atk' : [300,350]}}
ONE = None
TWO = None
THREE = None
def TEXT(X):
global ONE, TWO, THREE
if ONE == None:
ONE = X
elif ONE == X and TWO == None:
TWO = X
elif ONE and TWO and THREE == None:
THREE = X
elif ONE and TWO and THREE:
ONE = None
TWO = None
THREE = None
def level(char): # level up system
#nStr, nDex, nInt=0,0,0
while char['xp'] >= char['lvlNext']:
char['lvl']+=1
char['xp']=char['xp'] - char['lvlNext']
char['lvlNext'] = round(char['lvlNext']*1.5)
nStr=0.5*char['stats']['str']+1
nDex=0.5*char['stats']['dex']+1
nInt=0.5*char['stats']['int']+1
print(f'{char["name"]} levelled up to level {char["lvl"]}!') # current level
TEXT(f'{char["name"]} levelled up to level {char["lvl"]}!') # current level
print(f'( INT {round((char["stats"]["int"] + nInt))} - STR {round(char["stats"]["str"] + nStr)} - DEX {round(char["stats"]["dex"] + nDex)} )') # print new stats
TEXT(f'( INT {round((char["stats"]["int"] + nInt))} - STR {round(char["stats"]["str"] + nStr)} - DEX {round(char["stats"]["dex"] + nDex)} )') # print new statsm
char['stats']['str'] += nStr
char['stats']['dex'] += nDex
char['stats']['int'] += nInt
from random import randint
def takeDmg(attacker, defender): # damage alorithm
dmg = randint(attacker['stats']['atk'][0], attacker['stats']['atk'][1])
defender['stats']['hp'] = defender['stats']['hp'] - dmg
print(f'{defender["name"]} takes {dmg} damage!')
TEXT(f'{defender["name"]} takes {dmg} damage!')
if defender['stats']['hp'] <= 0:
print(f'{defender["name"]} has been slain...')
TEXT(f'{defender["name"]} has been slain...')
attacker['xp'] += defender['reward']
level(attacker)
if defender==hero:
#Dead()
input("Press ENTER to exit")
else:
hero['stats']['hp']=heroHP
#Title()
input("Press ENTER to exit")
def Battle(player, enemy):
global ONE, TWO, THREE
mouse.set_visible(1)
clock = time.Clock()
YES = Rect(100, 100, 50, 50)
NO = Rect(500, 100, 50, 50)
Text = Rect(70, 300, 500, 60)
#while ((enemy['stats']['hp']) > 0):
while True:
for e in event.get():
if e.type == QUIT:
exit("Quit") # if X is pressed, exit program
elif e.type == KEYDOWN:
if e.key == K_ESCAPE:
exit()
elif e.type == MOUSEBUTTONDOWN:
# 1 is the left mouse button, 2 is middle, 3 is right.
if e.button == 1:
# `event.pos` is the mouse position.
if YES.collidepoint(e.pos):
takeDmg(player, enemy)
print(f'{enemy["name"]} takes the opportunity to attack!')
TEXT(f'{enemy["name"]} takes the opportunity to attack!')
takeDmg(enemy, player)
elif NO.collidepoint(e.pos):
print(f'{enemy["name"]} takes the opportunity to attack!')
TEXT(f'{enemy["name"]} takes the opportunity to attack!')
takeDmg(enemy, player)
screen.fill(WHITE)
draw.rect(screen, BLACK, YES)
draw.rect(screen, BLACK, NO)
draw.rect(screen, GRAY, Text)
YES_surf = FONT.render(("YES"), True, WHITE)
NO_surf = FONT.render(("NO"), True, WHITE)
Text1_surf = FONT.render(ONE, True, WHITE)
Text2_surf = FONT.render(TWO, True, WHITE)
Text3_surf = FONT.render(THREE, True, WHITE)
screen.blit(YES_surf, YES)
screen.blit(NO_surf, NO)
screen.blit(Text1_surf, (80, 305))
screen.blit(Text2_surf, (80, 320))
screen.blit(Text3_surf, (80, 335))
display.update()
clock.tick(60)
Battle(hero, boss1)
A small change made it work for me:
def TEXT(X):
global ONE, TWO, THREE;
if ONE == None:
ONE = X
elif ONE and TWO == None: # "ONE == X" changed to "ONE"
TWO = X
elif ONE and TWO and THREE == None:
THREE = X
elif ONE and TWO and THREE:
ONE = None
TWO = None
THREE = None
I guess you can't compare strings with ==. You could probably compare them with somethin like "equals". I know that in Java == operator would compare addresses, that may not be the same when having two "equal" strings.
Edit: But even if that's true, the second call of "TEXT" would need to get the same parameter value to work with your code... You are comparing ONE to X.
TEXT("A");
TEXT("B");
wont work then.
I tested (your code) again with:
TEXT("A");
TEXT("A");
TEXT("C");
And it works.
Hello I'm new to python and I'm trying to make a simple counter as a delay to blit some text in pygame so it does not show up instantly.
What I want to do is make text appear in a box when the player levels up.
def TEXT(A, B, C):
global ONE, TWO, THREE, FOUR
counter = 0
text = True
if text:
if counter == 10:
ONE = A
if counter == 20:
TWO = B
elif counter == 30:
THREE = C
elif counter == 40:
ONE = None
TWO = None
THREE = None
text = False
counter += 1
The code as a whole seems to be working fine but I just can't get the counter to work.
Here's the full program as reference:
from pygame import *
from userInterface import Title, Dead
WIN_WIDTH = 640
WIN_HEIGHT = 400
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
init()
screen = display.set_mode(DISPLAY, FLAGS, DEPTH)
saveState = False
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (30, 30, 30)
FONT = font.SysFont("Courier New", 15)
heroHP = 1000
hero={'name' : 'Hero',
'height':4,
'lvl': 1,
'xp' : 0,
'reward' : 0,
'lvlNext':25,
'stats': {'str' : 12, # strength
'dex' : 4, # dexterity
'int' : 15, # intelligence
'hp' : heroHP, # health
'atk' : [250,350]}} # range of attack values
boss1={'name' : 'Imp',
'xp' : 0,
'lvlNext':25,
'reward' : 25,
'stats': {'hp' :400,
'atk' : [300,350]}}
ONE = None
TWO = None
THREE = None
FOUR = None
def TEXT(A, B, C):
global ONE, TWO, THREE, FOUR
counter = 0
text = True
if text:
if counter == 0:
ONE = A
if counter == 10:
TWO = B
elif counter == 20:
THREE = C
elif counter == 30:
ONE = None
TWO = None
THREE = None
text = False
counter += 1
def level(char): # level up system
#nStr, nDex, nInt=0,0,0
while char['xp'] >= char['lvlNext']:
char['lvl']+=1
char['xp']=char['xp'] - char['lvlNext']
char['lvlNext'] = round(char['lvlNext']*1.5)
nStr=0.5*char['stats']['str']+1
nDex=0.5*char['stats']['dex']+1
nInt=0.5*char['stats']['int']+1
print(f'{char["name"]} levelled up to level {char["lvl"]}!') # current level
A = (f'{char["name"]} levelled up to level {char["lvl"]}!') # current level
print(f'( INT {round((char["stats"]["int"] + nInt))} - STR {round(char["stats"]["str"] + nStr)} - DEX {round(char["stats"]["dex"] + nDex)} )') # print new stats
B = (f'( INT {round((char["stats"]["int"] + nInt))} - STR {round(char["stats"]["str"] + nStr)} - DEX {round(char["stats"]["dex"] + nDex)} )') # print new statsm
char['stats']['str'] += nStr
char['stats']['dex'] += nDex
char['stats']['int'] += nInt
TEXT(A,B,None)
from random import randint
def takeDmg(attacker, defender): # damage alorithm
dmg = randint(attacker['stats']['atk'][0], attacker['stats']['atk'][1])
defender['stats']['hp'] = defender['stats']['hp'] - dmg
print(f'{defender["name"]} takes {dmg} damage!')
#TEXT(f'{defender["name"]} takes {dmg} damage!')
if defender['stats']['hp'] <= 0:
print(f'{defender["name"]} has been slain...')
#TEXT(f'{defender["name"]} has been slain...')
attacker['xp'] += defender['reward']
level(attacker)
if defender==hero:
#Dead()
pass
else:
hero['stats']['hp']=heroHP
#Title()
pass
def Battle(player, enemy):
global ONE, TWO, THREE, FOUR
mouse.set_visible(1)
clock = time.Clock()
YES = Rect(100, 100, 50, 50)
NO = Rect(500, 100, 50, 50)
Text = Rect(70, 300, 500, 75)
#while ((enemy['stats']['hp']) > 0):
while True:
for e in event.get():
if e.type == QUIT:
exit("Quit") # if X is pressed, exit program
elif e.type == KEYDOWN:
if e.key == K_ESCAPE:
exit()
elif e.type == MOUSEBUTTONDOWN:
# 1 is the left mouse button, 2 is middle, 3 is right.
if e.button == 1:
# `event.pos` is the mouse position.
if YES.collidepoint(e.pos):
takeDmg(player, enemy)
print(f'{enemy["name"]} takes the opportunity to attack!')
#TEXT(f'{enemy["name"]} takes the opportunity to attack!')
takeDmg(enemy, player)
elif NO.collidepoint(e.pos):
print(f'{enemy["name"]} takes the opportunity to attack!')
#TEXT(f'{enemy["name"]} takes the opportunity to attack!')
takeDmg(enemy, player)
screen.fill(WHITE)
draw.rect(screen, BLACK, YES)
draw.rect(screen, BLACK, NO)
draw.rect(screen, GRAY, Text)
YES_surf = FONT.render(("YES"), True, WHITE)
NO_surf = FONT.render(("NO"), True, WHITE)
Text1_surf = FONT.render(ONE, True, WHITE)
Text2_surf = FONT.render(TWO, True, WHITE)
Text3_surf = FONT.render(THREE, True, WHITE)
Text4_surf = FONT.render(FOUR, True, WHITE)
screen.blit(YES_surf, YES)
screen.blit(NO_surf, NO)
screen.blit(Text1_surf, (80, 305))
screen.blit(Text2_surf, (80, 320))
screen.blit(Text3_surf, (80, 335))
screen.blit(Text4_surf, (80, 350))
display.update()
clock.tick(60)
Battle(hero, boss1)
If all you want to do is make counter a global variable that only gets set to 0 at the start of the program instead of a local variable that gets reset to 0 on each call, you do that the exact same way you handled ONE and the other globals in the same function:
counter =0
def TEXT(A, B, C):
global ONE, TWO, THREE, FOUR
global counter
text = True
if text:
if counter == 10:
# etc.
counter += 1
The only changes are moving that counter = 0 from the function body to the top level, and adding global counter at the start of the function body.
I am creating a text adventure. How could I to add static text to this.
What i mean is some text that always stays on the left side of the window. Even if all the other text is scrolling down. Also how could i make this text red.
Here is an example that shows some static text in red(that always stays on top):
import sys
import curses
curses.initscr()
if not curses.has_colors():
curses.endwin()
print "no colors"
sys.exit()
else:
curses.start_color()
curses.noecho() # don't echo the keys on the screen
curses.cbreak() # don't wait enter for input
curses.curs_set(0) # don't show cursor.
RED_TEXT = 1
curses.init_pair(RED_TEXT, curses.COLOR_RED, curses.COLOR_BLACK)
window = curses.newwin(20, 20, 0, 0)
window.box()
staticwin = curses.newwin(5, 10, 1, 1)
staticwin.box()
staticwin.addstr(1, 1, "test", curses.color_pair(RED_TEXT))
cur_x = 10
cur_y = 10
while True:
window.addch(cur_y, cur_x, '#')
window.refresh()
staticwin.box()
staticwin.refresh()
inchar = window.getch()
window.addch(cur_y, cur_x, ' ')
# W,A,S,D used to move around the #
if inchar == ord('w'):
cur_y -= 1
elif inchar == ord('a'):
cur_x -= 1
elif inchar == ord('d'):
cur_x += 1
elif inchar == ord('s'):
cur_y += 1
elif inchar == ord('q'):
break
curses.endwin()
A screenshot of the result:
Remember that windows on top must be refresh()ed last otherwise the windows that should go below are drawn over them.
If you want to change the static text do:
staticwin.clear() #clean the window
staticwin.addstr(1, 1, "insert-text-here", curses.color_pair(RED_TEXT))
staticwin.box() #re-draw the box
staticwin.refresh()
Where the 1, 1 means to start writing from the second character of the second line(remember: coordinates start at 0). This is needed since the window's box is drawn on the first line and first column.
You create static text by putting it in a separate window. Create a window large enough for all the text, and then create a smaller window for the dynamic text. Text is colored by passing the various COLOR_* constants as the text attribute.