@@ -4,74 +4,71 @@ import (
44 "image/color"
55
66 "github.com/hajimehoshi/ebiten/v2"
7- "github.com/hajimehoshi/ebiten/v2/vector "
7+ es "github.com/kijimaD/ruins/internal/engine/states "
88 w "github.com/kijimaD/ruins/internal/world"
99)
1010
11- // ブラー画像と黒背景のキャッシュ
11+ // ブラー画像と暗転オーバーレイのキャッシュ
1212var (
13- cachedBlurImage * ebiten.Image
14- cachedBlackBackground * ebiten.Image
15- cachedStateCount int
13+ cachedBlurImage * ebiten.Image
14+ cachedDarkOverlay * ebiten.Image
15+ cachedBaseState es. State [w. World ]
1616)
1717
18- // afterDrawHook は各stateのDraw完了後に呼ばれるフック関数
19- func afterDrawHook (stateIndex , stateCount int , _ w.World , screen * ebiten.Image ) error {
20- if cachedStateCount != stateCount {
21- // キャッシュをクリア
18+ // applyBlurOverlay は画面にブラー効果を適用する
19+ // baseStateが変わるとキャッシュを再生成する
20+ func applyBlurOverlay (screen * ebiten.Image , baseState es.State [w.World ]) {
21+ // 下層stateが変わったらキャッシュをクリア
22+ if cachedBaseState != baseState {
2223 cachedBlurImage = nil
23- cachedStateCount = stateCount
24+ cachedBaseState = baseState
2425 }
2526
26- // stateが複数あるとき初回のstate描画後に1回だけブラー効果を適用する
27- if stateCount > 1 && stateIndex == 0 {
28- bounds := screen .Bounds ()
27+ bounds := screen .Bounds ()
2928
30- // キャッシュがない場合のみブラー処理を実行
31- if cachedBlurImage == nil {
32- // 現在の画面をコピー
33- src := ebiten .NewImage (bounds .Dx (), bounds .Dy ())
34- src .DrawImage (screen , nil )
29+ // キャッシュがない場合のみブラー画像を生成する
30+ if cachedBlurImage == nil {
31+ w , h := bounds .Dx (), bounds .Dy ()
3532
36- // ブラー効果を2パス(水平→垂直)で適用
37- // 水平ブラー
38- const blurRadius = 4
39- tmp := ebiten .NewImage (bounds .Dx (), bounds .Dy ())
40- for x := - blurRadius ; x <= blurRadius ; x ++ {
41- op := & ebiten.DrawImageOptions {}
42- op .GeoM .Translate (float64 (x ), 0 )
43- op .ColorScale .ScaleAlpha (1.0 / float32 (blurRadius * 2 + 1 ))
44- op .Blend = ebiten .BlendSourceOver
45- tmp .DrawImage (src , op )
46- }
33+ // 現在の画面をコピーする
34+ src := ebiten .NewImage (w , h )
35+ op := & ebiten.DrawImageOptions {}
36+ op .GeoM .Translate (float64 (- bounds .Min .X ), float64 (- bounds .Min .Y ))
37+ src .DrawImage (screen , op )
4738
48- // 垂直ブラー
49- cachedBlurImage = ebiten .NewImage (bounds .Dx (), bounds .Dy ())
50- for y := - blurRadius ; y <= blurRadius ; y ++ {
51- op := & ebiten.DrawImageOptions {}
52- op .GeoM .Translate (0 , float64 (y ))
53- op .ColorScale .ScaleAlpha (1.0 / float32 (blurRadius * 2 + 1 ))
54- op .Blend = ebiten .BlendSourceOver
55- cachedBlurImage .DrawImage (tmp , op )
56- }
57- }
39+ // ブラー効果を2パス(水平→垂直)で適用する
40+ const blurRadius = 4
41+ kernel := blurRadius * 2 + 1
5842
59- // 黒い背景画像をキャッシュから取得または生成
60- if cachedBlackBackground == nil {
61- cachedBlackBackground = ebiten .NewImage (bounds .Dx (), bounds .Dy ())
62- width := float32 (bounds .Dx ())
63- height := float32 (bounds .Dy ())
64- vector .FillRect (cachedBlackBackground , 0 , 0 , width , height , color.RGBA {0 , 0 , 0 , 255 }, false )
43+ // 水平ブラー
44+ tmp := ebiten .NewImage (bounds .Dx (), bounds .Dy ())
45+ for x := - blurRadius ; x <= blurRadius ; x ++ {
46+ op := & ebiten.DrawImageOptions {}
47+ op .GeoM .Translate (float64 (x ), 0 )
48+ op .ColorScale .Scale (1.0 / float32 (kernel ), 1.0 / float32 (kernel ), 1.0 / float32 (kernel ), 1.0 / float32 (kernel ))
49+ op .Blend = ebiten .BlendLighter
50+ tmp .DrawImage (src , op )
6551 }
6652
67- screen .Clear ()
68-
69- // 黒背景を描画
70- screen .DrawImage (cachedBlackBackground , nil )
53+ // 垂直ブラー
54+ cachedBlurImage = ebiten .NewImage (bounds .Dx (), bounds .Dy ())
55+ for y := - blurRadius ; y <= blurRadius ; y ++ {
56+ op := & ebiten.DrawImageOptions {}
57+ op .GeoM .Translate (0 , float64 (y ))
58+ op .ColorScale .Scale (1.0 / float32 (kernel ), 1.0 / float32 (kernel ), 1.0 / float32 (kernel ), 1.0 / float32 (kernel ))
59+ op .Blend = ebiten .BlendLighter
60+ cachedBlurImage .DrawImage (tmp , op )
61+ }
62+ }
7163
72- // その上にブラー画像を描画
73- screen .DrawImage (cachedBlurImage , nil )
64+ // 黒い半透明オーバーレイをキャッシュから取得または生成する
65+ if cachedDarkOverlay == nil {
66+ cachedDarkOverlay = ebiten .NewImage (bounds .Dx (), bounds .Dy ())
67+ cachedDarkOverlay .Fill (color.RGBA {0 , 0 , 0 , 48 })
7468 }
7569
76- return nil
70+ drawOp := & ebiten.DrawImageOptions {}
71+ drawOp .GeoM .Translate (float64 (bounds .Min .X ), float64 (bounds .Min .Y ))
72+ screen .DrawImage (cachedBlurImage , drawOp )
73+ screen .DrawImage (cachedDarkOverlay , drawOp )
7774}
0 commit comments