Skip to content

Commit

Permalink
Merge pull request #39 from pankona/animation-on-building-destroy
Browse files Browse the repository at this point in the history
animation on building destroy
  • Loading branch information
pankona authored Jun 26, 2024
2 parents 01e2081 + f38ce88 commit 88cd318
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 20 deletions.
27 changes: 24 additions & 3 deletions barricade.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ type barricade struct {
// 1以外を指定する場合は元画像のサイズをそもそも変更できないか検討すること
scale float64

// 壊れたときのアニメーションを制御するための変数
deadAnimationDuration int

// health が 0 になったときに呼ばれる関数
onDestroy func(b *barricade)

Expand Down Expand Up @@ -61,14 +64,33 @@ func newBarricade(game *Game, x, y int, onDestroy func(b *barricade)) *barricade
}

func (b *barricade) Update() {
// 何もしない
if b.health <= 0 {
b.deadAnimationDuration++
if b.deadAnimationDuration >= deadAnimationTotalFrame {
b.onDestroy(b)
}
return
}
}

// 画面中央に配置
func (b *barricade) Draw(screen *ebiten.Image) {
// 画像を描画
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Scale(b.scale, b.scale)
if b.health <= 0 {
// 死亡時のアニメーションを行う
// ぺちゃんこになるように縮小する
scale := 1.0 - float64(b.deadAnimationDuration)/deadAnimationTotalFrame
if scale < 0 {
scale = 0
}

opts.GeoM.Translate(0, float64(-b.height))
opts.GeoM.Scale(1, scale)
opts.GeoM.Translate(0, float64(b.height))
} else {
opts.GeoM.Scale(b.scale, b.scale)
}
opts.GeoM.Translate(float64(b.x)-float64(b.width)*b.scale/2, float64(b.y)-float64(b.height)*b.scale/2)

// 他の建物と重なっている場合は赤くする
Expand Down Expand Up @@ -111,7 +133,6 @@ func (b *barricade) Damage(d int) {
b.health -= d
if b.health <= 0 {
b.health = 0
b.onDestroy(b)
}
}

Expand Down
9 changes: 6 additions & 3 deletions bugs.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ const (
bugsGreen
)

const (
deadAnimationTotalFrame = 10
)

func newBug(game *Game, bugColor bugColor, x, y int, onDestroy func(b *bug)) *bug {
img, _, err := image.Decode(bytes.NewReader(bugsImageData))
if err != nil {
Expand Down Expand Up @@ -147,7 +151,7 @@ func greenBug() image.Rectangle {
func (b *bug) Update() {
if b.health <= 0 {
b.deadAnimationDuration++
if b.deadAnimationDuration >= 30 {
if b.deadAnimationDuration >= deadAnimationTotalFrame {
b.onDestroy(b)
}
return
Expand Down Expand Up @@ -598,12 +602,11 @@ func (b *bug) Size() (int, int) {
// 画面中央に配置
func (b *bug) Draw(screen *ebiten.Image) {
// 画像を描画

opts := &ebiten.DrawImageOptions{}
if b.health <= 0 {
// 死亡時のアニメーションを行う
// ぺちゃんこになるように縮小する
scale := 1.0 - float64(b.deadAnimationDuration)/15
scale := 1.0 - float64(b.deadAnimationDuration)/deadAnimationTotalFrame
if scale < 0 {
scale = 0
}
Expand Down
30 changes: 27 additions & 3 deletions house.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ type house struct {

health int

// 死亡時のアニメーションを管理するための変数
deadAnimationDuration int

// 画像の拡大率。
// TODO: 本当は画像のサイズそのものを変更したほうが見た目も処理効率も良くなる。余裕があれば後々やろう。
scale float64
Expand Down Expand Up @@ -57,6 +60,7 @@ func newHouse(game *Game) *house {
// TODO: 爆発したり消えたりする処理を書く
// ここでフラグを設定しといて、Update() や Draw で続きの処理を行うのもあり
// いったんシンプルに消す
h.game.updateHandler.Remove(h)
h.game.RemoveBuilding(h)
h.game.drawHandler.Remove(h)
},
Expand All @@ -69,14 +73,35 @@ func newHouse(game *Game) *house {
}

func (h *house) Update() {
// 何もしない
if h.health <= 0 {
h.deadAnimationDuration++
if h.deadAnimationDuration >= deadAnimationTotalFrame {
h.onDestroy(h)
}
return
}
}

// 画面中央に配置
func (h *house) Draw(screen *ebiten.Image) {
// 画像を描画
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Scale(h.scale, h.scale)
if h.health <= 0 {
// 死亡時のアニメーションを行う
// ぺちゃんこになるように縮小する
// TODO: ちょっとアニメーションが怪しいので調整する
scale := h.scale * (1.0 - float64(h.deadAnimationDuration)/deadAnimationTotalFrame)
if scale < 0 {
scale = 0
}

opts.GeoM.Translate(0, h.scale*float64(-h.height)/2)
opts.GeoM.Scale(h.scale, scale)
opts.GeoM.Translate(0, h.scale*float64(h.height)/2)
} else {
opts.GeoM.Scale(h.scale, h.scale)
}

opts.GeoM.Translate(float64(h.x)-float64(h.width)*h.scale/2, float64(h.y)-float64(h.height)*h.scale/2)
screen.DrawImage(h.image, opts)
}
Expand Down Expand Up @@ -111,7 +136,6 @@ func (h *house) Damage(d int) {
h.health -= d
if h.health <= 0 {
h.health = 0
h.onDestroy(h)
}
}

Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ func (g *Game) initialize() {
// とりあえずいきなりゲームが始まるとする。
// TODO: まずタイトルバックを表示して、その後にゲーム画面に遷移するようにする
g.house = newHouse(g)
g.updateHandler.Add(g.house)
g.drawHandler.Add(g.house)
g.AddBuilding(g.house)
g.clickHandler.Add(g.house)
Expand Down
31 changes: 28 additions & 3 deletions radiotower.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type radioTower struct {
// 1以外を指定する場合は元画像のサイズをそもそも変更できないか検討すること
scale float64

// 死亡時のアニメーションを管理するための変数
deadAnimationDuration int

// health が 0 になったときに呼ばれる関数
onDestroy func(b *radioTower)

Expand Down Expand Up @@ -85,6 +88,15 @@ func (t *radioTower) Update() {
return
}

// 死亡時のアニメーションを再生する
if t.health <= 0 {
t.deadAnimationDuration++
if t.deadAnimationDuration >= deadAnimationTotalFrame {
t.onDestroy(t)
}
return
}

// 敵が攻撃範囲に入ってきたら攻撃する
// 複数の敵が攻撃範囲に入ってきた場合は、最も近い敵を攻撃する
// ただし近すぎる敵には攻撃できない
Expand Down Expand Up @@ -122,7 +134,6 @@ func (t *radioTower) Update() {
}

t.cooldown = radioTowerAttackCoolDown

}

if t.cooldown > 0 {
Expand Down Expand Up @@ -177,7 +188,22 @@ func (b *radioTowerAttackEffect) ZIndex() int {
func (b *radioTower) Draw(screen *ebiten.Image) {
// 画像を描画
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Scale(b.scale, b.scale)

if b.health <= 0 {
// 死亡時のアニメーションを行う
// ぺちゃんこになるように縮小する
scale := 1.0 - float64(b.deadAnimationDuration)/deadAnimationTotalFrame
if scale < 0 {
scale = 0
}

opts.GeoM.Translate(0, float64(-b.height))
opts.GeoM.Scale(1, scale)
opts.GeoM.Translate(0, float64(b.height))
} else {
opts.GeoM.Scale(b.scale, b.scale)
}

opts.GeoM.Translate(float64(b.x)-float64(b.width)*b.scale/2, float64(b.y)-float64(b.height)*b.scale/2)

// 他の建物と重なっている場合は赤くする
Expand Down Expand Up @@ -220,7 +246,6 @@ func (b *radioTower) Damage(d int) {
b.health -= d
if b.health <= 0 {
b.health = 0
b.onDestroy(b)
}
}

Expand Down
35 changes: 33 additions & 2 deletions tower.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ type tower struct {
// 1以外を指定する場合は元画像のサイズをそもそも変更できないか検討すること
scale float64

// 死亡時のアニメーションを管理するための変数
deadAnimationDuration int

// health が 0 になったときに呼ばれる関数
onDestroy func(b *tower)

Expand Down Expand Up @@ -77,6 +80,20 @@ func (t *tower) Update() {
return
}

// 死亡時のアニメーションを再生する
if t.health <= 0 {
t.deadAnimationDuration++
if t.deadAnimationDuration >= deadAnimationTotalFrame {
t.onDestroy(t)
}
return
}

// 家が壊れていたらもはや攻撃をやめる
if t.game.house.health <= 0 {
return
}

// 敵が攻撃範囲に入ってきたら攻撃する
// 複数の敵が攻撃範囲に入ってきた場合は、最も近い敵を攻撃する

Expand Down Expand Up @@ -152,7 +169,22 @@ func (b *beam) ZIndex() int {
func (b *tower) Draw(screen *ebiten.Image) {
// 画像を描画
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Scale(b.scale, b.scale)

if b.health <= 0 {
// 死亡時のアニメーションを行う
// ぺちゃんこになるように縮小する
scale := 1.0 - float64(b.deadAnimationDuration)/deadAnimationTotalFrame
if scale < 0 {
scale = 0
}

opts.GeoM.Translate(0, float64(-b.height))
opts.GeoM.Scale(1, scale)
opts.GeoM.Translate(0, float64(b.height))
} else {
opts.GeoM.Scale(b.scale, b.scale)
}

opts.GeoM.Translate(float64(b.x)-float64(b.width)*b.scale/2, float64(b.y)-float64(b.height)*b.scale/2)

// 他の建物と重なっている場合は赤くする
Expand Down Expand Up @@ -195,7 +227,6 @@ func (b *tower) Damage(d int) {
b.health -= d
if b.health <= 0 {
b.health = 0
b.onDestroy(b)
}
}

Expand Down
6 changes: 0 additions & 6 deletions wavectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ func (w *waveController) Update() {
w.game.clickHandler.Add(gover)
w.game.drawHandler.Add(gover)

// 建物の Update() が呼ばれないようにする
// ゲームオーバー画面で攻撃を続けないようにするため
for _, b := range w.game.buildings {
w.game.updateHandler.Remove(b)
}

// ウェーブ終了みたいなものなので自分を削除する
w.game.updateHandler.Remove(w)
} else if len(w.game.enemies) == 0 {
Expand Down

0 comments on commit 88cd318

Please sign in to comment.