Add reset mechanism

This commit is contained in:
Trevor Slocum 2021-10-09 10:35:57 -07:00
parent f176dc6cc0
commit 5b5d2535dd
3 changed files with 93 additions and 48 deletions

135
game.go
View File

@ -79,7 +79,8 @@ type game struct {
ojasSS *CharacterSpriteSheet
heartImg *ebiten.Image
heartImg *ebiten.Image
vampireImage *ebiten.Image
overlayImg *ebiten.Image
op *ebiten.DrawImageOptions
@ -103,24 +104,12 @@ const sampleRate = 48000
// NewGame returns a new isometric demo game.
func NewGame() (*game, error) {
l, err := NewLevel()
if err != nil {
return nil, fmt.Errorf("failed to create new level: %s", err)
}
p, err := NewPlayer()
if err != nil {
return nil, err
}
g := &game{
currentLevel: l,
camScale: 2,
camScaleTo: 2,
mousePanX: math.MinInt32,
mousePanY: math.MinInt32,
player: p,
op: &ebiten.DrawImageOptions{},
camScale: 2,
camScaleTo: 2,
mousePanX: math.MinInt32,
mousePanY: math.MinInt32,
op: &ebiten.DrawImageOptions{},
soundBuffer: make(map[int][]*audio.Player),
nextSound: make(map[int]int),
@ -129,33 +118,52 @@ func NewGame() (*game, error) {
g.audioContext = audio.NewContext(sampleRate)
g.player.x = float64(rand.Intn(108))
g.player.y = float64(rand.Intn(108))
ebiten.SetCursorShape(ebiten.CursorShapeCrosshair)
err := g.loadAssets()
if err != nil {
return nil, err
}
g.player, err = NewPlayer()
if err != nil {
return nil, err
}
err = g.reset()
if err != nil {
return nil, err
}
return g, nil
}
func (g *game) loadAssets() error {
var err error
// Load SpriteSheets.
g.ojasSS, err = LoadCharacterSpriteSheet()
if err != nil {
return nil, fmt.Errorf("failed to load embedded spritesheet: %s", err)
return fmt.Errorf("failed to load embedded spritesheet: %s", err)
}
f, err := assetsFS.Open("assets/weapons/bullet.png")
if err != nil {
return nil, err
return err
}
img, _, err := image.Decode(f)
if err != nil {
return nil, err
return err
}
bulletImage = ebiten.NewImageFromImage(img)
f, err = assetsFS.Open("assets/weapons/flash.png")
if err != nil {
return nil, err
return err
}
img, _, err = image.Decode(f)
if err != nil {
return nil, err
return err
}
flashImage = ebiten.NewImageFromImage(img)
@ -163,81 +171,101 @@ func NewGame() (*game, error) {
for i := 0; i < 4; i++ {
stream, err := loadMP3(g.audioContext, "assets/audio/gunshot.mp3")
if err != nil {
return nil, err
return err
}
g.soundBuffer[SoundGunshot] = append(g.soundBuffer[SoundGunshot], stream)
stream, err = loadMP3(g.audioContext, "assets/audio/vampiredie1.mp3")
if err != nil {
return nil, err
return err
}
g.soundBuffer[SoundVampireDie1] = append(g.soundBuffer[SoundVampireDie1], stream)
stream, err = loadMP3(g.audioContext, "assets/audio/vampiredie2.mp3")
if err != nil {
return nil, err
return err
}
g.soundBuffer[SoundVampireDie2] = append(g.soundBuffer[SoundVampireDie2], stream)
stream, err = loadWav(g.audioContext, "assets/audio/hurt.wav")
if err != nil {
return nil, err
return err
}
g.soundBuffer[SoundPlayerHurt] = append(g.soundBuffer[SoundPlayerHurt], stream)
stream, err = loadMP3(g.audioContext, "assets/audio/die.mp3")
if err != nil {
return nil, err
return err
}
g.soundBuffer[SoundPlayerDie] = append(g.soundBuffer[SoundPlayerDie], stream)
}
f, err = assetsFS.Open("assets/creeps/vampire.png")
if err != nil {
return nil, err
return err
}
img, _, err = image.Decode(f)
if err != nil {
return nil, err
return err
}
vampireImage := ebiten.NewImageFromImage(img)
g.vampireImage = ebiten.NewImageFromImage(img)
f, err = assetsFS.Open("assets/ui/heart.png")
if err != nil {
return nil, err
return err
}
img, _, err = image.Decode(f)
if err != nil {
return nil, err
return err
}
g.heartImg = ebiten.NewImageFromImage(img)
return nil
}
func (g *game) reset() error {
var err error
g.currentLevel, err = NewLevel()
if err != nil {
return fmt.Errorf("failed to create new level: %s", err)
}
// Reset player score.
g.player.score = 0
// Reset player health.
g.player.health = 3
// Position player.
g.player.x = float64(rand.Intn(108))
g.player.y = float64(rand.Intn(108))
// Spawn creeps.
g.creeps = make([]*gameCreep, 1000)
addedCreeps := make(map[string]bool)
for i := 0; i < 1000; i++ {
c := NewCreep(vampireImage, g.currentLevel, g.player)
c := NewCreep(g.vampireImage, g.currentLevel, g.player)
safeSpace := 7.0
dx, dy := deltaXY(g.player.x, g.player.y, c.x, c.y)
if dx <= safeSpace || dy <= safeSpace {
// Too close to the spawn point.
i--
continue
}
addedCreep := fmt.Sprintf("%0.0f-%0.0f", c.x, c.y)
if addedCreeps[addedCreep] {
// Already added a gameCreep here.
i--
continue
}
g.creeps = append(g.creeps, c)
g.creeps[i] = c
addedCreeps[addedCreep] = true
}
ebiten.SetCursorShape(ebiten.CursorShapeCrosshair)
return g, nil
return nil
}
// Layout is called when the game's layout changes.
@ -273,6 +301,15 @@ func (g *game) Update() error {
if g.player.health <= 0 && !g.godMode {
// Game over.
if ebiten.IsKeyPressed(ebiten.KeyEnter) {
err := g.reset()
if err != nil {
return err
}
g.gameOverTime = time.Time{}
}
// TODO or button start on gamepad
return nil
}
@ -583,13 +620,21 @@ func (g *game) Draw(screen *ebiten.Image) {
if time.Since(g.gameOverTime).Milliseconds()%2000 < 1500 {
g.overlayImg.Clear()
ebitenutil.DebugPrint(g.overlayImg, "GAME OVER")
ebitenutil.DebugPrint(g.overlayImg, "PRESS ENTER OR START TO PLAY AGAIN")
g.op.GeoM.Reset()
g.op.GeoM.Translate(3, 0)
g.op.GeoM.Scale(16, 16)
g.op.GeoM.Translate(float64(g.w/2)-495, float64(g.h/2)-200)
g.op.GeoM.Scale(4, 4)
g.op.GeoM.Translate(float64(g.w/2)-(36*12), 8)
screen.DrawImage(g.overlayImg, g.op)
}
g.overlayImg.Clear()
ebitenutil.DebugPrint(g.overlayImg, "GAME OVER")
g.op.GeoM.Reset()
g.op.GeoM.Translate(3, 0)
g.op.GeoM.Scale(16, 16)
g.op.GeoM.Translate(float64(g.w/2)-495, float64(g.h/2)-200)
screen.DrawImage(g.overlayImg, g.op)
}
heartSpace := 64
@ -610,7 +655,7 @@ func (g *game) Draw(screen *ebiten.Image) {
screen.DrawImage(g.overlayImg, g.op)
if g.godMode {
// Print game info.
// Draw God mode indicator.
g.overlayImg.Clear()
ebitenutil.DebugPrint(g.overlayImg, "GOD")
g.op.GeoM.Reset()

2
go.mod
View File

@ -3,7 +3,7 @@ module code.rocketnine.space/tslocum/carotidartillery
go 1.17
require (
github.com/hajimehoshi/ebiten/v2 v2.3.0-alpha.0.20211007133459-69087cdc4006
github.com/hajimehoshi/ebiten/v2 v2.2.0
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
golang.org/x/text v0.3.7
)

4
go.sum
View File

@ -97,8 +97,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hajimehoshi/bitmapfont/v2 v2.1.3/go.mod h1:2BnYrkTQGThpr/CY6LorYtt/zEPNzvE/ND69CRTaHMs=
github.com/hajimehoshi/ebiten/v2 v2.3.0-alpha.0.20211007133459-69087cdc4006 h1:81tAk6qxukWmcaP7zURm7jiIQ8efdDms6oGYRTeWIA8=
github.com/hajimehoshi/ebiten/v2 v2.3.0-alpha.0.20211007133459-69087cdc4006/go.mod h1:olKl/qqhMBBAm2oI7Zy292nCtE+nitlmYKNF3UpbFn0=
github.com/hajimehoshi/ebiten/v2 v2.2.0 h1:2mP9HrLLqiH9X3MajElYZEjVZU/CGh22iFkjatxhT4w=
github.com/hajimehoshi/ebiten/v2 v2.2.0/go.mod h1:olKl/qqhMBBAm2oI7Zy292nCtE+nitlmYKNF3UpbFn0=
github.com/hajimehoshi/file2byteslice v0.0.0-20210813153925-5340248a8f41/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
github.com/hajimehoshi/go-mp3 v0.3.2 h1:xSYNE2F3lxtOu9BRjCWHHceg7S91IHfXfXp5+LYQI7s=
github.com/hajimehoshi/go-mp3 v0.3.2/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=