Files
HanjaKanaMun/main.odin
T
SansanandClaude Opus 5.5 3794a9e2e9 Add screen fade-in and card deal-in animations
Cards slide in one after another when a game starts and can't be picked
until they have landed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:36:54 +02:00

115 lines
3.4 KiB
Odin

package main
import "core:fmt"
import "core:reflect"
import raylib "vendor:raylib"
import assets "src/assets"
import audio "src/audio"
import card "src/card"
import decks "src/decks"
import memory "src/memory"
import profile "src/profile"
import screens "src/screens"
import themes "src/themes"
import ui "src/ui"
TRANSITION_SPEED :: 4 // screen fade-ins per second
// Where Escape takes you from each screen (nil = quit)
parent_screen :: proc(screen: themes.Screen) -> Maybe(themes.Screen) {
switch screen {
case .MAIN_MENU: return nil
case .LANGUAGE_MENU: return .MAIN_MENU
case .MEMORY: return .LANGUAGE_MENU
}
return nil
}
main :: proc() {
raylib.SetConfigFlags({.MSAA_4X_HINT, .VSYNC_HINT})
raylib.InitWindow(themes.SCREEN_WIDTH, themes.SCREEN_HEIGHT, "HanjaKanaMun")
defer raylib.CloseWindow()
raylib.SetExitKey(.KEY_NULL)
// Assets are loaded relative to the executable, so it can be started from anywhere
raylib.ChangeDirectory(raylib.GetApplicationDirectory())
raylib.SetTargetFPS(60)
raylib.InitAudioDevice()
defer raylib.CloseAudioDevice()
audio.load()
defer audio.unload()
assets.load_fonts()
defer assets.unload_fonts()
card.load_art()
defer card.unload_art()
defer memory.unload()
if !profile.init() {
raylib.TraceLog(.WARNING, "PROFILE: Could not read saved scores, starting fresh")
}
screen := themes.Screen.MAIN_MENU
language := decks.Language.JAPANESE
difficulty := memory.Difficulty.NORMAL
if saved, ok := reflect.enum_from_name(memory.Difficulty, profile.data.difficulty); ok {
difficulty = saved
}
transition_t: f32 = 1 // fades the screen in from the background color
running := true
for running && !raylib.WindowShouldClose() {
dt := raylib.GetFrameTime()
if raylib.IsKeyPressed(.ESCAPE) {
if parent, ok := parent_screen(screen).?; ok {
screen = parent
transition_t = 1
} else {
running = false
}
}
if screen == .MEMORY {
memory.update(dt)
}
raylib.BeginDrawing()
ui.begin_frame()
next := screen
start_deck: Maybe(decks.Deck_Id)
switch screen {
case .MAIN_MENU:
if picked, ok := screens.main_menu().?; ok {
language = picked
next = .LANGUAGE_MENU
}
case .LANGUAGE_MENU:
switch result in screens.language_menu(language, &difficulty) {
case decks.Deck_Id:
start_deck = result
next = .MEMORY
case themes.Screen:
next = result
}
case .MEMORY:
next = memory.draw()
}
if transition_t > 0 {
alpha := transition_t * transition_t
raylib.DrawRectangle(0, 0, themes.SCREEN_WIDTH, themes.SCREEN_HEIGHT, raylib.Fade(themes.MENU_BACKGROUND, alpha))
transition_t = max(transition_t - dt * TRANSITION_SPEED, 0)
}
ui.end_frame()
raylib.EndDrawing()
free_all(context.temp_allocator)
profile.set_difficulty(fmt.tprintf("%v", difficulty))
// Building card faces renders into textures, so do it outside of drawing
if deck, ok := start_deck.?; ok {
memory.start(deck, difficulty)
}
if next != screen { transition_t = 1 }
screen = next
}
}