Refactor to use better interfaces and event callbacks.

This commit is contained in:
2024-11-15 16:11:45 -05:00
parent 4ced75d66c
commit cbc4ba5eb3
16 changed files with 1009 additions and 14 deletions

View File

@@ -16,6 +16,8 @@ type Boss struct {
Spawned bool
Pos gamedata.Coordinates
Right bool
Health int
Touched bool
damage bool
cycle int
Action MoverAction
@@ -32,6 +34,8 @@ func NewBoss() *Boss {
hitcount: 0,
Maks: ebiten.NewImage(96, 96),
MaskDest: ebiten.NewImage(96, 96),
Health: 100,
Touched: false,
}
b.Maks.Fill(color.White)
return b
@@ -45,6 +49,9 @@ func (b *Boss) Update() {
b.damageduration = 0
}
}
if b.Action == MoverActionDead {
b.Spawned = false
}
b.cycle++
}
@@ -71,15 +78,17 @@ func (b *Boss) Draw() {
switch b.Action {
case MoverActionDefault:
b.Sprite.DrawImage(assets.ImageBank[assets.Worm].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), op)
case MoverActionDamaged:
if (b.cycle/5)%2 == 0 && b.damage {
b.MaskDest.DrawImage(assets.ImageBank[assets.Worm].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), op)
b.MaskDest.DrawImage(assets.ImageBank[assets.WormDamaged].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), op)
op := &ebiten.DrawImageOptions{}
op.GeoM.Reset()
op.Blend = ebiten.BlendSourceAtop
b.MaskDest.DrawImage(b.Maks, op)
b.Sprite.DrawImage(b.MaskDest, nil)
} else {
b.Sprite.DrawImage(assets.ImageBank[assets.Worm].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), op)
b.Sprite.DrawImage(assets.ImageBank[assets.WormDamaged].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), op)
}
case MoverActionExploding:
op.GeoM.Scale(2, 2)
@@ -95,7 +104,9 @@ func (b *Boss) Draw() {
func (b *Boss) SetHit() {
b.hitcount++
b.damage = true
if b.hitcount > 10 {
b.Health--
if b.Health <= 0 {
b.Action = MoverActionExploding
b.cycle = 0
}
@@ -107,4 +118,13 @@ func (b *Boss) Reset() {
b.damageduration = 0
b.Action = MoverActionDefault
b.Spawned = false
b.Health = 100
}
func (b *Boss) ToggleColor() {
if b.Action == MoverActionDefault {
b.Action = MoverActionDamaged
} else if b.Action == MoverActionDamaged {
b.Action = MoverActionDefault
}
}

23
elements/enemies.go Normal file
View File

@@ -0,0 +1,23 @@
package elements
import (
"mover/gamedata"
"github.com/hajimehoshi/ebiten/v2"
)
type Enemies interface {
Update() error
Draw()
GetPosition() gamedata.Coordinates
SetPosition(gamedata.Coordinates)
SetTarget(gamedata.Coordinates)
GetSprite() *ebiten.Image
GetEnemyState() gamedata.EnemyState
SetHit()
SetToggle()
IsToggled() bool
SetTouched()
ClearTouched()
IsTouched() bool
}

153
elements/flyeye.go Normal file
View File

@@ -0,0 +1,153 @@
package elements
import (
"image"
"image/color"
"math"
"mover/assets"
"mover/gamedata"
"github.com/hajimehoshi/ebiten/v2"
)
type FlyEye struct {
Sprite *ebiten.Image
Maks *ebiten.Image
MaksDest *ebiten.Image
position gamedata.Coordinates
target gamedata.Coordinates
state gamedata.EnemyState
cycle int
dyingcount int
hit bool
touched bool
toggle bool
}
func NewFlyEye() *FlyEye {
f := &FlyEye{
Sprite: ebiten.NewImage(46, 46),
Maks: ebiten.NewImage(48, 48),
MaksDest: ebiten.NewImage(48, 48),
cycle: 0,
dyingcount: 0,
hit: false,
touched: false,
toggle: false,
}
f.Maks.Fill(color.White)
return f
}
func (f *FlyEye) Update() error {
//close loop on target
if f.state <= gamedata.EnemyStateHit {
dx := f.target.X - f.position.X
dy := f.target.Y - f.position.Y
if math.Abs(dx) > 3 || math.Abs(dy) > 3 {
angle := math.Atan2(dy, dx)
f.position.X += math.Cos(angle) * 3
f.position.Y += math.Sin(angle) * 3
}
}
if f.state == gamedata.EnemyStateDying {
f.dyingcount++
}
f.cycle++
return nil
}
func (f *FlyEye) Draw() {
f.Sprite.Clear()
f.MaksDest.Clear()
idx := (f.cycle / 8) % 4
y0 := 0
y1 := 48
x0 := 48 * idx
x1 := x0 + 48
switch f.state {
case gamedata.EnemyStateDefault:
if !f.toggle {
f.Sprite.DrawImage(assets.ImageBank[assets.FlyEyeNormal].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
} else {
f.Sprite.DrawImage(assets.ImageBank[assets.FlyEyeDamaged].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
}
case gamedata.EnemyStateDying:
//after some condition, set to exploding
if (f.cycle/5)%2 == 0 {
f.MaksDest.DrawImage(assets.ImageBank[assets.FlyEyeDamaged].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
op := &ebiten.DrawImageOptions{}
op.GeoM.Reset()
op.Blend = ebiten.BlendSourceAtop
f.MaksDest.DrawImage(f.Maks, op)
f.Sprite.DrawImage(f.MaksDest, nil)
} else {
f.Sprite.DrawImage(assets.ImageBank[assets.FlyEyeDamaged].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
}
if f.dyingcount >= 31 {
f.cycle = 0
f.state = gamedata.EnemyStateExploding
}
case gamedata.EnemyStateExploding:
f.Sprite.DrawImage(assets.ImageBank[assets.FlyEyeDying].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
if idx == 3 {
f.state = gamedata.EnemyStateDead
}
}
}
func (f *FlyEye) GetPosition() gamedata.Coordinates {
return f.position
}
func (f *FlyEye) SetTarget(p gamedata.Coordinates) {
f.target = p
}
func (f *FlyEye) GetSprite() *ebiten.Image {
return f.Sprite
}
func (f *FlyEye) SetHit() {
f.hit = true
f.state = gamedata.EnemyStateDying
f.cycle = 0
}
func (f *FlyEye) IsTouched() bool {
return f.touched
}
func (f *FlyEye) SetTouched() {
f.touched = true
}
func (f *FlyEye) ClearTouched() {
f.touched = false
}
func (f *FlyEye) SetToggle() {
f.toggle = !f.toggle
}
func (f *FlyEye) IsToggled() bool {
return f.toggle
}
func (f *FlyEye) GetEnemyState() gamedata.EnemyState {
return f.state
}
func (f *FlyEye) SetPosition(p gamedata.Coordinates) {
f.position = p
}

View File

@@ -114,7 +114,7 @@ func (m *Mover) Draw() {
}
}
func (m *Mover) Update() {
func (m *Mover) Update() error {
/*
dx := 0. //40 * math.Cos(float64(m.cycles)/16)
dy := 0. //40 * math.Sin(float64(m.cycles)/16)
@@ -130,6 +130,7 @@ func (m *Mover) Update() {
m.dyingcount++
}
m.cycles++
return nil
}
func (m *Mover) SetHit() {