Cleanup, touchups, new death animation on hero.
This commit is contained in:
98
game.go
98
game.go
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
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 (
|
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
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() {
|
func main() {
|
||||||
ver := "survive v0.08"
|
ver := "survive v0.10"
|
||||||
|
|
||||||
fmt.Println(ver)
|
fmt.Println(ver)
|
||||||
|
|
||||||
|
|||||||
15
mover.go
15
mover.go
@@ -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
BIN
shadow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 B |
Reference in New Issue
Block a user