[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [pygame] ** Newbie ** Questions re: text windows and input fields
>I am a pyGame newbie (using it about a week), writing a simple map
>editor for an RPG-style game. I have found pyGame incredibly easy to
>use; it's really jumpstarted my coding. But there is one area where I
>need some direction. While running my program, I need to print out
>information, and receive text input. I've been sendning those things
>to the command prompt, but it's a hassle flipping back and forth from
>my graphical game window to the text window, and vice versa.
on seeing your message i thought to myself 'hmm, i wonder how much work
it is..'
i coded together a rough quake-style console. it works mildly well, but
might be enough to get the job done for you. i see room for seveal big
enhancements (and they shouldn't be hard to add if anyone's interested)
command history buffer
scrollback buffer
prettier
"erase" properly
hookup to python interpreter :]
while not full featured, it does win points on the 'easy to use'
category. included in the script is a small runtime test so you can see
how to make it work (since i just typed this up quick, so no
documentation :[)
to make it work you just pass it any events you get from pygame. it will
filter them as appropriate. it will send a "USEREVENT" with a field
"command" when the user has entered something. add lines to it by
calling the "write" method.
you can easily use a different font or display more lines by changing
the arguments passed to the constructor. the rest is fairly easy to
customize by changing the small "customize" method.
actually, having this full featured would be a great addition to the
pygame library. for now, this is all you get for my 'morning email
reading experiment'.
import pygame
from pygame.locals import *
class MiniConsole:
def __init__(self, font=None, numlines=5):
self.screen = pygame.display.get_surface()
if not self.screen: raise RuntimeError, "sceen not initialized"
if font == None:
if not pygame.font: raise RuntimeError, "no pygame.font module"
pygame.font.init()
font = pygame.font.Font(None, 20)
self.font = font
self.numlines = numlines
self.lineheight = font.get_ascent() + font.get_descent() + 3
size = self.screen.get_width(), self.lineheight*(numlines+2)
self.rect = Rect((0, 0), size)
self.visible = 0
self.clear()
self.customize()
def customize(self):
self.textcolor = 200, 255, 200
self.bgcolor = 50, 80, 50
self.entercolor = 255, 255, 255
self.event = USEREVENT
self.write('Welcome to MiniConsole...')
self.prompt = '>>> '
self.visiblekey = K_TAB
def clear(self):
self.buffer = [None for x in range(self.numlines)]
self.entered = ''
def write(self, text):
text = text.strip()
if not text: return
print 'TEXT="%s"'%text
text = self.font.render(text, 0, self.textcolor)
self.buffer = self.buffer[1:] + [text]
def draw(self):
if not self.visible: return None
self.screen.fill(self.bgcolor, self.rect)
outline = self.rect.inflate(-2,-2).move(-1,-1)
pygame.draw.rect(self.screen, self.textcolor, outline, 2)
height = 0
for line in self.buffer:
if line is not None:
self.screen.blit(line, (3, height))
height += self.lineheight
entry = self.prompt + self.entered
img = self.font.render(entry, 0, self.entercolor)
self.screen.blit(img, (3, height+3))
return self.rect
def handle(self, event):
if not self.visible:
if event.type == KEYDOWN and event.key == self.visiblekey:
self.togglevisible()
return pygame.event.Event(NOEVENT)
return event
if event.type == KEYUP:
return pygame.event.Event(NOEVENT)
elif event.type == KEYDOWN:
if event.key == K_BACKSPACE:
if self.entered: self.entered = self.entered[:-1]
elif event.key == K_RETURN:
if self.entered:
entered = self.entered
self.entered = ''
return pygame.event.Event(self.event, command=entered)
elif event.key == self.visiblekey:
self.togglevisible()
elif event.unicode:
self.entered += str(event.unicode)
return pygame.event.Event(NOEVENT)
return event
def togglevisible(self):
self.visible = not self.visible
if not self.visible:
self.screen.fill(0, self.rect)
pygame.display.update(self.rect)
if __name__ == '__main__':
pygame.init()
screen = pygame.display.set_mode((640, 480))
ball = pygame.Surface((60, 60))
pygame.draw.ellipse(ball, (255, 0, 0), ball.get_rect(), 0)
screenrect = screen.get_rect()
ballrect = ball.get_rect()
ballspeed = [2, 2]
console = MiniConsole()
clock = pygame.time.Clock()
playing = 1
while playing:
for event in pygame.event.get():
event = console.handle(event)
if event.type == QUIT: playing = 0
elif event.type == KEYDOWN and event.key == K_ESCAPE: playing = 0
elif event.type == USEREVENT:
message = 'YOU TYPED: "%s"' % event.command
print message
print >> console, message
oldballrect = ballrect
ballrect = ballrect.move(ballspeed)
if ballrect.bottom >= screenrect.bottom or ballrect.top < screenrect.top:
ballspeed[1] = -ballspeed[1]
console.write("Vertical Bounce! %r"%ballrect)
if ballrect.right >= screenrect.right or ballrect.left < screenrect.left:
ballspeed[0] = -ballspeed[0]
console.write("HorizontalBounce! %r"%ballrect)
rect1 = screen.fill(0, oldballrect)
rect2 = screen.blit(ball, ballrect)
rect3 = console.draw()
pygame.display.update((rect1, rect2, rect3))
clock.tick(60)