From 9e4be870f0ba451a1ef397db336e52997f4c7a9e Mon Sep 17 00:00:00 2001 From: pankona Date: Fri, 28 Jun 2024 14:26:16 +0000 Subject: [PATCH 1/3] place ready button in build menu --- buildpane.go | 42 ------------------------------------------ house.go | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 42 deletions(-) diff --git a/buildpane.go b/buildpane.go index 001f9d3..9de5114 100644 --- a/buildpane.go +++ b/buildpane.go @@ -1,8 +1,6 @@ package main import ( - "log" - "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/ebitenutil" @@ -109,11 +107,8 @@ func newBuildPane(game *Game) *buildPane { ebitenutil.DebugPrintAt(screen, "Cancel", x+width/2-20, y+height/2-8) }) - readyButton := newReadyButton(game) - game.clickHandler.Add(okButton) game.clickHandler.Add(cancelButton) - game.clickHandler.Add(readyButton) return &buildPane{ game: game, @@ -126,14 +121,12 @@ func newBuildPane(game *Game) *buildPane { okButton: okButton, cancelButton: cancelButton, - readyButton: readyButton, } } func (a *buildPane) Draw(screen *ebiten.Image) { a.okButton.Draw(screen) a.cancelButton.Draw(screen) - a.readyButton.Draw(screen) } // buildPane implement Clickable interface @@ -163,41 +156,6 @@ func (a *buildPane) ZIndex() int { return a.zindex } -func newReadyButton(g *Game) *Button { - width, height := 100, 40 - x := screenWidth - width - 12 - y := eScreenHeight - height - 20 - - return newButton(g, x, y, width, height, 110, - func(x, y int) bool { - // 現在のフェーズによって処理を変える - // 建築フェーズの場合はウェーブフェーズに遷移する - // - buildpane を取り去る - // - atkpane を追加する - // ウェーブフェーズの場合は建築フェーズに遷移する - // - atkpane を取り去る - // - buildpane を追加する - - getAudioPlayer().play(soundKettei) - - switch g.phase { - case PhaseBuilding: - g.SetWavePhase() - case PhaseWave: - g.SetBuildingPhase() - default: - log.Fatalf("unexpected phase: %v", g.phase) - } - - return false - }, - func(screen *ebiten.Image, x, y, width, height int) { - // ボタンの枠を描く(白) - drawRect(screen, x, y, width, height) - ebitenutil.DebugPrintAt(screen, "READY", x+width/2-15, y+height/2-7) - }) -} - // ウェーブフェーズに繊維するとき、建築フェーズのパネルを取り去る // このとき、ClickHandler や DrawHandler に入れたボタンも取り去る func (p *buildPane) RemoveAll() { diff --git a/house.go b/house.go index 5d5281d..b8b9a3a 100644 --- a/house.go +++ b/house.go @@ -303,6 +303,32 @@ func (h *house) OnClick(x, y int) bool { }) h.game.infoPanel.AddButton(buildRadioTowerButton) + nextWaveStartButton := newButton(h.game, + screenWidth-10-infoPanelHeight, eScreenHeight, infoPanelHeight, infoPanelHeight, 1, + func(x, y int) bool { + getAudioPlayer().play(soundKettei) + + switch h.game.phase { + case PhaseBuilding: + h.game.SetWavePhase() + case PhaseWave: + h.game.SetBuildingPhase() + default: + log.Fatalf("unexpected phase: %v", h.game.phase) + } + + return false + }, + func(screen *ebiten.Image, x, y, width, height int) { + drawRect(screen, x, y, width, height) + ebitenutil.DebugPrintAt(screen, "FINISH BUILDING!", x+width/2-45, y+height/2-40) + ebitenutil.DebugPrintAt(screen, "START NEXT WAVE!", x+width/2-45, y+height/2-8) + // 現在のウェーブとトータルウェーブ数を表示する + ebitenutil.DebugPrintAt(screen, fmt.Sprintf("CURRENT WAVE: %d/%d", h.game.waveCtrl.currentBigWave, len(waveList)), x+width/2-52, y+height/2+32) + }, + ) + h.game.infoPanel.AddButton(nextWaveStartButton) + case PhaseWave: // TODO: implement default: From 45c7f59596ac3bf8f2efb48bad97494a1ac53a70 Mon Sep 17 00:00:00 2001 From: pankona Date: Fri, 28 Jun 2024 15:08:20 +0000 Subject: [PATCH 2/3] add more instructions --- buildpane.go | 6 +++--- house.go | 15 ++++++++++++++- main.go | 24 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/buildpane.go b/buildpane.go index 9de5114..ba6ba45 100644 --- a/buildpane.go +++ b/buildpane.go @@ -23,7 +23,7 @@ type buildPane struct { } func newBuildPane(game *Game) *buildPane { - okButton := newButton(game, screenWidth-200-22, eScreenHeight-130, 100, 50, 110, + okButton := newButton(game, screenWidth-200-22, eScreenHeight-80, 100, 50, 110, func(x, y int) bool { if game.buildCandidate == nil { return true @@ -70,10 +70,10 @@ func newBuildPane(game *Game) *buildPane { } else { drawRect(screen, x, y, width, height) } - ebitenutil.DebugPrintAt(screen, "OK", x+width/2-10, y+height/2-8) + ebitenutil.DebugPrintAt(screen, "BUILD IT!", x+width/2-25, y+height/2-8) }) - cancelButton := newButton(game, screenWidth-100-12, eScreenHeight-130, 100, 50, 110, + cancelButton := newButton(game, screenWidth-100-12, eScreenHeight-80, 100, 50, 110, func(x, y int) bool { if game.buildCandidate == nil { return true diff --git a/house.go b/house.go index b8b9a3a..7d682d6 100644 --- a/house.go +++ b/house.go @@ -141,6 +141,13 @@ func (h *house) Damage(d int) { // house implements Clickable interface func (h *house) OnClick(x, y int) bool { + + // 建築 instruction を消す + if h.game.buildInstruction != nil { + h.game.drawHandler.Remove(h.game.buildInstruction) + h.game.buildInstruction = nil + } + getAudioPlayer().play(soundChoice) h.game.clickedObject = "House" @@ -310,9 +317,15 @@ func (h *house) OnClick(x, y int) bool { switch h.game.phase { case PhaseBuilding: + // 最初のウェーブだったら攻撃方法に関する説明を表示する + if h.game.waveCtrl.currentBigWave == 0 { + h.game.attackInstruction = newInstruction(h.game, "CLICK BUGS TO ATTACK!", screenWidth/2-60, eScreenHeight/2+50) + h.game.drawHandler.Add(h.game.attackInstruction) + } h.game.SetWavePhase() case PhaseWave: - h.game.SetBuildingPhase() + // never reach + fallthrough default: log.Fatalf("unexpected phase: %v", h.game.phase) } diff --git a/main.go b/main.go index 1a96fbb..63a6cfd 100644 --- a/main.go +++ b/main.go @@ -45,6 +45,12 @@ type Game struct { // ウェーブのコントローラ waveCtrl *waveController + // 最初のウェーブが始まる前に表示するインストラクション + buildInstruction *instruction + + // 攻撃のインストラクション + attackInstruction *instruction + credit int } @@ -219,11 +225,29 @@ func (g *Game) initialize() { // 敵が全滅したらウェーブを終了して建築フェーズに戻る // 敵が全滅したことをコールバックする waveEndFn := func() { + // 最初のウェーブが終了したら攻撃インストラクションを消す + if g.attackInstruction != nil { + g.drawHandler.Remove(g.attackInstruction) + g.attackInstruction = nil + } + + // 建築 instruction を出す + g.buildInstruction = newInstruction(g, "CLICK ME TO OPEN BUILD MENU", screenWidth/2-80, eScreenHeight/2+50) + g.drawHandler.Add(g.buildInstruction) + + // TODO: ウェーブが終わっておめでとう的なことを少しの間だけ表示する + // その後に建築フェーズに移行する + g.SetBuildingPhase() // ウェーブ終了時に一定のクレジットを得る g.credit += 120 } + // インストラクションを表示 + // 家がクリックされたら消える + g.buildInstruction = newInstruction(g, "CLICK ME TO OPEN BUILD MENU", screenWidth/2-80, eScreenHeight/2+50) + g.drawHandler.Add(g.buildInstruction) + g.waveCtrl = newWaveController(g, waveEndFn) } From 55d1cfdb18ae18ec63b36e9085b6532275c0e449 Mon Sep 17 00:00:00 2001 From: pankona Date: Fri, 28 Jun 2024 15:12:33 +0000 Subject: [PATCH 3/3] some margin for clicking the button after game clear or game over --- gameclear.go | 17 +++++++++++++++-- gameover.go | 17 +++++++++++++++-- instruction.go | 41 +++++++++++++++++++++++++++++++++++++++++ wavectl.go | 3 ++- 4 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 instruction.go diff --git a/gameclear.go b/gameclear.go index c09f823..3d6fc6b 100644 --- a/gameclear.go +++ b/gameclear.go @@ -9,18 +9,31 @@ import ( ) type gameclear struct { - game *Game + game *Game + erapsedFrame int // このフレームを経過しないとクリックできないようにする } func newGameClear(g *Game) *gameclear { return &gameclear{ game: g, + // 3秒間はクリックを受け付けない + erapsedFrame: 60 * 3, + } +} + +func (g *gameclear) Update() { + if g.erapsedFrame > 0 { + g.erapsedFrame-- } } func (g *gameclear) OnClick(x, y int) bool { - // ゲームリセットする + // ちょっとの間クリックを受け付けないようにする + if g.erapsedFrame > 0 { + return false + } + // ゲームリセットする g.game.Reset() // ゲームオーバー画面を削除 diff --git a/gameover.go b/gameover.go index 04cb859..1306c06 100644 --- a/gameover.go +++ b/gameover.go @@ -10,17 +10,30 @@ import ( type gameover struct { game *Game + + erapsedFrame int // このフレームを経過しないとクリックできないようにする } func newGameover(g *Game) *gameover { return &gameover{ - game: g, + game: g, + erapsedFrame: 60 * 3, + } +} + +func (g *gameover) Update() { + if g.erapsedFrame > 0 { + g.erapsedFrame-- } } func (g *gameover) OnClick(x, y int) bool { - // ゲームリセットする + // ちょっとの間クリックを受け付けないようにする + if g.erapsedFrame > 0 { + return false + } + // ゲームリセットする g.game.Reset() // ゲームオーバー画面を削除 diff --git a/instruction.go b/instruction.go new file mode 100644 index 0000000..a940a62 --- /dev/null +++ b/instruction.go @@ -0,0 +1,41 @@ +package main + +import ( + "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/ebitenutil" +) + +type instruction struct { + game *Game + + erapsedFrame int + zindex int + + x, y int + text string +} + +func newInstruction(game *Game, text string, x, y int) *instruction { + return &instruction{ + game: game, + + x: x, + y: y, + text: text, + + zindex: 100, + } +} + +func (i *instruction) Draw(screen *ebiten.Image) { + // click me to open build menu と、家の下 (画面中央下) に表示する + // 点滅させる + i.erapsedFrame++ + if i.erapsedFrame%240 < 120 { + ebitenutil.DebugPrintAt(screen, i.text, i.x, i.y) + } +} + +func (i *instruction) ZIndex() int { + return i.zindex +} diff --git a/wavectl.go b/wavectl.go index 8921927..f808d9c 100644 --- a/wavectl.go +++ b/wavectl.go @@ -33,6 +33,7 @@ func (w *waveController) Update() { if w.game.house.health <= 0 { // ゲームオーバーの処理 gover := newGameover(w.game) + w.game.updateHandler.Add(gover) w.game.clickHandler.Add(gover) w.game.drawHandler.Add(gover) @@ -57,9 +58,9 @@ func (w *waveController) Update() { getAudioPlayer().play(soundClear) gclear := newGameClear(w.game) + w.game.updateHandler.Add(gclear) w.game.clickHandler.Add(gclear) w.game.drawHandler.Add(gclear) - } else { // ウェーブ間の処理 // TODO: 必要ならなにか実装する