From 4a103c8bdf8b3073ca34db604d2ef81eb4e5eafe Mon Sep 17 00:00:00 2001 From: magavel <57044229+magavel@users.noreply.github.com> Date: Mon, 22 Sep 2025 22:19:18 +0900 Subject: [PATCH 1/6] feat: support dark theme --- view/components/button.go | 6 +++--- view/renderer.go | 8 +++----- view/screens/game.go | 7 +++++-- view/screens/result.go | 18 +++++++++--------- view/screens/title.go | 16 ++++++++-------- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/view/components/button.go b/view/components/button.go index 7d8a28e..57ca882 100644 --- a/view/components/button.go +++ b/view/components/button.go @@ -55,10 +55,10 @@ func DrawRoundedButton(screen *ebiten.Image, content string, x, y, w, h int) { radius = 30 // 最大半径30px } - // Button body - 黒背景(ホバー時はグレー) - buttonColor := color.RGBA{0, 0, 0, 255} // 黒 + // Button body - Goブランドカラー背景(ホバー時は少し暗く) + buttonColor := color.RGBA{0, 173, 216, 255} // #00ADD8 (Goブランドカラー) if isHover { - buttonColor = color.RGBA{50, 50, 50, 255} // ダークグレー + buttonColor = color.RGBA{0, 153, 194, 255} // #0099C2 (少し暗め) } // 角丸のボタンを描画 diff --git a/view/renderer.go b/view/renderer.go index f654ab3..f5026d2 100644 --- a/view/renderer.go +++ b/view/renderer.go @@ -1,8 +1,6 @@ package view import ( - "image/color" - "github.com/hajimehoshi/ebiten/v2" "github.com/snkrdunk/find-gopher/internal/font" "github.com/snkrdunk/find-gopher/service" @@ -29,11 +27,11 @@ func (r *Renderer) Draw(screen *ebiten.Image) { screens.DrawTitleScreen(screen, r.game) case service.StateGame: - // Game background color (white) - screen.Fill(color.RGBA{255, 255, 255, 255}) + // 先に背景とUIを描画 + screens.DrawGameScreen(screen, r.game) + // その後にGopherとエフェクトを描画 DrawGophers(screen, r.game.Gophers) components.DrawEffects(screen, r.game.EffectManager.GetAll()) - screens.DrawGameScreen(screen, r.game) case service.StateResult: screens.DrawResultScreen(screen, r.game) diff --git a/view/screens/game.go b/view/screens/game.go index cdcbfe4..949407a 100644 --- a/view/screens/game.go +++ b/view/screens/game.go @@ -13,12 +13,15 @@ import ( // DrawGameScreen はゲーム画面を描画します func DrawGameScreen(screen *ebiten.Image, game *service.Game) { + // ダークグレー背景 + screen.Fill(color.RGBA{50, 50, 50, 255}) + // ゲームコンテナ(枠)を描画 drawGameContainer(screen, game) // タイマー表示を中央上部に配置(960x540画面に適合) timerText := fmt.Sprintf("残り時間%.1f秒", game.TimeLeft) - timerColor := color.RGBA{0, 0, 0, 255} // デフォルトは黒 + timerColor := color.RGBA{255, 255, 255, 255} // デフォルトは白 if game.EffectManager.HasTimerRedEffect() { timerColor = color.RGBA{255, 0, 0, 255} // 赤文字エフェクト中は赤 } @@ -43,7 +46,7 @@ func drawGameContainer(screen *ebiten.Image, game *service.Game) { ) // エフェクト状態に応じて枠色を決定 - borderColor := color.RGBA{0, 0, 0, 255} // デフォルトは黒 + borderColor := color.RGBA{255, 255, 255, 255} // デフォルトは白 if game.EffectManager.HasSuccessEffect() { borderColor = color.RGBA{0, 255, 0, 255} // 成功時は緑 } else if game.EffectManager.HasPenaltyEffect() { diff --git a/view/screens/result.go b/view/screens/result.go index a2d86e7..0f9bd28 100644 --- a/view/screens/result.go +++ b/view/screens/result.go @@ -72,8 +72,8 @@ func DrawResultScreen(screen *ebiten.Image, game *service.Game) { // drawSuccessScreen は成功時の画面を描画します func drawSuccessScreen(screen *ebiten.Image, game *service.Game) { - // 白背景 - screen.Fill(color.White) + // ダークグレー背景 + screen.Fill(color.RGBA{50, 50, 50, 255}) // 背景Gopherの初期化と更新 if !backgroundInitialized { @@ -85,13 +85,13 @@ func drawSuccessScreen(screen *ebiten.Image, game *service.Game) { drawBackgroundGophers(screen) // タイトル「ゲームクリア!」 - font.DrawCenteredJapaneseText(screen, "ゲームクリア!", service.ScreenWidth/2, successTitleY, true, color.Black) + font.DrawCenteredJapaneseText(screen, "ゲームクリア!", service.ScreenWidth/2, successTitleY, true, color.White) // スコア表示(2行) scoreText1 := fmt.Sprintf("スコア:%d", game.Score) scoreText2 := fmt.Sprintf("(残り時間%.1f秒)", float64(game.Score)/1000.0) - font.DrawCenteredJapaneseText(screen, scoreText1, service.ScreenWidth/2, successScoreY, true, color.Black) - font.DrawCenteredJapaneseText(screen, scoreText2, service.ScreenWidth/2, successScoreY+35, false, color.Black) + font.DrawCenteredJapaneseText(screen, scoreText1, service.ScreenWidth/2, successScoreY, true, color.White) + font.DrawCenteredJapaneseText(screen, scoreText2, service.ScreenWidth/2, successScoreY+35, false, color.White) // QRコードの生成と表示 if qrCodeImage == nil || cachedScore != game.Score { @@ -110,7 +110,7 @@ func drawSuccessScreen(screen *ebiten.Image, game *service.Game) { screen.DrawImage(qrCodeImage, op) // QRコード説明テキスト - font.DrawCenteredJapaneseText(screen, "QRコードをスキャンしてXにシェア", service.ScreenWidth/2, successQRDescY, false, color.Black) + font.DrawCenteredJapaneseText(screen, "QRコードをスキャンしてXにシェア", service.ScreenWidth/2, successQRDescY, false, color.White) } // ボタン描画 @@ -119,11 +119,11 @@ func drawSuccessScreen(screen *ebiten.Image, game *service.Game) { // drawFailureScreen は失敗時の画面を描画します func drawFailureScreen(screen *ebiten.Image, game *service.Game) { - // 白背景 - screen.Fill(color.White) + // ダークグレー背景 + screen.Fill(color.RGBA{50, 50, 50, 255}) // タイトル「ざんねん!タイムアップ!」 - font.DrawCenteredJapaneseText(screen, "ざんねん!タイムアップ!", service.ScreenWidth/2, failTitleY, true, color.Black) + font.DrawCenteredJapaneseText(screen, "ざんねん!タイムアップ!", service.ScreenWidth/2, failTitleY, true, color.White) // 中央に大きなWANTED Gopher画像 if service.WantedGopherImage != nil && service.WantedGopherImage.Image != nil { diff --git a/view/screens/title.go b/view/screens/title.go index 3094c8f..25280b7 100644 --- a/view/screens/title.go +++ b/view/screens/title.go @@ -25,12 +25,12 @@ const ( // DrawTitleScreen はタイトル画面を描画します func DrawTitleScreen(screen *ebiten.Image, game *service.Game) { - // 白背景 - vector.DrawFilledRect(screen, 0, 0, float32(service.ScreenWidth), float32(service.ScreenHeight), color.White, false) + // ダークグレー背景 + vector.DrawFilledRect(screen, 0, 0, float32(service.ScreenWidth), float32(service.ScreenHeight), color.RGBA{50, 50, 50, 255}, false) - // Title - "Find Gopher" を黒文字で太く大きく表示 + // Title - "Find Gopher" を白文字で太く大きく表示 titleText := "Find Gopher" - font.DrawCenteredJapaneseTextWithSize(screen, titleText, service.ScreenWidth/2, 25, "title", color.Black) + font.DrawCenteredJapaneseTextWithSize(screen, titleText, service.ScreenWidth/2, 25, "title", color.White) // Gopher画像を中央に表示 if service.NormalGopherImage != nil { @@ -56,15 +56,15 @@ func DrawTitleScreen(screen *ebiten.Image, game *service.Game) { // "あそびかた" セクション howToY := 370 - // Section title - 黒文字で中サイズ、左寄せ + // Section title - 白文字で中サイズ、左寄せ howToTitle := "あそびかた" titleMarginLeft := 100.0 listMarginLeft := 130.0 // リストを段落下げ - font.DrawJapaneseTextWithSize(screen, howToTitle, titleMarginLeft, float64(howToY), "medium", color.Black) + font.DrawJapaneseTextWithSize(screen, howToTitle, titleMarginLeft, float64(howToY), "medium", color.White) howToY += 40 - // Rules - 黒文字でリスト表示 + // Rules - 白文字でリスト表示 rules := []string{ "• 制限時間30秒", "• この画面と同じGopherくんをクリックするだけ!", @@ -74,7 +74,7 @@ func DrawTitleScreen(screen *ebiten.Image, game *service.Game) { for _, rule := range rules { // リストを段落下げして表示 - font.DrawJapaneseTextWithSize(screen, rule, listMarginLeft, float64(howToY), "list", color.Black) + font.DrawJapaneseTextWithSize(screen, rule, listMarginLeft, float64(howToY), "list", color.White) howToY += 28 // 行間を調整 } } From 308ccfc76d94561cca312a75d2c61241ac66b3a0 Mon Sep 17 00:00:00 2001 From: magavel <57044229+magavel@users.noreply.github.com> Date: Mon, 22 Sep 2025 22:33:49 +0900 Subject: [PATCH 2/6] feat: enhance game clear result screen --- internal/font/fontutil.go | 48 +++++++++++++++++++++++++++++++++++++++ view/screens/result.go | 20 +++++++++------- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/internal/font/fontutil.go b/internal/font/fontutil.go index 92898af..7077c5c 100644 --- a/internal/font/fontutil.go +++ b/internal/font/fontutil.go @@ -164,3 +164,51 @@ func DrawCenteredJapaneseTextWithSize(screen *ebiten.Image, txt string, centerX, x := centerX - width/2 DrawJapaneseTextWithSize(screen, txt, x, y, fontSize, textColor) } + +// DrawCenteredJapaneseTextWithBackground は背景色付きで中央揃えで日本語テキストを描画します +func DrawCenteredJapaneseTextWithBackground(screen *ebiten.Image, txt string, centerX, y float64, large bool, textColor, backgroundColor color.Color) { + width, height := MeasureJapaneseText(txt, large) + x := centerX - width/2 + + // 背景の描画(パディング付き) + padding := 8.0 + backgroundX := x - padding + backgroundY := y - padding + backgroundWidth := width + padding*2 + backgroundHeight := height + padding*2 + + // 背景矩形を描画 + backgroundImg := ebiten.NewImage(int(backgroundWidth), int(backgroundHeight)) + backgroundImg.Fill(backgroundColor) + + backgroundOp := &ebiten.DrawImageOptions{} + backgroundOp.GeoM.Translate(backgroundX, backgroundY) + screen.DrawImage(backgroundImg, backgroundOp) + + // テキストを描画 + DrawJapaneseText(screen, txt, x, y, large, textColor) +} + +// DrawCenteredJapaneseTextWithSizeAndBackground は指定したサイズで背景色付きで中央揃えで日本語テキストを描画します +func DrawCenteredJapaneseTextWithSizeAndBackground(screen *ebiten.Image, txt string, centerX, y float64, fontSize string, textColor, backgroundColor color.Color) { + width, height := MeasureJapaneseTextWithSize(txt, fontSize) + x := centerX - width/2 + + // 背景の描画(パディング付き) + padding := 8.0 + backgroundX := x - padding + backgroundY := y - padding + backgroundWidth := width + padding*2 + backgroundHeight := height + padding*2 + + // 背景矩形を描画 + backgroundImg := ebiten.NewImage(int(backgroundWidth), int(backgroundHeight)) + backgroundImg.Fill(backgroundColor) + + backgroundOp := &ebiten.DrawImageOptions{} + backgroundOp.GeoM.Translate(backgroundX, backgroundY) + screen.DrawImage(backgroundImg, backgroundOp) + + // テキストを描画 + DrawJapaneseTextWithSize(screen, txt, x, y, fontSize, textColor) +} diff --git a/view/screens/result.go b/view/screens/result.go index 0f9bd28..951cd9a 100644 --- a/view/screens/result.go +++ b/view/screens/result.go @@ -84,13 +84,14 @@ func drawSuccessScreen(screen *ebiten.Image, game *service.Game) { // 背景Gopherを描画 drawBackgroundGophers(screen) - // タイトル「ゲームクリア!」 - font.DrawCenteredJapaneseText(screen, "ゲームクリア!", service.ScreenWidth/2, successTitleY, true, color.White) + // タイトル「ゲームクリア!」(背景色付き) + backgroundColor := color.RGBA{0, 0, 0, 180} + font.DrawCenteredJapaneseTextWithBackground(screen, "ゲームクリア!", service.ScreenWidth/2, successTitleY, true, color.White, backgroundColor) - // スコア表示(2行) + // スコア表示(2行)(背景色付き) scoreText1 := fmt.Sprintf("スコア:%d", game.Score) scoreText2 := fmt.Sprintf("(残り時間%.1f秒)", float64(game.Score)/1000.0) - font.DrawCenteredJapaneseText(screen, scoreText1, service.ScreenWidth/2, successScoreY, true, color.White) + font.DrawCenteredJapaneseTextWithBackground(screen, scoreText1, service.ScreenWidth/2, successScoreY, true, color.White, backgroundColor) font.DrawCenteredJapaneseText(screen, scoreText2, service.ScreenWidth/2, successScoreY+35, false, color.White) // QRコードの生成と表示 @@ -109,8 +110,10 @@ func drawSuccessScreen(screen *ebiten.Image, game *service.Game) { op.GeoM.Translate(float64(qrX), float64(successQRCodeY)) screen.DrawImage(qrCodeImage, op) - // QRコード説明テキスト - font.DrawCenteredJapaneseText(screen, "QRコードをスキャンしてXにシェア", service.ScreenWidth/2, successQRDescY, false, color.White) + // QRコード説明テキスト(点滅・背景色付き) + if int(time.Now().UnixMilli()/500)%2 == 0 { + font.DrawCenteredJapaneseTextWithBackground(screen, "QRコードをスキャンしてXにシェア", service.ScreenWidth/2, successQRDescY, false, color.White, backgroundColor) + } } // ボタン描画 @@ -122,8 +125,9 @@ func drawFailureScreen(screen *ebiten.Image, game *service.Game) { // ダークグレー背景 screen.Fill(color.RGBA{50, 50, 50, 255}) - // タイトル「ざんねん!タイムアップ!」 - font.DrawCenteredJapaneseText(screen, "ざんねん!タイムアップ!", service.ScreenWidth/2, failTitleY, true, color.White) + // タイトル「ざんねん!タイムアップ!」(背景色付き) + backgroundColor := color.RGBA{0, 0, 0, 180} + font.DrawCenteredJapaneseTextWithBackground(screen, "ざんねん!タイムアップ!", service.ScreenWidth/2, failTitleY, true, color.White, backgroundColor) // 中央に大きなWANTED Gopher画像 if service.WantedGopherImage != nil && service.WantedGopherImage.Image != nil { From 1d7f1a140da104ec4d4d3de35fd321e349a1957a Mon Sep 17 00:00:00 2001 From: magavel <57044229+magavel@users.noreply.github.com> Date: Mon, 22 Sep 2025 22:46:03 +0900 Subject: [PATCH 3/6] feat: update GenerateShareURL --- service/share.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/service/share.go b/service/share.go index be62f99..b8c1021 100644 --- a/service/share.go +++ b/service/share.go @@ -3,6 +3,8 @@ package service import ( "fmt" "net/url" + "strconv" + "strings" ) // GenerateShareURL はX(Twitter)のWeb Intent URLを生成します @@ -15,7 +17,7 @@ func GenerateShareURL(score int) string { // スコアがある場合(ゲームクリア) if score > 0 { - text := fmt.Sprintf("ゴーファー一意化スコア: %d点!", score) + text := fmt.Sprintf("Go Conference 2025のブースでFind Gopherに挑戦しました!スコア%s点!", addCommas(score)) params.Add("text", text) } else { // スコアがない場合(タイムアウト) @@ -30,3 +32,30 @@ func GenerateShareURL(score int) string { return baseURL + "?" + params.Encode() } + +// addCommas は数値にカンマ区切りを追加します +func addCommas(num int) string { + str := strconv.Itoa(num) + if len(str) <= 3 { + return str + } + + var result []string + for i, r := range reverse(str) { + if i > 0 && i%3 == 0 { + result = append(result, ",") + } + result = append(result, string(r)) + } + + return reverse(strings.Join(result, "")) +} + +// reverse は文字列を逆順にします +func reverse(s string) string { + runes := []rune(s) + for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { + runes[i], runes[j] = runes[j], runes[i] + } + return string(runes) +} From c89fbea16b9d9fa2dc38b48a2acf5c4a589cb7c0 Mon Sep 17 00:00:00 2001 From: magavel <57044229+magavel@users.noreply.github.com> Date: Tue, 23 Sep 2025 00:34:42 +0900 Subject: [PATCH 4/6] feat: center button text vertically --- internal/font/fontutil.go | 28 ++++++++++++++++++++++++++++ view/components/button.go | 9 ++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/internal/font/fontutil.go b/internal/font/fontutil.go index 7077c5c..d5297d5 100644 --- a/internal/font/fontutil.go +++ b/internal/font/fontutil.go @@ -151,6 +151,34 @@ func MeasureJapaneseTextWithSize(txt string, fontSize string) (width, height flo return } +// GetFontMetrics は指定したフォントサイズのメトリクス情報を取得します +func GetFontMetrics(fontSize string) (ascent, descent float64) { + if japaneseFontFace == nil { + InitFonts() + } + + var font *text.GoTextFace + switch fontSize { + case "title": + font = japaneseFontTitleFace + case "xlarge": + font = japaneseFontXLargeFace + case "medium": + font = japaneseFontMediumFace + case "list": + font = japaneseFontListFace + case "large": + font = japaneseFontLargeFace + default: + font = japaneseFontFace + } + + metrics := font.Metrics() + ascent = metrics.HAscent + descent = metrics.HDescent + return +} + // DrawCenteredJapaneseText は中央揃えで日本語テキストを描画します func DrawCenteredJapaneseText(screen *ebiten.Image, txt string, centerX, y float64, large bool, textColor color.Color) { width, _ := MeasureJapaneseText(txt, large) diff --git a/view/components/button.go b/view/components/button.go index 57ca882..f36229f 100644 --- a/view/components/button.go +++ b/view/components/button.go @@ -74,9 +74,12 @@ func DrawRoundedButton(screen *ebiten.Image, content string, x, y, w, h int) { vector.DrawFilledCircle(screen, float32(x+w)-radius, float32(y+h)-radius, radius, buttonColor, false) // Button text - 白文字で大きめに - textWidth, textHeight := font.MeasureJapaneseTextWithSize(content, "large") + textWidth, _ := font.MeasureJapaneseTextWithSize(content, "large") + ascent, _ := font.GetFontMetrics("large") + contentX := float64(x) + (float64(w)-textWidth)/2 - // ボタンの垂直中央に配置 - contentY := float64(y) + float64(h)/2 - textHeight/3 + // ボタンの垂直中央に配置(上側に微調整) + textCenterY := float64(y) + float64(h)/2 + contentY := textCenterY - ascent*0.6 font.DrawJapaneseTextWithSize(screen, content, contentX, contentY, "large", color.White) } From 2d6a331583626eaeb1a65f753de6e6f48ba49417 Mon Sep 17 00:00:00 2001 From: magavel <57044229+magavel@users.noreply.github.com> Date: Tue, 23 Sep 2025 00:54:08 +0900 Subject: [PATCH 5/6] feat: adjust title screen --- internal/font/fontutil.go | 13 ++++++++++++ view/components/button.go | 44 +++++++++++++++++++++++++++++++++++++++ view/screens/title.go | 6 +++--- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/internal/font/fontutil.go b/internal/font/fontutil.go index d5297d5..091c7b3 100644 --- a/internal/font/fontutil.go +++ b/internal/font/fontutil.go @@ -14,6 +14,7 @@ var ( // 日本語対応フォント japaneseFontFace *text.GoTextFace japaneseFontLargeFace *text.GoTextFace + japaneseFontButtonFace *text.GoTextFace // プレイボタン用(32px) japaneseFontXLargeFace *text.GoTextFace // タイトル用(96px相当) japaneseFontTitleFace *text.GoTextFace // タイトル用太字(64px相当) japaneseFontMediumFace *text.GoTextFace // 見出し用(48px相当) @@ -40,6 +41,12 @@ func InitFonts() { Size: 24, } + // プレイボタン用フォント + japaneseFontButtonFace = &text.GoTextFace{ + Source: fontSource, + Size: 32, + } + // 特大サイズのフォント(タイトル用) japaneseFontXLargeFace = &text.GoTextFace{ Source: fontSource, @@ -100,6 +107,8 @@ func DrawJapaneseTextWithSize(screen *ebiten.Image, txt string, x, y float64, fo font = japaneseFontListFace case "large": font = japaneseFontLargeFace + case "button": + font = japaneseFontButtonFace default: font = japaneseFontFace } @@ -143,6 +152,8 @@ func MeasureJapaneseTextWithSize(txt string, fontSize string) (width, height flo font = japaneseFontListFace case "large": font = japaneseFontLargeFace + case "button": + font = japaneseFontButtonFace default: font = japaneseFontFace } @@ -169,6 +180,8 @@ func GetFontMetrics(fontSize string) (ascent, descent float64) { font = japaneseFontListFace case "large": font = japaneseFontLargeFace + case "button": + font = japaneseFontButtonFace default: font = japaneseFontFace } diff --git a/view/components/button.go b/view/components/button.go index f36229f..11e8778 100644 --- a/view/components/button.go +++ b/view/components/button.go @@ -83,3 +83,47 @@ func DrawRoundedButton(screen *ebiten.Image, content string, x, y, w, h int) { contentY := textCenterY - ascent*0.6 font.DrawJapaneseTextWithSize(screen, content, contentX, contentY, "large", color.White) } + +// DrawRoundedButtonWithFontSize は指定したフォントサイズで丸みを帯びたボタンを描画します +// x, y: ボタンの左上座標 +// w, h: ボタンの幅と高さ +// fontSize: フォントサイズタイプ +func DrawRoundedButtonWithFontSize(screen *ebiten.Image, content string, x, y, w, h int, fontSize string) { + // Mouse hover detection + mx, my := ebiten.CursorPosition() + isHover := mx >= x && mx <= x+w && my >= y && my <= y+h + + // 角丸の半径 + radius := float32(h / 2) // ボタンの高さの半分を角丸の半径に + if radius > 30 { + radius = 30 // 最大半径30px + } + + // Button body - Goブランドカラー背景(ホバー時は少し暗く) + buttonColor := color.RGBA{0, 173, 216, 255} // #00ADD8 (Goブランドカラー) + if isHover { + buttonColor = color.RGBA{0, 153, 194, 255} // #0099C2 (少し暗め) + } + + // 角丸のボタンを描画 + // 中央の長方形 + vector.DrawFilledRect(screen, float32(x)+radius, float32(y), float32(w)-2*radius, float32(h), buttonColor, false) + // 左右の長方形 + vector.DrawFilledRect(screen, float32(x), float32(y)+radius, radius, float32(h)-2*radius, buttonColor, false) + vector.DrawFilledRect(screen, float32(x+w)-radius, float32(y)+radius, radius, float32(h)-2*radius, buttonColor, false) + // 角の円(簡易的に円で代替) + vector.DrawFilledCircle(screen, float32(x)+radius, float32(y)+radius, radius, buttonColor, false) + vector.DrawFilledCircle(screen, float32(x+w)-radius, float32(y)+radius, radius, buttonColor, false) + vector.DrawFilledCircle(screen, float32(x)+radius, float32(y+h)-radius, radius, buttonColor, false) + vector.DrawFilledCircle(screen, float32(x+w)-radius, float32(y+h)-radius, radius, buttonColor, false) + + // Button text - 白文字で指定のフォントサイズ + textWidth, _ := font.MeasureJapaneseTextWithSize(content, fontSize) + ascent, _ := font.GetFontMetrics(fontSize) + + contentX := float64(x) + (float64(w)-textWidth)/2 + // ボタンの垂直中央に配置(上側に微調整) + textCenterY := float64(y) + float64(h)/2 + contentY := textCenterY - ascent*0.6 + font.DrawJapaneseTextWithSize(screen, content, contentX, contentY, fontSize, color.White) +} diff --git a/view/screens/title.go b/view/screens/title.go index 25280b7..04d316d 100644 --- a/view/screens/title.go +++ b/view/screens/title.go @@ -44,13 +44,13 @@ func DrawTitleScreen(screen *ebiten.Image, game *service.Game) { screen.DrawImage(service.NormalGopherImage.Image, op) } - // プレイボタンを描画(黒背景、白文字、角丸) - components.DrawRoundedButton(screen, "プレイする", playButtonX, playButtonY, playButtonWidth, playButtonHeight) + // プレイボタンを描画(黒背景、白文字、角丸、32pxフォント) + components.DrawRoundedButtonWithFontSize(screen, "プレイする", playButtonX, playButtonY, playButtonWidth, playButtonHeight, "button") // 点滅メッセージ(プレイボタンの下) if int(time.Now().UnixMilli()/500)%2 == 0 { hintText := "プレイボタンをクリックしてスタート!" - font.DrawCenteredJapaneseTextWithSize(screen, hintText, service.ScreenWidth/2, float64(playButtonY+playButtonHeight+5), "list", color.RGBA{0, 150, 0, 255}) + font.DrawCenteredJapaneseTextWithSize(screen, hintText, service.ScreenWidth/2, float64(playButtonY+playButtonHeight+5), "list", color.RGBA{0, 255, 0, 255}) } // "あそびかた" セクション From d7675891de6faecbc7ec8254483ee28188366b39 Mon Sep 17 00:00:00 2001 From: magavel <57044229+magavel@users.noreply.github.com> Date: Tue, 23 Sep 2025 01:06:59 +0900 Subject: [PATCH 6/6] feat: add emoji --- service/share.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/share.go b/service/share.go index b8c1021..a6b5bab 100644 --- a/service/share.go +++ b/service/share.go @@ -17,7 +17,7 @@ func GenerateShareURL(score int) string { // スコアがある場合(ゲームクリア) if score > 0 { - text := fmt.Sprintf("Go Conference 2025のブースでFind Gopherに挑戦しました!スコア%s点!", addCommas(score)) + text := fmt.Sprintf("Go Conference 2025のブースでFind Gopherに挑戦しました!スコア%s点✅", addCommas(score)) params.Add("text", text) } else { // スコアがない場合(タイムアウト)