Cleanup, touchups, new death animation on hero.
This commit is contained in:
78
game.go
78
game.go
@@ -25,9 +25,12 @@ const (
|
||||
|
||||
var (
|
||||
tilesetImage *ebiten.Image
|
||||
altarImage *ebiten.Image
|
||||
|
||||
//go:embed grasstile.png
|
||||
tileset_img []byte
|
||||
//go:embed altar.png
|
||||
altar_img []byte
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
@@ -64,6 +67,12 @@ func init() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
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() {
|
||||
@@ -87,6 +96,7 @@ func (g *Game) Initialize() {
|
||||
g.score = 0
|
||||
g.reset = false
|
||||
|
||||
//clean up all targets
|
||||
for j := 0; j < len(g.targets); j++ {
|
||||
g.targets[j] = nil
|
||||
}
|
||||
@@ -97,6 +107,10 @@ func (g *Game) Initialize() {
|
||||
g.timer = 0
|
||||
g.runtime = 0.
|
||||
|
||||
g.projectiles = make(map[int]*Projectile)
|
||||
g.initialized = true
|
||||
g.reset = false
|
||||
|
||||
}
|
||||
|
||||
func (g *Game) Update() error {
|
||||
@@ -119,10 +133,6 @@ func (g *Game) Update() error {
|
||||
|
||||
if !g.initialized || g.reset {
|
||||
g.Initialize()
|
||||
|
||||
g.projectiles = make(map[int]*Projectile)
|
||||
g.initialized = true
|
||||
g.reset = false
|
||||
} else {
|
||||
g.StepGame()
|
||||
}
|
||||
@@ -221,8 +231,6 @@ func (g *Game) StepGame() {
|
||||
|
||||
if !g.Paused {
|
||||
|
||||
g.UpdateHeroPosition()
|
||||
|
||||
g.hero.Update()
|
||||
g.explosion.Update()
|
||||
|
||||
@@ -230,10 +238,11 @@ func (g *Game) StepGame() {
|
||||
g.UpdateProjectiles()
|
||||
|
||||
if !g.gameover {
|
||||
g.UpdateHeroPosition()
|
||||
//append new projectiles
|
||||
g.AppendProjectiles()
|
||||
//add new target with increasing frequency
|
||||
g.AddNewTargets()
|
||||
g.SpawnEnemies()
|
||||
//handle pulsewave updates
|
||||
g.HandlePulseWaveUpdate()
|
||||
}
|
||||
@@ -243,11 +252,29 @@ func (g *Game) StepGame() {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) AddNewTargets() {
|
||||
func (g *Game) SpawnEnemies() {
|
||||
f := 40000 / (g.counter + 1)
|
||||
if g.counter%f == 0 {
|
||||
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
|
||||
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.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 {
|
||||
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.DrawImage(g.hero.Sprite, nil)
|
||||
|
||||
@@ -352,8 +380,8 @@ func (g *Game) UpdateTargets() {
|
||||
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
|
||||
//fmt.Println("pixel death")
|
||||
g.hero.SetHit()
|
||||
g.gameover = true
|
||||
break
|
||||
}
|
||||
@@ -381,7 +409,7 @@ func (g *Game) AppendProjectiles() {
|
||||
func (g *Game) HandleInput() {
|
||||
if len(g.gamepadIDs) > 0 {
|
||||
if ebiten.IsGamepadButtonPressed(0, ebiten.GamepadButton11) {
|
||||
if !g.explosion.Active {
|
||||
if !g.explosion.Active && !g.gameover {
|
||||
g.explosion.SetOrigin(g.hero.Pos)
|
||||
g.explosion.Reset()
|
||||
g.explosion.ToggleActivate()
|
||||
@@ -397,6 +425,7 @@ func (g *Game) HandleInput() {
|
||||
}
|
||||
|
||||
//account for controller sensitivity
|
||||
if !g.gameover {
|
||||
xaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickHorizontal)
|
||||
yaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickVertical)
|
||||
|
||||
@@ -411,6 +440,7 @@ func (g *Game) HandleInput() {
|
||||
g.hero.SetAngle(inputangle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) UpdateHeroPosition() {
|
||||
//handle gamepad input
|
||||
@@ -427,18 +457,19 @@ func (g *Game) UpdateHeroPosition() {
|
||||
|
||||
func (g *Game) ConstructBackground() {
|
||||
g.background = ebiten.NewImage(screenWidth, screenHeight)
|
||||
BLOCK_SIZE := 32
|
||||
|
||||
for i := 0; i < 640/16; i++ {
|
||||
for j := 0; j < 480/16; j++ {
|
||||
|
||||
//select random tile in x and y from tileset
|
||||
idx_x := rand.IntN(256 / 16)
|
||||
idx_y := rand.IntN(256 / 16)
|
||||
idx_y := rand.IntN(256 / BLOCK_SIZE)
|
||||
idx_x := rand.IntN(256 / BLOCK_SIZE)
|
||||
|
||||
x0 := 16 * idx_x
|
||||
y0 := 16 * idx_y
|
||||
x1 := x0 + 16
|
||||
y1 := y0 + 16
|
||||
x0 := BLOCK_SIZE * idx_x
|
||||
y0 := BLOCK_SIZE * idx_y
|
||||
x1 := x0 + BLOCK_SIZE
|
||||
y1 := y0 + BLOCK_SIZE
|
||||
|
||||
//translate for grid element we're painting
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
BIN
grasstile.png
BIN
grasstile.png
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
26
hero.go
26
hero.go
@@ -14,9 +14,13 @@ import (
|
||||
|
||||
var (
|
||||
heroImage *ebiten.Image
|
||||
heroDeath *ebiten.Image
|
||||
|
||||
//go:embed hero.png
|
||||
hero_img []byte
|
||||
|
||||
//go:embed herodeath.png
|
||||
herodeath_img []byte
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -36,6 +40,12 @@ func init() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
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 {
|
||||
@@ -98,6 +108,17 @@ func (m *Hero) Draw() {
|
||||
switch m.Action {
|
||||
case HeroActionDefault:
|
||||
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:
|
||||
}
|
||||
}
|
||||
@@ -106,8 +127,11 @@ func (m *Hero) Update() {
|
||||
m.cycles++
|
||||
}
|
||||
|
||||
// one hit death for the hero
|
||||
func (m *Hero) SetHit() {
|
||||
m.Action++ // = (m.Action + 1) % HeroActionMax
|
||||
m.Action = MoverActionDying
|
||||
m.Angle = 0
|
||||
m.cycles = 0
|
||||
}
|
||||
|
||||
func (m *Hero) ToggleColor() {
|
||||
|
||||
BIN
hero.png
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
BIN
herodeath.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
2
main.go
2
main.go
@@ -13,7 +13,7 @@ const (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ver := "survive v0.08"
|
||||
ver := "survive v0.10"
|
||||
|
||||
fmt.Println(ver)
|
||||
|
||||
|
||||
15
mover.go
15
mover.go
@@ -16,6 +16,7 @@ var (
|
||||
flyeyeImage *ebiten.Image
|
||||
flyeyeImage2 *ebiten.Image
|
||||
flyeyeImage3 *ebiten.Image
|
||||
shadow *ebiten.Image
|
||||
|
||||
//go:embed fly-eye.png
|
||||
flyeye_img []byte
|
||||
@@ -23,6 +24,8 @@ var (
|
||||
flyeye_img2 []byte
|
||||
//go:embed fly-eye3.png
|
||||
flyeye_img3 []byte
|
||||
//go:embed shadow.png
|
||||
shadow_img []byte
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -54,6 +57,12 @@ func init() {
|
||||
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 {
|
||||
@@ -115,8 +124,14 @@ func (m *Mover) Draw() {
|
||||
|
||||
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:
|
||||
m.dyingcount++
|
||||
|
||||
BIN
shadow.png
Normal file
BIN
shadow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 B |
Reference in New Issue
Block a user