Fonts and Text
Rendering text is essential for UI, dialogue, scores, and debugging.
Kraken provides the Font and Text classes for flexible text rendering.
Loading a Font
Load a TrueType font (.ttf) at a specific point size:
# Load font at size 24
font = kn.Font("fonts/arial.ttf", 24)
# Load a larger font for titles
title_font = kn.Font("fonts/arial.ttf", 48)
# Use a built-in font
retro_font = kn.Font("kraken-retro", 16)
You can also change a font's size at runtime with the pt_size property:
font.pt_size = 32 # Change to 32pt
Kraken includes two built-in fonts: "kraken-clean" and "kraken-retro".
Creating Text Objects
Create a Text object by passing a font, then set its content and color:
# Create a text object with a font
label = kn.Text(font)
label.text = "Hello, World!"
label.color = kn.color.WHITE
# Create another with a custom color
score_text = kn.Text(font)
score_text.text = "Score: 0"
score_text.color = kn.Color(255, 200, 0)
Drawing Text
Text objects have their own draw() method:
position = kn.Vec2(100, 100)
while kn.window.is_open():
kn.event.poll()
kn.renderer.clear()
label.draw(position)
kn.renderer.present()
Result:
Updating Text
To change the displayed text, simply update the .text property:
score = 0
score_text = kn.Text(font)
score_text.text = f"Score: {score}"
score_text.color = kn.color.WHITE
# When score changes:
score += 10
score_text.text = f"Score: {score}"
Font Styling
Fonts have properties for styling, with the ability to use more than one at a time:
font = kn.Font("fonts/arial.ttf", 24)
# Style options
font.bold = True
font.italic = True
font.underline = True
font.strikethrough = True
# Outline
font.outline = 1 # 1px outline
In practice:
Drop Shadows
Text objects support drop shadows via the shadow_color and shadow_offset properties.
Shadows will only be drawn if shadow_color.a > 0 and shadow_offset is not (0, 0).
# Once
label = kn.Text(font)
label.color = kn.color.WHITE
label.shadow_offset = kn.Vec2(4, 4)
label.shadow_color = kn.Color(0, 0, 0, 128)
# Per frame
label.draw(pos)
Result:
Multi-line Text
Use \n for line breaks, or set wrap_width for automatic wrapping:
dialogue = kn.Text(font)
dialogue.text = "Line 1\nLine 2\nLine 3"
# Or with automatic wrapping
dialogue.wrap_width = 300
dialogue.text = "This long text will automatically wrap at 300 pixels."
Result:
Putting It Together
Here's a full example with score display and title screen:
import pykraken as kn
SCN_WIDTH, SCN_HEIGHT = SCN_SIZE = kn.Vec2(800, 600)
kn.init()
kn.window.create("Text Example", SCN_SIZE)
kn.time.set_target(60)
# Load fonts
small_font = kn.Font("fonts/arial.ttf", 20)
medium_font = kn.Font("fonts/arial.ttf", 32)
large_font = kn.Font("fonts/arial.ttf", 64)
# Create static text
title = kn.Text(large_font)
title.text = "SPACE SHOOTER"
title.color = kn.Color(100, 200, 255)
instructions = kn.Text(medium_font)
instructions.text = "Press SPACE to start"
# Dynamic text
score = 0
score_text = kn.Text(small_font)
score_text.text = f"Score: {score}"
score_text.color = kn.color.YELLOW
fps_text = kn.Text(small_font)
fps_text.color = kn.color.GRAY
game_started = False
player_rect = kn.Rect(0, 0, 40, 40)
player_rect.center = (SCN_WIDTH / 2, SCN_HEIGHT - 100)
while kn.window.is_open():
kn.event.poll()
dt = kn.time.get_delta()
if not game_started:
# Title screen
if kn.key.is_just_pressed(kn.K_SPACE):
game_started = True
kn.renderer.clear((20, 20, 40))
title.draw((SCN_WIDTH / 2, SCN_HEIGHT / 3), kn.Anchor.CENTER)
instructions.draw(SCN_SIZE / 2, kn.Anchor.CENTER)
else:
# Game screen
if kn.key.is_pressed(kn.S_a):
player_rect.center += kn.Vec2(-300 * dt, 0)
if kn.key.is_pressed(kn.S_d):
player_rect.center += kn.Vec2(300 * dt, 0)
# Score increases over time (for demo)
score += 1
score_text.text = f"Score: {score}"
kn.renderer.clear((20, 20, 40))
# Draw player
kn.draw.rect(player_rect, kn.color.GREEN)
# Draw score in top-left
score_text.draw((10, 10))
# Draw FPS in top-right
fps_text.text = f"FPS: {int(kn.time.get_fps())}"
fps_text.draw((SCN_WIDTH - 10, 10), kn.Anchor.TOP_RIGHT)
kn.renderer.present()
kn.quit()
Result: