package main import ( "bytes" "image" "log" _ "embed" "image/color" _ "image/png" "github.com/hajimehoshi/ebiten/v2" ) var ( flyeyeImage *ebiten.Image flyeyeImage2 *ebiten.Image flyeyeImage3 *ebiten.Image shadow *ebiten.Image //go:embed fly-eye.png flyeye_img []byte //go:embed fly-eye2.png flyeye_img2 []byte //go:embed fly-eye3.png flyeye_img3 []byte //go:embed shadow.png shadow_img []byte ) const ( MoverActionDefault = iota MoverActionDamaged MoverActionDying MoverActionExploding MoverActionDead MoverActionMax ) type MoverAction uint func init() { img, _, err := image.Decode(bytes.NewReader(flyeye_img)) if err != nil { log.Fatal(err) } flyeyeImage = ebiten.NewImageFromImage(img) img, _, err = image.Decode(bytes.NewReader(flyeye_img2)) if err != nil { log.Fatal(err) } flyeyeImage2 = ebiten.NewImageFromImage(img) img, _, err = image.Decode(bytes.NewReader(flyeye_img3)) if err != nil { log.Fatal(err) } flyeyeImage3 = ebiten.NewImageFromImage(img) img, _, err = image.Decode(bytes.NewReader(shadow_img)) if err != nil { log.Fatal(err) } shadow = ebiten.NewImageFromImage(img) } type Mover struct { Sprite *ebiten.Image Maks *ebiten.Image MaksDest *ebiten.Image Angle float64 Pos Coordinates Origin Coordinates Action MoverAction cycles int rotating bool Toggled bool Hit bool Touched bool dyingcount int } func NewMover() *Mover { m := &Mover{ Sprite: ebiten.NewImage(MOVER_WIDTH, MOVER_HEIGHT), Maks: ebiten.NewImage(MOVER_WIDTH, MOVER_HEIGHT), MaksDest: ebiten.NewImage(MOVER_WIDTH, MOVER_HEIGHT), Action: MoverActionDefault, cycles: 4, Angle: 0, rotating: false, Toggled: false, dyingcount: 0, } m.Maks.Fill(color.White) return m } func (m *Mover) ToggleRotate() { m.rotating = !m.rotating } func (m *Mover) SetAngle(a float64) { m.Angle = a } func (m *Mover) SetOrigin(coords Coordinates) { m.Origin = coords m.Pos = coords } func (m *Mover) Draw() { m.Sprite.Clear() m.MaksDest.Clear() idx := (m.cycles / 8) % 4 y0 := 0 y1 := 48 x0 := 48 * idx x1 := x0 + 48 switch m.Action { case MoverActionDefault: op := &ebiten.DrawImageOptions{} op.GeoM.Translate(14, 40) m.Sprite.DrawImage(shadow, op) m.Sprite.DrawImage(flyeyeImage.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) case MoverActionDamaged: op := &ebiten.DrawImageOptions{} op.GeoM.Translate(14, 40) m.Sprite.DrawImage(shadow, op) m.Sprite.DrawImage(flyeyeImage2.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) case MoverActionDying: if (m.cycles/5)%2 == 0 { m.MaksDest.DrawImage(flyeyeImage2.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) op := &ebiten.DrawImageOptions{} op.GeoM.Reset() op.Blend = ebiten.BlendSourceAtop m.MaksDest.DrawImage(m.Maks, op) m.Sprite.DrawImage(m.MaksDest, nil) } else { m.Sprite.DrawImage(flyeyeImage2.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) } if m.dyingcount >= 31 { m.cycles = 0 m.SetHit() } case MoverActionExploding: m.Sprite.DrawImage(flyeyeImage3.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) if idx == 3 { m.SetHit() } default: } } func (m *Mover) Update() { /* dx := 0. //40 * math.Cos(float64(m.cycles)/16) dy := 0. //40 * math.Sin(float64(m.cycles)/16) m.Pos = Coordinates{X: m.Origin.X + dx, Y: m.Origin.Y + dy} */ /* if m.rotating { m.Angle = float64(m.cycles) / (math.Pi * 2) } */ if m.Action == MoverActionDying { m.dyingcount++ } m.cycles++ } func (m *Mover) SetHit() { m.Action++ // = (m.Action + 1) % MoverActionMax } func (m *Mover) ToggleColor() { //m.Toggled = !m.Toggled if m.Action == MoverActionDefault { m.Action = MoverActionDamaged } else if m.Action == MoverActionDamaged { m.Action = MoverActionDefault } }