New hero sprite, timer and score added, death added, reset added.
This commit is contained in:
BIN
fonts/FFForward.ttf
Normal file
BIN
fonts/FFForward.ttf
Normal file
Binary file not shown.
BIN
fonts/agencyb.ttf
Normal file
BIN
fonts/agencyb.ttf
Normal file
Binary file not shown.
BIN
fonts/arcade_n.ttf
Normal file
BIN
fonts/arcade_n.ttf
Normal file
Binary file not shown.
85
fonts/fonts.go
Normal file
85
fonts/fonts.go
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package fonts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/examples/resources/fonts"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"golang.org/x/image/font/opentype"
|
||||||
|
"golang.org/x/image/font/sfnt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FontDPI = 72
|
||||||
|
FontSizeStandard = 16
|
||||||
|
FontSizeLarge = 24
|
||||||
|
FontSizeBig = 60
|
||||||
|
FontSizeArcade = 12
|
||||||
|
FontSizeArcadeBig = 40
|
||||||
|
FontSizeArcadeHuge = 80
|
||||||
|
)
|
||||||
|
|
||||||
|
type FontStruct struct {
|
||||||
|
Standard font.Face
|
||||||
|
Large font.Face
|
||||||
|
Glitch font.Face
|
||||||
|
GlitchBig font.Face
|
||||||
|
Arcade font.Face
|
||||||
|
ArcadeLarge font.Face
|
||||||
|
ArcadeHuge font.Face
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
//go:embed agencyb.ttf
|
||||||
|
agency_ttf []byte
|
||||||
|
|
||||||
|
//go:embed arcade_n.ttf
|
||||||
|
arcade_ttf []byte
|
||||||
|
|
||||||
|
SurviveFont FontStruct
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadFontFatal(src []byte) *sfnt.Font {
|
||||||
|
tt, err := opentype.Parse(src)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return tt
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFaceFatal(fnt *sfnt.Font, dpi, size float64) font.Face {
|
||||||
|
var face font.Face
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if dpi > 0 && size > 0 && fnt != nil {
|
||||||
|
face, err = opentype.NewFace(fnt, &opentype.FaceOptions{
|
||||||
|
Size: size,
|
||||||
|
DPI: dpi,
|
||||||
|
Hinting: font.HintingVertical,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return face
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
SurviveFont = FontStruct{}
|
||||||
|
|
||||||
|
fnt := LoadFontFatal(fonts.MPlus1pRegular_ttf)
|
||||||
|
SurviveFont.Standard = GetFaceFatal(fnt, FontDPI, FontSizeStandard)
|
||||||
|
SurviveFont.Large = GetFaceFatal(fnt, FontDPI, FontSizeLarge)
|
||||||
|
|
||||||
|
fnt2 := LoadFontFatal(agency_ttf)
|
||||||
|
SurviveFont.Glitch = GetFaceFatal(fnt2, FontDPI, FontSizeLarge)
|
||||||
|
SurviveFont.GlitchBig = GetFaceFatal(fnt2, FontDPI, FontSizeBig)
|
||||||
|
|
||||||
|
fnt3 := LoadFontFatal(arcade_ttf)
|
||||||
|
SurviveFont.Arcade = GetFaceFatal(fnt3, FontDPI, FontSizeArcade)
|
||||||
|
SurviveFont.ArcadeLarge = GetFaceFatal(fnt3, FontDPI, FontSizeArcadeBig)
|
||||||
|
SurviveFont.ArcadeHuge = GetFaceFatal(fnt3, FontDPI, FontSizeArcadeHuge)
|
||||||
|
}
|
||||||
129
game.go
129
game.go
@@ -1,13 +1,16 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
|
"mover/fonts"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/text"
|
||||||
"github.com/hajimehoshi/ebiten/v2/vector"
|
"github.com/hajimehoshi/ebiten/v2/vector"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,14 +22,20 @@ const (
|
|||||||
type Game struct {
|
type Game struct {
|
||||||
collisionMask *ebiten.Image
|
collisionMask *ebiten.Image
|
||||||
projectileMask *ebiten.Image
|
projectileMask *ebiten.Image
|
||||||
|
heroCollisionMask *ebiten.Image
|
||||||
|
heroCollisionCpy *ebiten.Image
|
||||||
|
|
||||||
Pos Coordinates
|
Pos Coordinates
|
||||||
Paused bool
|
Paused bool
|
||||||
initialized bool
|
initialized bool
|
||||||
mover *Mover
|
gameover bool
|
||||||
|
reset bool
|
||||||
|
runtime float64
|
||||||
|
hero *Hero
|
||||||
projectiles map[int]*Projectile
|
projectiles map[int]*Projectile
|
||||||
explosion *Explosion
|
explosion *Explosion
|
||||||
|
|
||||||
|
score int
|
||||||
counter int
|
counter int
|
||||||
timer int
|
timer int
|
||||||
targets []*Mover
|
targets []*Mover
|
||||||
@@ -41,15 +50,31 @@ func (g *Game) Initialize() {
|
|||||||
|
|
||||||
origin := Coordinates{X: 640 / 2, Y: 480 / 2}
|
origin := Coordinates{X: 640 / 2, Y: 480 / 2}
|
||||||
|
|
||||||
g.mover = NewMover()
|
g.hero = NewHero()
|
||||||
g.mover.SetOrigin(origin)
|
g.hero.SetOrigin(origin)
|
||||||
g.mover.ToggleRotate()
|
g.hero.ToggleRotate()
|
||||||
|
|
||||||
|
g.gameover = false
|
||||||
|
|
||||||
g.collisionMask = ebiten.NewImage(screenWidth, screenHeight)
|
g.collisionMask = ebiten.NewImage(screenWidth, screenHeight)
|
||||||
g.projectileMask = ebiten.NewImage(screenWidth, screenHeight)
|
g.projectileMask = ebiten.NewImage(screenWidth, screenHeight)
|
||||||
|
g.heroCollisionMask = ebiten.NewImage(MOVER_WIDTH, MOVER_HEIGHT)
|
||||||
|
g.heroCollisionCpy = ebiten.NewImage(MOVER_WIDTH, MOVER_HEIGHT)
|
||||||
|
|
||||||
g.explosion = NewExplosion()
|
g.explosion = NewExplosion()
|
||||||
g.explosion.SetOrigin(origin)
|
g.explosion.SetOrigin(origin)
|
||||||
|
g.score = 0
|
||||||
|
g.reset = false
|
||||||
|
|
||||||
|
for j := 0; j < len(g.targets); j++ {
|
||||||
|
g.targets[j] = nil
|
||||||
|
}
|
||||||
|
g.targets = g.targets[:0]
|
||||||
|
|
||||||
|
g.score = 0
|
||||||
|
g.counter = 0
|
||||||
|
g.timer = 0
|
||||||
|
g.runtime = 0.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,11 +96,12 @@ func (g *Game) Update() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !g.initialized {
|
if !g.initialized || g.reset {
|
||||||
g.Initialize()
|
g.Initialize()
|
||||||
|
|
||||||
g.projectiles = make(map[int]*Projectile)
|
g.projectiles = make(map[int]*Projectile)
|
||||||
g.initialized = true
|
g.initialized = true
|
||||||
|
g.reset = false
|
||||||
} else {
|
} else {
|
||||||
g.StepGame()
|
g.StepGame()
|
||||||
}
|
}
|
||||||
@@ -87,19 +113,29 @@ func (g *Game) Update() error {
|
|||||||
|
|
||||||
func (g *Game) Draw(screen *ebiten.Image) {
|
func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
|
|
||||||
g.mover.Draw()
|
g.hero.Draw()
|
||||||
|
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
|
||||||
/*
|
if !g.gameover {
|
||||||
dx := 40 * math.Cos(float64(g.counter)/16)
|
g.runtime = float64(g.counter) / 60.
|
||||||
dy := 40 * math.Sin(float64(g.counter)/16)
|
}
|
||||||
a := float64(g.counter) / (math.Pi * 2)
|
|
||||||
*/
|
s := fmt.Sprintf("%02.3f", g.runtime)
|
||||||
|
if !g.gameover {
|
||||||
|
text.Draw(screen, "TIME: "+s, fonts.SurviveFont.Arcade, 640/2-250, 25, color.White)
|
||||||
|
text.Draw(screen, fmt.Sprintf("SCORE: %d", g.score*10), fonts.SurviveFont.Arcade, 640/2+100, 25, color.White)
|
||||||
|
} else {
|
||||||
|
if (g.counter/30)%2 == 0 {
|
||||||
|
text.Draw(screen, "TIME: "+s, fonts.SurviveFont.Arcade, 640/2-250, 25, color.White)
|
||||||
|
text.Draw(screen, fmt.Sprintf("SCORE: %d", g.score*10), fonts.SurviveFont.Arcade, 640/2+100, 25, color.White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
op.GeoM.Translate(-MOVER_WIDTH/2, -MOVER_HEIGHT/2)
|
op.GeoM.Translate(-MOVER_WIDTH/2, -MOVER_HEIGHT/2)
|
||||||
op.GeoM.Rotate(g.mover.Angle)
|
op.GeoM.Rotate(g.hero.Angle)
|
||||||
op.GeoM.Translate(g.mover.Pos.X, g.mover.Pos.Y)
|
op.GeoM.Translate(g.hero.Pos.X, g.hero.Pos.Y)
|
||||||
screen.DrawImage(g.mover.Sprite, op)
|
screen.DrawImage(g.hero.Sprite, op)
|
||||||
|
|
||||||
for _, target := range g.targets {
|
for _, target := range g.targets {
|
||||||
target.Draw()
|
target.Draw()
|
||||||
@@ -142,10 +178,13 @@ func (g *Game) CleanupTargets() {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//then culling the last elements of the slice
|
//then culling the last elements of the slice
|
||||||
/*if len(g.targets)-i > 0 {
|
if len(g.targets)-i > 0 {
|
||||||
fmt.Printf("Removing %d elements\n", len(g.targets)-i)
|
// fmt.Printf("Removing %d elements\n", len(g.targets)-i)
|
||||||
}*/
|
g.score += len(g.targets) - i
|
||||||
|
}
|
||||||
|
|
||||||
for j := i; j < len(g.targets); j++ {
|
for j := i; j < len(g.targets); j++ {
|
||||||
g.targets[j] = nil
|
g.targets[j] = nil
|
||||||
}
|
}
|
||||||
@@ -160,20 +199,20 @@ func (g *Game) StepGame() {
|
|||||||
|
|
||||||
g.UpdateHeroPosition()
|
g.UpdateHeroPosition()
|
||||||
|
|
||||||
g.mover.Update()
|
g.hero.Update()
|
||||||
g.explosion.Update()
|
g.explosion.Update()
|
||||||
|
|
||||||
g.UpdateTargets()
|
g.UpdateTargets()
|
||||||
g.UpdateProjectiles()
|
g.UpdateProjectiles()
|
||||||
|
|
||||||
|
if !g.gameover {
|
||||||
//append new projectiles
|
//append new projectiles
|
||||||
g.AppendProjectiles()
|
g.AppendProjectiles()
|
||||||
|
|
||||||
//add new target with increasing frequency
|
//add new target with increasing frequency
|
||||||
g.AddNewTargets()
|
g.AddNewTargets()
|
||||||
|
|
||||||
//handle pulsewave updates
|
//handle pulsewave updates
|
||||||
g.HandlePulseWaveUpdate()
|
g.HandlePulseWaveUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
g.CleanupTargets()
|
g.CleanupTargets()
|
||||||
g.counter++
|
g.counter++
|
||||||
@@ -198,8 +237,8 @@ func (g *Game) HandlePulseWaveUpdate() {
|
|||||||
|
|
||||||
//check collisions
|
//check collisions
|
||||||
for _, target := range g.targets {
|
for _, target := range g.targets {
|
||||||
dx := target.Pos.X - g.mover.Pos.X
|
dx := target.Pos.X - g.hero.Pos.X
|
||||||
dy := target.Pos.Y - g.mover.Pos.Y
|
dy := target.Pos.Y - g.hero.Pos.Y
|
||||||
r := math.Sqrt(dx*dx + dy*dy)
|
r := math.Sqrt(dx*dx + dy*dy)
|
||||||
|
|
||||||
if r >= g.explosion.Radius-5 && r <= g.explosion.Radius+5 && target.Action <= MoverActionDamaged && !target.Touched {
|
if r >= g.explosion.Radius-5 && r <= g.explosion.Radius+5 && target.Action <= MoverActionDamaged && !target.Touched {
|
||||||
@@ -261,9 +300,9 @@ func (g *Game) UpdateProjectiles() {
|
|||||||
func (g *Game) UpdateTargets() {
|
func (g *Game) UpdateTargets() {
|
||||||
for _, target := range g.targets {
|
for _, target := range g.targets {
|
||||||
|
|
||||||
if !target.Hit {
|
if !target.Hit && g.hero.Action < MoverActionDying {
|
||||||
dx := g.mover.Pos.X - target.Pos.X
|
dx := g.hero.Pos.X - target.Pos.X
|
||||||
dy := g.mover.Pos.Y - target.Pos.Y
|
dy := g.hero.Pos.Y - target.Pos.Y
|
||||||
angle := math.Atan2(dy, dx)
|
angle := math.Atan2(dy, dx)
|
||||||
|
|
||||||
maxspeed := 3.
|
maxspeed := 3.
|
||||||
@@ -271,6 +310,30 @@ func (g *Game) UpdateTargets() {
|
|||||||
target.Pos.Y += maxspeed * math.Sin(angle)
|
target.Pos.Y += maxspeed * math.Sin(angle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//compute collision with hero
|
||||||
|
if g.hero.Pos.X >= target.Pos.X-MOVER_WIDTH/2 && g.hero.Pos.X <= target.Pos.X+MOVER_WIDTH/2 && g.hero.Pos.Y >= target.Pos.Y-MOVER_HEIGHT/2 && g.hero.Pos.Y <= target.Pos.Y+MOVER_HEIGHT/2 && target.Action < MoverActionDying {
|
||||||
|
g.heroCollisionMask.Clear()
|
||||||
|
g.heroCollisionMask.DrawImage(g.hero.Sprite, nil)
|
||||||
|
|
||||||
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
op.GeoM.Reset()
|
||||||
|
op.Blend = ebiten.BlendSourceIn
|
||||||
|
op.GeoM.Translate((g.hero.Pos.X-target.Pos.X)-MOVER_WIDTH/2, (g.hero.Pos.Y-target.Pos.Y)-MOVER_HEIGHT/2)
|
||||||
|
g.heroCollisionMask.DrawImage(target.Sprite, op)
|
||||||
|
|
||||||
|
//var pixels []byte = make([]byte, MOVER_WIDTH*MOVER_HEIGHT*4)
|
||||||
|
var pixels []byte = make([]byte, MOVER_HEIGHT*MOVER_HEIGHT*4)
|
||||||
|
g.heroCollisionMask.ReadPixels(pixels)
|
||||||
|
for i := 0; i < len(pixels); i = i + 4 {
|
||||||
|
if pixels[i+3] != 0 {
|
||||||
|
fmt.Println("pixel death")
|
||||||
|
g.hero.Action = MoverActionDying
|
||||||
|
g.gameover = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
target.Update()
|
target.Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,8 +347,8 @@ func (g *Game) ResetTargetTouches() {
|
|||||||
func (g *Game) AppendProjectiles() {
|
func (g *Game) AppendProjectiles() {
|
||||||
if g.counter%14 == 0 && ebiten.IsGamepadButtonPressed(0, ebiten.GamepadButton7) {
|
if g.counter%14 == 0 && ebiten.IsGamepadButtonPressed(0, ebiten.GamepadButton7) {
|
||||||
|
|
||||||
g.projectiles[g.counter] = NewProjectile(Coordinates{X: g.mover.Pos.X, Y: g.mover.Pos.Y}, g.mover.Angle, 5.)
|
g.projectiles[g.counter] = NewProjectile(Coordinates{X: g.hero.Pos.X, Y: g.hero.Pos.Y}, g.hero.Angle, 5.)
|
||||||
g.projectiles[g.counter+1] = NewProjectile(Coordinates{X: g.mover.Pos.X, Y: g.mover.Pos.Y}, g.mover.Angle+math.Pi, 5.)
|
g.projectiles[g.counter+1] = NewProjectile(Coordinates{X: g.hero.Pos.X, Y: g.hero.Pos.Y}, g.hero.Angle+math.Pi, 5.)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,15 +356,19 @@ func (g *Game) HandleInput() {
|
|||||||
if len(g.gamepadIDs) > 0 {
|
if len(g.gamepadIDs) > 0 {
|
||||||
if ebiten.IsGamepadButtonPressed(0, ebiten.GamepadButton11) {
|
if ebiten.IsGamepadButtonPressed(0, ebiten.GamepadButton11) {
|
||||||
if !g.explosion.Active {
|
if !g.explosion.Active {
|
||||||
g.explosion.SetOrigin(g.mover.Pos)
|
g.explosion.SetOrigin(g.hero.Pos)
|
||||||
g.explosion.Reset()
|
g.explosion.Reset()
|
||||||
g.explosion.ToggleActivate()
|
g.explosion.ToggleActivate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if inpututil.IsGamepadButtonJustPressed(0, ebiten.GamepadButton9) {
|
if inpututil.IsGamepadButtonJustPressed(0, ebiten.GamepadButton9) {
|
||||||
|
if g.gameover {
|
||||||
|
g.reset = true
|
||||||
|
} else {
|
||||||
g.Paused = !g.Paused
|
g.Paused = !g.Paused
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//account for controller sensitivity
|
//account for controller sensitivity
|
||||||
xaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickHorizontal)
|
xaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickHorizontal)
|
||||||
@@ -315,7 +382,7 @@ func (g *Game) HandleInput() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inputangle := math.Atan2(yaxis, xaxis)
|
inputangle := math.Atan2(yaxis, xaxis)
|
||||||
g.mover.SetAngle(inputangle)
|
g.hero.SetAngle(inputangle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,10 +391,10 @@ func (g *Game) UpdateHeroPosition() {
|
|||||||
inpx := ebiten.GamepadAxisValue(0, 0)
|
inpx := ebiten.GamepadAxisValue(0, 0)
|
||||||
inpy := ebiten.GamepadAxisValue(0, 1)
|
inpy := ebiten.GamepadAxisValue(0, 1)
|
||||||
if inpx >= 0.15 || inpx <= -0.15 {
|
if inpx >= 0.15 || inpx <= -0.15 {
|
||||||
g.mover.Pos.X += ebiten.GamepadAxisValue(0, 0) * 5
|
g.hero.Pos.X += ebiten.GamepadAxisValue(0, 0) * 5
|
||||||
}
|
}
|
||||||
|
|
||||||
if inpy >= 0.15 || inpy <= -0.15 {
|
if inpy >= 0.15 || inpy <= -0.15 {
|
||||||
g.mover.Pos.Y += ebiten.GamepadAxisValue(0, 1) * 5
|
g.hero.Pos.Y += ebiten.GamepadAxisValue(0, 1) * 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
go.mod
7
go.mod
@@ -4,7 +4,11 @@ go 1.22.0
|
|||||||
|
|
||||||
toolchain go1.22.8
|
toolchain go1.22.8
|
||||||
|
|
||||||
require github.com/hajimehoshi/ebiten/v2 v2.8.2
|
require (
|
||||||
|
github.com/hajimehoshi/ebiten v1.12.12
|
||||||
|
github.com/hajimehoshi/ebiten/v2 v2.8.2
|
||||||
|
golang.org/x/image v0.20.0
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 // indirect
|
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 // indirect
|
||||||
@@ -13,4 +17,5 @@ require (
|
|||||||
github.com/jezek/xgb v1.1.1 // indirect
|
github.com/jezek/xgb v1.1.1 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
|
golang.org/x/text v0.18.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
120
hero.go
Normal file
120
hero.go
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"image"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
|
"image/color"
|
||||||
|
_ "image/png"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
heroImage *ebiten.Image
|
||||||
|
|
||||||
|
//go:embed hero.png
|
||||||
|
hero_img []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
HeroActionDefault = iota
|
||||||
|
HeroActionDamaged
|
||||||
|
HeroActionDying
|
||||||
|
HeroActionExploding
|
||||||
|
HeroActionDead
|
||||||
|
HeroActionMax
|
||||||
|
)
|
||||||
|
|
||||||
|
type HeroAction uint
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
img, _, err := image.Decode(bytes.NewReader(hero_img))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
heroImage = ebiten.NewImageFromImage(img)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hero struct {
|
||||||
|
Sprite *ebiten.Image
|
||||||
|
Maks *ebiten.Image
|
||||||
|
MaksDest *ebiten.Image
|
||||||
|
Angle float64
|
||||||
|
Pos Coordinates
|
||||||
|
Origin Coordinates
|
||||||
|
Action HeroAction
|
||||||
|
cycles int
|
||||||
|
rotating bool
|
||||||
|
Toggled bool
|
||||||
|
Hit bool
|
||||||
|
Touched bool
|
||||||
|
dyingcount int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHero() *Hero {
|
||||||
|
m := &Hero{
|
||||||
|
Sprite: ebiten.NewImage(48, 48),
|
||||||
|
Maks: ebiten.NewImage(48, 48),
|
||||||
|
MaksDest: ebiten.NewImage(48, 48),
|
||||||
|
Action: HeroActionDefault,
|
||||||
|
cycles: 4,
|
||||||
|
Angle: 0,
|
||||||
|
rotating: false,
|
||||||
|
Toggled: false,
|
||||||
|
dyingcount: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Maks.Fill(color.White)
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Hero) ToggleRotate() {
|
||||||
|
m.rotating = !m.rotating
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Hero) SetAngle(a float64) {
|
||||||
|
m.Angle = a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Hero) SetOrigin(coords Coordinates) {
|
||||||
|
m.Origin = coords
|
||||||
|
m.Pos = coords
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Hero) 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 HeroActionDefault:
|
||||||
|
m.Sprite.DrawImage(heroImage.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Hero) Update() {
|
||||||
|
m.cycles++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Hero) SetHit() {
|
||||||
|
m.Action++ // = (m.Action + 1) % HeroActionMax
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Hero) ToggleColor() {
|
||||||
|
//m.Toggled = !m.Toggled
|
||||||
|
if m.Action == HeroActionDefault {
|
||||||
|
m.Action = HeroActionDamaged
|
||||||
|
} else if m.Action == HeroActionDamaged {
|
||||||
|
m.Action = HeroActionDefault
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user