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:
1 parent
4cfe73c9eb
commit
8214fda8f6
15 files changed
+1920
-229
No files matched your search
+26
-11
@@ -2,6 +2,7 @@ package card
|
||||
|
||||
import "core:math"
|
||||
import raylib "vendor:raylib"
|
||||
import assets "../assets"
|
||||
import themes "../themes"
|
||||
import ui "../ui"
|
||||
|
||||
@@ -19,8 +20,9 @@ HOVER_LIFT :: 4
|
||||
|
||||
Card :: struct {
|
||||
rect: raylib.Rectangle, // resting position on screen
|
||||
text: cstring,
|
||||
is_kana: bool,
|
||||
text: cstring,
|
||||
hint: cstring, // small second line on reading cards
|
||||
is_symbol: bool, // script symbol (vs. its reading)
|
||||
pair_id: int,
|
||||
face_up: bool, // logical state; the animation follows it
|
||||
matched: bool,
|
||||
@@ -154,21 +156,34 @@ get_back_art :: proc(flag: themes.Flag) -> raylib.Texture2D {
|
||||
return back_art[flag].texture
|
||||
}
|
||||
|
||||
// Renders the card's face into its own texture
|
||||
build_face :: proc(card: ^Card, theme: themes.Theme) {
|
||||
// Font size that fits text inside the card width
|
||||
@(private)
|
||||
fit_size :: proc(text: cstring, size: f32, style: assets.Font_Style) -> f32 {
|
||||
max_width: f32 = ART_WIDTH * 0.78
|
||||
width := ui.measure_text(text, size, style).x
|
||||
return width > max_width ? size * max_width / width : size
|
||||
}
|
||||
|
||||
// Renders the card's face into its own texture. Symbols use their script's font.
|
||||
build_face :: proc(card: ^Card, theme: themes.Theme, symbol_style: assets.Font_Style) {
|
||||
unload_face(card)
|
||||
card.face_art = new_art_texture(theme.primary)
|
||||
raylib.BeginTextureMode(card.face_art)
|
||||
draw_frame(theme.card_face, theme.primary)
|
||||
raylib.DrawRectangleRoundedLinesEx(art_rect(16), ROUNDNESS, SEGMENTS, 2, raylib.Fade(theme.primary, 0.35))
|
||||
|
||||
size: f32 = card.is_kana ? 132 : 96
|
||||
color := card.is_kana ? theme.ink : theme.primary
|
||||
// Shrink long romaji (e.g. "TSU") to fit inside the card
|
||||
max_width: f32 = ART_WIDTH * 0.78
|
||||
width := ui.measure_text(card.text, size, bold = true).x
|
||||
if width > max_width { size *= max_width / width }
|
||||
ui.draw_text_in_rect(card.text, art_rect(), size, color, bold = true)
|
||||
if card.is_symbol {
|
||||
ui.draw_text_in_rect(card.text, art_rect(), fit_size(card.text, 132, symbol_style), theme.ink, symbol_style)
|
||||
} else if card.hint == nil {
|
||||
ui.draw_text_in_rect(card.text, art_rect(), fit_size(card.text, 96, .BOLD), theme.primary, .BOLD)
|
||||
} else {
|
||||
// Reading on top, hint underneath
|
||||
main_rect := art_rect()
|
||||
main_rect.height -= 56
|
||||
ui.draw_text_in_rect(card.text, main_rect, fit_size(card.text, 88, .BOLD), theme.primary, .BOLD)
|
||||
hint_rect := raylib.Rectangle{0, ART_HEIGHT * 0.62, ART_WIDTH, 60}
|
||||
ui.draw_text_in_rect(card.hint, hint_rect, fit_size(card.hint, 34, .REGULAR), theme.ink, .REGULAR)
|
||||
}
|
||||
raylib.EndTextureMode()
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user