Cleanup, touchups, new death animation on hero.

This commit is contained in:
2024-11-07 10:41:30 -05:00
parent b4e1f459bf
commit 87e40226c7
9 changed files with 109 additions and 32 deletions

BIN
altar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

98
game.go
View File

@@ -25,9 +25,12 @@ const (
var ( var (
tilesetImage *ebiten.Image tilesetImage *ebiten.Image
altarImage *ebiten.Image
//go:embed grasstile.png //go:embed grasstile.png
tileset_img []byte tileset_img []byte
//go:embed altar.png
altar_img []byte
) )
type Game struct { type Game struct {
@@ -64,6 +67,12 @@ func init() {
log.Fatal(err) log.Fatal(err)
} }
tilesetImage = ebiten.NewImageFromImage(img) tilesetImage = ebiten.NewImageFromImage(img)
img, _, err = image.Decode(bytes.NewReader(altar_img))
if err != nil {
log.Fatal(err)
}
altarImage = ebiten.NewImageFromImage(img)
} }
func (g *Game) Initialize() { func (g *Game) Initialize() {
@@ -87,6 +96,7 @@ func (g *Game) Initialize() {
g.score = 0 g.score = 0
g.reset = false g.reset = false
//clean up all targets
for j := 0; j < len(g.targets); j++ { for j := 0; j < len(g.targets); j++ {
g.targets[j] = nil g.targets[j] = nil
} }
@@ -97,6 +107,10 @@ func (g *Game) Initialize() {
g.timer = 0 g.timer = 0
g.runtime = 0. g.runtime = 0.
g.projectiles = make(map[int]*Projectile)
g.initialized = true
g.reset = false
} }
func (g *Game) Update() error { func (g *Game) Update() error {
@@ -119,10 +133,6 @@ func (g *Game) Update() error {
if !g.initialized || g.reset { if !g.initialized || g.reset {
g.Initialize() g.Initialize()
g.projectiles = make(map[int]*Projectile)
g.initialized = true
g.reset = false
} else { } else {
g.StepGame() g.StepGame()
} }
@@ -221,8 +231,6 @@ func (g *Game) StepGame() {
if !g.Paused { if !g.Paused {
g.UpdateHeroPosition()
g.hero.Update() g.hero.Update()
g.explosion.Update() g.explosion.Update()
@@ -230,10 +238,11 @@ func (g *Game) StepGame() {
g.UpdateProjectiles() g.UpdateProjectiles()
if !g.gameover { if !g.gameover {
g.UpdateHeroPosition()
//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.SpawnEnemies()
//handle pulsewave updates //handle pulsewave updates
g.HandlePulseWaveUpdate() g.HandlePulseWaveUpdate()
} }
@@ -243,11 +252,29 @@ func (g *Game) StepGame() {
} }
} }
func (g *Game) AddNewTargets() { func (g *Game) SpawnEnemies() {
f := 40000 / (g.counter + 1) f := 40000 / (g.counter + 1)
if g.counter%f == 0 { if g.counter%f == 0 {
g.targets = append(g.targets, NewMover()) g.targets = append(g.targets, NewMover())
g.targets[len(g.targets)-1].SetOrigin(Coordinates{X: rand.Float64() * 640, Y: rand.Float64() * 480})
x0 := rand.Float64() * 640
y0 := rand.Float64() * 480
quadrant := rand.IntN(3)
switch quadrant {
case 0:
g.targets[len(g.targets)-1].SetOrigin(Coordinates{X: x0, Y: -MOVER_HEIGHT})
case 1:
g.targets[len(g.targets)-1].SetOrigin(Coordinates{X: x0, Y: screenHeight + MOVER_HEIGHT})
case 2:
g.targets[len(g.targets)-1].SetOrigin(Coordinates{X: -MOVER_WIDTH, Y: y0})
case 3:
g.targets[len(g.targets)-1].SetOrigin(Coordinates{X: screenWidth + x0, Y: y0})
default:
g.targets[len(g.targets)-1].SetOrigin(Coordinates{X: x0, Y: y0})
fmt.Println("WTF " + string(quadrant))
}
} }
} }
@@ -331,13 +358,14 @@ func (g *Game) UpdateTargets() {
dy := g.hero.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 := (float64(g.counter) + 1.) / 1000.
maxspeed := 2.9
target.Pos.X += maxspeed * math.Cos(angle) target.Pos.X += maxspeed * math.Cos(angle)
target.Pos.Y += maxspeed * math.Sin(angle) target.Pos.Y += maxspeed * math.Sin(angle)
} }
//compute collision with hero //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 { 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.hero.Action < MoverActionDying {
g.heroCollisionMask.Clear() g.heroCollisionMask.Clear()
g.heroCollisionMask.DrawImage(g.hero.Sprite, nil) g.heroCollisionMask.DrawImage(g.hero.Sprite, nil)
@@ -352,8 +380,8 @@ func (g *Game) UpdateTargets() {
g.heroCollisionMask.ReadPixels(pixels) g.heroCollisionMask.ReadPixels(pixels)
for i := 0; i < len(pixels); i = i + 4 { for i := 0; i < len(pixels); i = i + 4 {
if pixels[i+3] != 0 { if pixels[i+3] != 0 {
fmt.Println("pixel death") //fmt.Println("pixel death")
g.hero.Action = MoverActionDying g.hero.SetHit()
g.gameover = true g.gameover = true
break break
} }
@@ -381,7 +409,7 @@ func (g *Game) AppendProjectiles() {
func (g *Game) HandleInput() { 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.gameover {
g.explosion.SetOrigin(g.hero.Pos) g.explosion.SetOrigin(g.hero.Pos)
g.explosion.Reset() g.explosion.Reset()
g.explosion.ToggleActivate() g.explosion.ToggleActivate()
@@ -397,18 +425,20 @@ func (g *Game) HandleInput() {
} }
//account for controller sensitivity //account for controller sensitivity
xaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickHorizontal) if !g.gameover {
yaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickVertical) xaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickHorizontal)
yaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickVertical)
if yaxis <= 0.09 && yaxis >= -0.09 { if yaxis <= 0.09 && yaxis >= -0.09 {
yaxis = 0 yaxis = 0
} }
if xaxis <= 0.09 && xaxis >= -0.09 { if xaxis <= 0.09 && xaxis >= -0.09 {
xaxis = 0 xaxis = 0
} }
inputangle := math.Atan2(yaxis, xaxis) inputangle := math.Atan2(yaxis, xaxis)
g.hero.SetAngle(inputangle) g.hero.SetAngle(inputangle)
}
} }
} }
@@ -427,18 +457,19 @@ func (g *Game) UpdateHeroPosition() {
func (g *Game) ConstructBackground() { func (g *Game) ConstructBackground() {
g.background = ebiten.NewImage(screenWidth, screenHeight) g.background = ebiten.NewImage(screenWidth, screenHeight)
BLOCK_SIZE := 32
for i := 0; i < 640/16; i++ { for i := 0; i < 640/16; i++ {
for j := 0; j < 480/16; j++ { for j := 0; j < 480/16; j++ {
//select random tile in x and y from tileset //select random tile in x and y from tileset
idx_x := rand.IntN(256 / 16) idx_y := rand.IntN(256 / BLOCK_SIZE)
idx_y := rand.IntN(256 / 16) idx_x := rand.IntN(256 / BLOCK_SIZE)
x0 := 16 * idx_x x0 := BLOCK_SIZE * idx_x
y0 := 16 * idx_y y0 := BLOCK_SIZE * idx_y
x1 := x0 + 16 x1 := x0 + BLOCK_SIZE
y1 := y0 + 16 y1 := y0 + BLOCK_SIZE
//translate for grid element we're painting //translate for grid element we're painting
op := &ebiten.DrawImageOptions{} op := &ebiten.DrawImageOptions{}
@@ -446,4 +477,11 @@ func (g *Game) ConstructBackground() {
g.background.DrawImage(tilesetImage.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), op) g.background.DrawImage(tilesetImage.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), op)
} }
} }
ax := float64(rand.IntN(640/BLOCK_SIZE) * BLOCK_SIZE)
ay := float64(rand.IntN(480/BLOCK_SIZE) * BLOCK_SIZE)
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(ax, ay)
g.background.DrawImage(altarImage, op)
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

26
hero.go
View File

@@ -14,9 +14,13 @@ import (
var ( var (
heroImage *ebiten.Image heroImage *ebiten.Image
heroDeath *ebiten.Image
//go:embed hero.png //go:embed hero.png
hero_img []byte hero_img []byte
//go:embed herodeath.png
herodeath_img []byte
) )
const ( const (
@@ -36,6 +40,12 @@ func init() {
log.Fatal(err) log.Fatal(err)
} }
heroImage = ebiten.NewImageFromImage(img) heroImage = ebiten.NewImageFromImage(img)
img, _, err = image.Decode(bytes.NewReader(herodeath_img))
if err != nil {
log.Fatal(err)
}
heroDeath = ebiten.NewImageFromImage(img)
} }
type Hero struct { type Hero struct {
@@ -98,6 +108,17 @@ func (m *Hero) Draw() {
switch m.Action { switch m.Action {
case HeroActionDefault: case HeroActionDefault:
m.Sprite.DrawImage(heroImage.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) m.Sprite.DrawImage(heroImage.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
case HeroActionDying:
m.dyingcount++
m.Sprite.DrawImage(heroDeath.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
if m.dyingcount > 60 {
m.cycles = 0
m.Action++
}
case HeroActionExploding:
m.Sprite.DrawImage(heroDeath.SubImage(image.Rect(48*3, 0, 48*4, 48)).(*ebiten.Image), nil)
default: default:
} }
} }
@@ -106,8 +127,11 @@ func (m *Hero) Update() {
m.cycles++ m.cycles++
} }
// one hit death for the hero
func (m *Hero) SetHit() { func (m *Hero) SetHit() {
m.Action++ // = (m.Action + 1) % HeroActionMax m.Action = MoverActionDying
m.Angle = 0
m.cycles = 0
} }
func (m *Hero) ToggleColor() { func (m *Hero) ToggleColor() {

BIN
hero.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
herodeath.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -13,7 +13,7 @@ const (
) )
func main() { func main() {
ver := "survive v0.08" ver := "survive v0.10"
fmt.Println(ver) fmt.Println(ver)

View File

@@ -16,6 +16,7 @@ var (
flyeyeImage *ebiten.Image flyeyeImage *ebiten.Image
flyeyeImage2 *ebiten.Image flyeyeImage2 *ebiten.Image
flyeyeImage3 *ebiten.Image flyeyeImage3 *ebiten.Image
shadow *ebiten.Image
//go:embed fly-eye.png //go:embed fly-eye.png
flyeye_img []byte flyeye_img []byte
@@ -23,6 +24,8 @@ var (
flyeye_img2 []byte flyeye_img2 []byte
//go:embed fly-eye3.png //go:embed fly-eye3.png
flyeye_img3 []byte flyeye_img3 []byte
//go:embed shadow.png
shadow_img []byte
) )
const ( const (
@@ -54,6 +57,12 @@ func init() {
log.Fatal(err) log.Fatal(err)
} }
flyeyeImage3 = ebiten.NewImageFromImage(img) 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 { type Mover struct {
@@ -115,8 +124,14 @@ func (m *Mover) Draw() {
switch m.Action { switch m.Action {
case MoverActionDefault: 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) m.Sprite.DrawImage(flyeyeImage.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
case MoverActionDamaged: 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) m.Sprite.DrawImage(flyeyeImage2.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
case MoverActionDying: case MoverActionDying:
m.dyingcount++ m.dyingcount++

BIN
shadow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B