controllables.TextScreen

class controllables.TextScreen(port: Optional[int] = None)

Reference to a text screen part.

Text screens can be useful both as the primary output for a script and as a static debugging output to examine the state of your program.

The following script uses the text screen for as its primary output and it assumes that it is assigned to port 0 and is at least 8 x 5 in size.

from controllables import TextScreen
from inputs import Input, ButtonState
from time import time
from random import random

screen = TextScreen(0)
screen.horizontal_alignment = TextScreen.HorizontalAlignment.LEFT
screen.vertical_alignment = TextScreen.VerticalAlignment.TOP

p1_up = Input.stream("w")
p1_down = Input.stream("s")
p2_up = Input.stream("i")
p2_down = Input.stream("k")

paddle_speed = 100
ball_speed = 1
arena_height = 5
arena_width = 20

score = [0,0]

class GameState():
    def __init__(self):
        self.paddle1 = 0
        self.paddle2 = 0
        self.ball = [arena_width // 2,arena_height // 2]
        self.balldir = [1 if random() < .5 else -1,1 if random() < .5 else -1]
        self.ballspeed = 2

    def reset(self):
        self.ballspeed = 2
        self.ball = [arena_width // 2,arena_height // 2]
        self.balldir = [1 if random() < .5 else -1,1 if random() < .5 else -1]

def display(gamestate : GameState) -> str:
    lines = [[' ' for _ in range(0,arena_width)] for _ in range(0,arena_height)]
    lines[0][arena_width // 2 - 1] = str(score[0])
    lines[0][arena_width // 2 + 1] = str(score[1])
    lines[gamestate.paddle1][0] = '|'
    lines[gamestate.paddle2][arena_width - 1] = '|'
    lines[gamestate.ball[1]][gamestate.ball[0]] = '*'
    return '\n'.join([''.join(line) for line in lines])


def apply_input(gamestate : GameState):
    for event in p1_up:
        if event == ButtonState.UP:
            gamestate.paddle1 -= 1
    for event in p1_down:
        if event == ButtonState.UP:
            gamestate.paddle1 += 1
    for event in p2_up:
        if event == ButtonState.UP:
            gamestate.paddle2 -= 1
    for event in p2_down:
        if event == ButtonState.UP:
            gamestate.paddle2 += 1

def clamp_paddles(gamestate : GameState):
    if gamestate.paddle1 < 0:
        gamestate.paddle1 = 0
    if gamestate.paddle2 < 0:
        gamestate.paddle2 = 0
    if gamestate.paddle1 >= arena_height:
        gamestate.paddle1 = arena_height - 1
    if gamestate.paddle2 >= arena_height:
        gamestate.paddle2 = arena_height - 1

def clamp_ball(gamestate : GameState):
    if gamestate.ball[0] <= 0:
        if gamestate.paddle1 == gamestate.ball[1]:
            gamestate.ball[0] = 1
            gamestate.balldir[0] = 1
            gamestate.ballspeed *= 1.2
        elif gamestate.ball[0] < 0:
            score[1] += 1
            gamestate.reset()
    if gamestate.ball[1] < 0:
        gamestate.ball[1] = 0
        gamestate.balldir[1] = 1
    if gamestate.ball[0] >= arena_width - 1:
        if gamestate.paddle2 == gamestate.ball[1]:
            gamestate.ball[0] = arena_width - 2
            gamestate.balldir[0] = -1
            gamestate.ballspeed *= 1.2
        elif gamestate.ball[0] > arena_width - 1:
            score[0] += 1
            gamestate.reset()
    if gamestate.ball[1] >= arena_height:
        gamestate.ball[1] = arena_height - 1
        gamestate.balldir[1] = -1

def move_ball(gamestate : GameState):
    gamestate.ball[0] += gamestate.balldir[0]
    gamestate.ball[1] += gamestate.balldir[1]

gamestate = GameState()
last_time_ball_moved = time()
while True:
    apply_input(gamestate)
    clamp_paddles(gamestate)
    if time() - last_time_ball_moved > 1 / gamestate.ballspeed:
        move_ball(gamestate)
        last_time_ball_moved = time()
    clamp_ball(gamestate)

    screen.text = display(gamestate)
name() str

Returns the user editable name of the controllable as found in the properties tab of the game.

The following example assumes that any controllable or sensor is assigned to port 0 and prints out its name.

from ports import PortReference

print(PortReference(0).name())
property text: str

The text value that the screen displays.

from controllables import TextScreen
import time

screen = TextScreen(0)
start_time = time.time()

while True:
    screen.text = f'time: {time.time() - start_time : 0.1f}'
property size: float

The font size of the text.

from controllables import TextScreen
from time import sleep

screen = TextScreen(0)
screen.text = "Hello World"
# if you just want to set the text size
# you can do that at the start of your
# script like this
screen.size = 40

# you can also animate the font size
# during play like this
while True:
    for size in range(40,160,5):
        sleep(.05)
        screen.size = size
    for size in range(160,40,-5):
        sleep(.05)
        screen.size = size
property color: Color

The color of the text.

To learn more about the color class, check out Color.

from controllables import TextScreen
from time import sleep
from color import Color

screen = TextScreen(0)
screen.text = "Hello World"
# if you just want to set the text color
# you can do that at the start of your
# script like this
screen.color = Color.red()

# you can also animate the text color
# during play like this
while True:
    for i in range(0,255,5):
        sleep(.05)
        screen.color = Color(1 - i/255,0,i/255)
    for i in range(255,0,-5):
        sleep(.05)
        screen.color = Color(1 - i/255,0,i/255)
property horizontal_alignment: HorizontalAlignment

The horizontal alignment setting. Centered by default.

from controllables import TextScreen
from time import sleep

screen = TextScreen(0)
screen.horizontal_alignment = TextScreen.HorizontalAlignment.LEFT
screen.text = "I'm left aligned!"

while True:
    sleep(1)
    # you can also set this using the name as a string
    screen.horizontal_alignment = "RIGHT"
    screen.text = "I'm a main menu button!"

    sleep(1)
    # there's also an alias with a shorter name
    screen.h_align = "CENTER"
    screen.text = "I'm a road sign!"

    sleep(1)
    # you can also leave off any letters at the end of the name
    screen.h_align = "JUST" # or "J" or "j" if you want
    screen.text = "I'm a newspaper column!"
property h_align: HorizontalAlignment

Alias for the horizontal_alignment property.

property vertical_alignment: VerticalAlignment

The vertical alignment setting. Centered by default.

from controllables import TextScreen
from time import sleep

screen = TextScreen(0)
screen.vertical_alignment = TextScreen.VerticalAlignment.MIDDLE
screen.text = "I'm middle aligned!"

while True:
    sleep(1)
    # you can also set this using the name as a string
    screen.vertical_alignment = "TOP"
    screen.text = "I'm top aligned!"

    sleep(1)
    # there's also an alias with a shorter name
    screen.v_align = "BOTTOM"
    screen.text = "I'm bottom aligned!"

    sleep(1)
    # you can also leave off letters at the end
    screen.v_align = "MID" # or "M" or "m" if you want
    screen.text = "I'm middle aligned!"
property v_align: VerticalAlignment

Alias for the vertical_alignment property.

property auto_size: bool

Determines whether the text changes font size automatically in order to fit onto the screen if it would run out of space. This property is False by default.

from controllables import TextScreen
from time import sleep

screen = TextScreen(0)
screen.auto_size = True
screen.text = "Well the years start coming,\n"

for i in range(0,600):
    screen.text += "And they dont stop coming!\n"
    sleep(.5)
property auto_size_min: int

The minimum font size that will be used if auto_size is set to True.

from controllables import TextScreen

screen = TextScreen(0)
screen.auto_size = True
screen.auto_size_min = 80
screen.text = "Saluton Mondo " * 100
property auto_size_max: int

The maximum font size that will be used if auto_size is set to True.

from controllables import TextScreen

screen = TextScreen(0)
screen.auto_size = True
screen.auto_size_max = 300
screen.text = "Ĥ"
property wrapping: bool

Determines whether the text can break lines to wrap around when it hits the edge of the screen. This property is True by default.

from controllables import TextScreen

screen = TextScreen(0)
screen.text = "Oh no! This text is too long!" * 64
screen.wrapping = False
class HorizontalAlignment(value)

An enum representing the various options for horizontally aligning the TextScreen.

LEFT

Align the left side of each text line to the left of the screen.

CENTER

Align the center of each line to the center of the screen.

RIGHT

Align the right side of each line to the right of the screen.

JUSTIFIED

Stretch each line, except the last, so that the left and right sides reach their respective sides of the screen.

FLUSH

Stretch each line so that the left and right sides reach their respective sides of the screen.

class VerticalAlignment(value)

An enum representing the various options for vertically aligning the TextScreen.

TOP

Align the top of the top line to the top of the screen.

MIDDLE

Align the middle of the middle line to the middle of the screen.

BOTTOM

Align the bottom of the bottom line to the bottom of the screen.