Add Katakana, Korean and Thai games and difficulty levels

- decks package: Hiragana, Katakana, Hangul jamo and Thai consonants
  (Thai readings carry the letter's name word, since sounds repeat)
- Per-script fonts: Jua for Hangul, Mali for Thai (both OFL)
- Memory game works with any deck; Easy 3x4, Normal 4x6, Hard 4x8
- Language menus pick a deck and difficulty, with number/arrow key shortcuts
- Tests cover every deck, difficulty, and font glyph coverage

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
SansanandClaude Opus 5.5 committed 2026-10-01 21:33:16 +02:00
1 parent 4cfe73c9eb
commit 8214fda8f6
15 files changed
+1920 -229

No files matched your search

+26 -15
View File
@@ -5,6 +5,8 @@ import assets "../assets"
import audio "../audio"
import themes "../themes"
Font_Style :: assets.Font_Style
TEXT_SPACING :: 1
@(private)
@@ -25,38 +27,42 @@ set_hovered :: proc() {
any_hovered = true
}
measure_text :: proc(text: cstring, size: f32, bold := false) -> raylib.Vector2 {
return raylib.MeasureTextEx(assets.get_font(bold), text, size, TEXT_SPACING)
measure_text :: proc(text: cstring, size: f32, style: Font_Style = .REGULAR) -> raylib.Vector2 {
return raylib.MeasureTextEx(assets.get_font(style), text, size, TEXT_SPACING)
}
draw_text :: proc(text: cstring, pos: raylib.Vector2, size: f32, color: raylib.Color, bold := false) {
raylib.DrawTextEx(assets.get_font(bold), text, pos, size, TEXT_SPACING, color)
draw_text :: proc(text: cstring, pos: raylib.Vector2, size: f32, color: raylib.Color, style: Font_Style = .REGULAR) {
raylib.DrawTextEx(assets.get_font(style), text, pos, size, TEXT_SPACING, color)
}
// Draws text horizontally centered on center_x with its top at y
draw_text_centered :: proc(text: cstring, center_x, y, size: f32, color: raylib.Color, bold := false, shadow := false) {
w := measure_text(text, size, bold).x
draw_text_centered :: proc(text: cstring, center_x, y, size: f32, color: raylib.Color,
style: Font_Style = .REGULAR, shadow := false) {
w := measure_text(text, size, style).x
pos := raylib.Vector2{center_x - w / 2, y}
if shadow {
draw_text(text, pos + {0, size * 0.05}, size, raylib.Fade(themes.BLACK, 0.18), bold)
draw_text(text, pos + {0, size * 0.05}, size, raylib.Fade(themes.BLACK, 0.18), style)
}
draw_text(text, pos, size, color, bold)
draw_text(text, pos, size, color, style)
}
// Draws text centered in a rectangle
draw_text_in_rect :: proc(text: cstring, rect: raylib.Rectangle, size: f32, color: raylib.Color, bold := false) {
dims := measure_text(text, size, bold)
draw_text_in_rect :: proc(text: cstring, rect: raylib.Rectangle, size: f32, color: raylib.Color,
style: Font_Style = .REGULAR) {
dims := measure_text(text, size, style)
pos := raylib.Vector2{rect.x + (rect.width - dims.x) / 2, rect.y + (rect.height - dims.y) / 2}
draw_text(text, pos, size, color, bold)
draw_text(text, pos, size, color, style)
}
draw_title :: proc(text: cstring, y: f32, color: raylib.Color, size: f32 = themes.TITLE_FONT_SIZE) {
draw_text_centered(text, themes.SCREEN_WIDTH / 2, y, size, color, bold = true, shadow = true)
draw_text_centered(text, themes.SCREEN_WIDTH / 2, y, size, color, style = .BOLD, shadow = true)
}
// A rounded button with hover, press and shadow states. Returns true when clicked.
// A rounded button with hover, press and shadow states. Returns true when clicked
// or when its hotkey is pressed.
button :: proc(rect: raylib.Rectangle, text: cstring, color: raylib.Color,
text_color := themes.WHITE, font_size: f32 = themes.BUTTON_FONT_SIZE) -> bool {
text_color := themes.WHITE, font_size: f32 = themes.BUTTON_FONT_SIZE,
hotkey := raylib.KeyboardKey.KEY_NULL, selected := false) -> bool {
hovered := raylib.CheckCollisionPointRec(raylib.GetMousePosition(), rect)
pressed := hovered && raylib.IsMouseButtonDown(.LEFT)
if hovered { set_hovered() }
@@ -76,9 +82,14 @@ button :: proc(rect: raylib.Rectangle, text: cstring, color: raylib.Color,
raylib.DrawRectangleRounded(shadow, 0.4, 12, raylib.Fade(themes.BLACK, 0.18))
body := raylib.Rectangle{rect.x, rect.y - lift, rect.width, rect.height}
raylib.DrawRectangleRounded(body, 0.4, 12, fill)
draw_text_in_rect(text, body, font_size, text_color, bold = true)
if selected {
ring := raylib.Rectangle{body.x - 4, body.y - 4, body.width + 8, body.height + 8}
raylib.DrawRectangleRoundedLinesEx(ring, 0.4, 12, 3, color)
}
draw_text_in_rect(text, body, font_size, text_color, style = .BOLD)
clicked := hovered && raylib.IsMouseButtonPressed(.LEFT)
if hotkey != .KEY_NULL && raylib.IsKeyPressed(hotkey) { clicked = true }
if clicked { audio.play(.CLICK) }
return clicked
}