commit e4ec46e92e4ea43db0f8d9aea92a149845cdd5bd Author: Sebastian Date: Sat May 9 00:08:05 2026 +0200 Initial commit: Add main menu with Thai, Korean, Japanese buttons and language screens diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..77fcbe9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.test +*.out +learning + +# Go workspace file +go.work + +# Dependency directories +vendor/ + +# IDE specific +.idea/ +.vscode/ +*.swp +*.swo + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9dbbbc0 --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module learning + +go 1.26.2 + +require github.com/gen2brain/raylib-go/raylib v0.55.1 + +require ( + github.com/ebitengine/purego v0.7.1 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/sys v0.20.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..aa78a1e --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA= +github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/gen2brain/raylib-go/raylib v0.55.1 h1:1rdc10WvvYjtj7qijHnV9T38/WuvlT6IIL+PaZ6cNA8= +github.com/gen2brain/raylib-go/raylib v0.55.1/go.mod h1:BaY76bZk7nw1/kVOSQObPY1v1iwVE1KHAGMfvI6oK1Q= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/justfile b/justfile new file mode 100644 index 0000000..d98a690 --- /dev/null +++ b/justfile @@ -0,0 +1,21 @@ +# Build and run commands for the Go raylib project + +# Build the project +build: + go build -o learning . + +# Run the project +run: + go run . + +# Run all tests +test: + go test ./... + +# Build and run tests +build-test: + go build -o learning . && go test ./... + +# Clean build artifacts +clean: + rm -f learning diff --git a/learning b/learning new file mode 100755 index 0000000..99e69f5 Binary files /dev/null and b/learning differ diff --git a/main.go b/main.go new file mode 100644 index 0000000..7fb435b --- /dev/null +++ b/main.go @@ -0,0 +1,201 @@ +package main + +import ( + "runtime" + + "github.com/gen2brain/raylib-go/raylib" +) + +// Button represents a clickable button with animation state +type Button struct { + Bounds rl.Rectangle + Text string + Color rl.Color + Hovered bool + Clicked bool + Scale float32 + Action string +} + +// Screen represents different application screens +const ( + ScreenMenu = "menu" + ScreenThai = "thai" + ScreenKorean = "korean" + ScreenJapanese = "japanese" +) + +func main() { + // Initialize window + screenWidth := int32(800) + screenHeight := int32(450) + + rl.InitWindow(screenWidth, screenHeight, "Learning Raylib in Go") + defer rl.CloseWindow() + + // Set target FPS + rl.SetTargetFPS(60) + + // Button dimensions and positions + buttonWidth := int32(200) + buttonHeight := int32(50) + buttonSpacing := int32(20) + startY := int32(screenHeight/2) - (buttonHeight*3 + buttonSpacing*2)/2 + + // Create buttons + thaiBtn := Button{ + Bounds: rl.Rectangle{ + X: float32(screenWidth/2 - buttonWidth/2), + Y: float32(startY), + Width: float32(buttonWidth), + Height: float32(buttonHeight), + }, + Text: "Thai", + Color: rl.LightGray, + Scale: 1.0, + Action: ScreenThai, + } + + koreanBtn := Button{ + Bounds: rl.Rectangle{ + X: float32(screenWidth/2 - buttonWidth/2), + Y: float32(startY + buttonHeight + buttonSpacing), + Width: float32(buttonWidth), + Height: float32(buttonHeight), + }, + Text: "Korean", + Color: rl.LightGray, + Scale: 1.0, + Action: ScreenKorean, + } + + japaneseBtn := Button{ + Bounds: rl.Rectangle{ + X: float32(screenWidth/2 - buttonWidth/2), + Y: float32(startY + (buttonHeight+buttonSpacing)*2), + Width: float32(buttonWidth), + Height: float32(buttonHeight), + }, + Text: "Japanese", + Color: rl.LightGray, + Scale: 1.0, + Action: ScreenJapanese, + } + + buttons := []*Button{&thaiBtn, &koreanBtn, &japaneseBtn} + + // Current screen state + currentScreen := ScreenMenu + prevScreen := ScreenMenu + + // Main game loop + for !rl.WindowShouldClose() { + // Get mouse position + mousePos := rl.GetMousePosition() + + // Handle screen transitions + if currentScreen != prevScreen { + // Reset button states when changing screens + for _, btn := range buttons { + btn.Clicked = false + btn.Scale = 1.0 + } + prevScreen = currentScreen + } + + // Update button states and handle clicks + for _, btn := range buttons { + btn.Hovered = rl.CheckCollisionPointRec(mousePos, btn.Bounds) + + // Handle click animation + if btn.Clicked { + btn.Scale += 0.05 + if btn.Scale >= 1.1 { + btn.Clicked = false + } + } else if btn.Scale > 1.0 { + btn.Scale -= 0.05 + if btn.Scale < 1.0 { + btn.Scale = 1.0 + } + } else { + btn.Scale = 1.0 + } + + // Handle click - only on menu screen + if currentScreen == ScreenMenu && btn.Hovered && rl.IsMouseButtonPressed(rl.MouseLeftButton) { + btn.Clicked = true + btn.Scale = 0.95 + currentScreen = btn.Action + } + } + + // Begin drawing + rl.BeginDrawing() + + // Clear background + rl.ClearBackground(rl.RayWhite) + + // Draw appropriate screen + switch currentScreen { + case ScreenMenu: + // Draw title + rl.DrawText("Main Menu", int32(screenWidth/2)-50, startY-60, 30, rl.Black) + + // Draw buttons + for _, btn := range buttons { + // Calculate scaled bounds for animation + scaledWidth := btn.Bounds.Width * btn.Scale + scaledHeight := btn.Bounds.Height * btn.Scale + scaledX := btn.Bounds.X - (scaledWidth-btn.Bounds.Width)/2 + scaledY := btn.Bounds.Y - (scaledHeight-btn.Bounds.Height)/2 + + // Draw button with animation + if btn.Hovered { + rl.DrawRectangleRec(rl.Rectangle{X: scaledX, Y: scaledY, Width: scaledWidth, Height: scaledHeight}, rl.DarkGray) + } else { + rl.DrawRectangleRec(rl.Rectangle{X: scaledX, Y: scaledY, Width: scaledWidth, Height: scaledHeight}, btn.Color) + } + rl.DrawRectangleLinesEx(rl.Rectangle{X: scaledX, Y: scaledY, Width: scaledWidth, Height: scaledHeight}, 2, rl.Black) + + // Draw text + textWidth := rl.MeasureText(btn.Text, 20) + textX := int32(scaledX) + int32(scaledWidth)/2 - textWidth/2 + textY := int32(scaledY) + int32(scaledHeight)/2 - 10 + rl.DrawText(btn.Text, textX, textY, 20, rl.Black) + } + + case ScreenThai: + rl.DrawText("Thai Language Screen", screenWidth/2-100, screenHeight/2-20, 30, rl.Red) + rl.DrawText("Press ESC to return to menu", screenWidth/2-120, screenHeight/2+30, 20, rl.Black) + if rl.IsKeyPressed(rl.KeyEscape) { + currentScreen = ScreenMenu + } + + case ScreenKorean: + rl.DrawText("Korean Language Screen", screenWidth/2-120, screenHeight/2-20, 30, rl.Blue) + rl.DrawText("Press ESC to return to menu", screenWidth/2-120, screenHeight/2+30, 20, rl.Black) + if rl.IsKeyPressed(rl.KeyEscape) { + currentScreen = ScreenMenu + } + + case ScreenJapanese: + rl.DrawText("Japanese Language Screen", screenWidth/2-140, screenHeight/2-20, 30, rl.Green) + rl.DrawText("Press ESC to return to menu", screenWidth/2-120, screenHeight/2+30, 20, rl.Black) + if rl.IsKeyPressed(rl.KeyEscape) { + currentScreen = ScreenMenu + } + } + + // Draw FPS counter + rl.DrawFPS(10, 10) + + // End drawing + rl.EndDrawing() + } +} + +// Required for raylib-go on some platforms +func init() { + runtime.LockOSThread() +}