Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Rendering text (for classic 'Star Trek' game) using scene?
-
I've found a Python version of the classic text-based 'Star Trek' game. It writes loads of text to the console for star-field displays etc.
I'd like to rewrite it with a static text display that updates in place, and though that the 'scene' module would be the best way to do it, but I'm obviously not understanding how the 'scene' module works.
For example: I want to display the intro text, so I've coded the following:
import console from scene import * import time class MyScene(Scene): def draw(self): pass def setup(self): global screen screen = self.size w, h = self.size.w, self.size.h self.graphicBlurb() def graphicBlurb(self): blurb = [] blurb.append("Space ... the final frontier.") blurb.append("These are the voyages of the starship Enterprise") blurb.append("Its five year mission ...") blurb.append("... to boldly go where no-one has gone before") blurb.append("You are Captain Kirk.") blurb.append("Your mission is to destroy all of the Klingons in the galaxy.") #font_size = 60 if self.size5.w > 700 else 40 yOffset = screen.h/(len(blurb)) yPos = screen.h for line in blurb: text(line,'GillSans',40,screen.w/2,yPos) print "Printing {0} {1}".format(line,time.localtime()) time.sleep(1.5) yPos -= yOffset trekGame = MyScene() run(trekGame)
but when I run this, instead of the lines of text appearing one at a time down the screen, I get a black screen for about 10.5 seconds, then all the text appears at once.
I'm guessing that it's running the 'setup' method but nothing is appearing on screen until the 'draw' method is called.
What's the best way to do this, or is 'scene' only for programs that need to 60fps gameloop and should I be using the 'ui' module instead?
Thanks,
Steve
-
setup
is called once. Think of it more like compiling your scene.. Don't use wait here. All drawing should happen inside ofdraw
, and you can't usewait
there either. Rather, you'd keep track of time, and update game state inside draw (say, as instance variables of your scene class).For example, you'd have
MyScene.blurb
, which could be updated inside draw based on a counter, or maybe in a function called fromscene.delay
the first time draw is called, or touch happens. (A scene.delay'd function could call scene.delay at the end, for example to append to blurb once a second for example.If you want the user to type things, as opposed to just touch interaction, a SceneView might be a better fit, since you could have a textbox input field. You would still interact with the scene by use of your instance variables, and draw still does all of the drawing based on the game state encoded inside those instance variables
-
Thanks Jon. As this is a text-heavy game, I think that a 'ui' based interface will work better.
-
Take a look at stash. The stash terminal class probably does a lot of what you want, assuming you don't need colors -- it has a scrolling buffer and an input field that moves when the keyboard frame appears, along with history, and some autocompletion framework. Some formatting has been implemented in the ssh module, I believe, using the pyte terminal emulator library.
You can either subclass the appropriate classes, or you can actually write .py scripts that make use of the stash modules (i.e. called from within stash), for instance a script called from stash that uses raw_input will use stash's stdin replacement. You also have access to the global
_stash
for more complicated things like directly accessing the buffer.If you do need color, then you'd probably be best using a WebView for display, along with a TextView or TextField for input.