From e5e8af1e9bd93e43a405db991cfc561ce33a8a7a Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Wed, 6 Oct 2021 08:03:13 -0700 Subject: [PATCH] Randomize player and creep placement --- creep.go | 35 ++++++++++++++++++++---- game.go | 83 ++++++++++++++++++++++++++++++++------------------------ level.go | 16 +++++------ 3 files changed, 85 insertions(+), 49 deletions(-) diff --git a/creep.go b/creep.go index 56430fc..f92c4b3 100644 --- a/creep.go +++ b/creep.go @@ -18,36 +18,59 @@ type gameCreep struct { level *Level + health int + sync.Mutex } func NewCreep(sprite *ebiten.Image, level *Level) *gameCreep { return &gameCreep{ - x: float64(1 + rand.Intn(64)), - y: float64(1 + rand.Intn(64)), + x: float64(1 + rand.Intn(108)), + y: float64(1 + rand.Intn(108)), sprite: sprite, level: level, + health: 1, } } func (c *gameCreep) doNextAction() { - c.moveX = (rand.Float64() - 0.5) / 10 - c.moveY = (rand.Float64() - 0.5) / 10 + c.moveX = (rand.Float64() - 0.5) / 7 + c.moveY = (rand.Float64() - 0.5) / 7 - c.nextAction = 400 + rand.Intn(1000) + if c.x <= 2 && c.moveX < 0 { + c.moveX *= 1 + } else if c.x >= float64(c.level.w-3) && c.moveX > 0 { + c.moveX *= 1 + } + if c.y <= 2 && c.moveY > 0 { + c.moveY *= 1 + } else if c.y >= float64(c.level.h-3) && c.moveY < 0 { + c.moveY *= 1 + } + + c.nextAction = 400 + rand.Intn(400) } func (c *gameCreep) Update() { c.Lock() defer c.Unlock() + if c.health == 0 { + return + } + c.tick++ if c.tick >= c.nextAction { c.doNextAction() c.tick = 0 } - c.x, c.y = c.level.Clamp(c.x+c.moveX, c.y+c.moveY) + x, y := c.x+c.moveX, c.y+c.moveY + clampX, clampY := c.level.Clamp(x, y) + c.x, c.y = clampX, clampY + if clampX != x || clampY != y { + c.nextAction = 0 + } } func (c *gameCreep) Position() (float64, float64) { diff --git a/game.go b/game.go index 9b35789..b2f8466 100644 --- a/game.go +++ b/game.go @@ -9,14 +9,12 @@ import ( "os" "time" - "github.com/hajimehoshi/ebiten/v2/audio" - - "github.com/hajimehoshi/ebiten/v2/audio/mp3" - - "golang.org/x/image/colornames" - "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/audio" + "github.com/hajimehoshi/ebiten/v2/audio/mp3" "github.com/hajimehoshi/ebiten/v2/ebitenutil" + "github.com/hajimehoshi/ebiten/v2/inpututil" + "golang.org/x/image/colornames" ) var spinner = []byte(`-\|/`) @@ -59,6 +57,8 @@ type game struct { overlayImg *ebiten.Image op *ebiten.DrawImageOptions + + godMode bool } const sampleRate = 48000 @@ -79,16 +79,16 @@ func NewGame() (*game, error) { g := &game{ currentLevel: l, - camScale: 4, - camScaleTo: 4, + camScale: 2, + camScaleTo: 2, mousePanX: math.MinInt32, mousePanY: math.MinInt32, player: p, op: &ebiten.DrawImageOptions{}, } - g.player.x = 7 - g.player.y = 7 + g.player.x = float64(rand.Intn(108)) + g.player.y = float64(rand.Intn(108)) // Load SpriteSheets. g.ojasSS, err = LoadCharacterSpriteSheet() @@ -137,11 +137,13 @@ func NewGame() (*game, error) { if err != nil { return nil, err } + g.audioPlayerGunshot.SetVolume(0.6) g.audioPlayerGib, err = loadSound("assets/audio/gib.mp3") if err != nil { return nil, err } + g.audioPlayerGib.SetVolume(1.0) g.audioPlayerDie, err = loadSound("assets/audio/die.mp3") if err != nil { @@ -196,12 +198,12 @@ func NewGame() (*game, error) { // Update reads current user input and updates the game state. func (g *game) Update() error { - if ebiten.IsWindowBeingClosed() { + if ebiten.IsKeyPressed(ebiten.KeyEscape) || ebiten.IsWindowBeingClosed() { g.exit() return nil } - if g.player.health <= 0 { + if g.player.health <= 0 && !g.godMode { // Game over. return nil } @@ -227,8 +229,8 @@ func (g *game) Update() error { g.camScaleTo += scrollY * (g.camScaleTo / 7) // Clamp target zoom level. - if g.camScaleTo < 1 { - g.camScaleTo = 1 + if g.camScaleTo < 2 { + g.camScaleTo = 2 } else if g.camScaleTo > 4 { g.camScaleTo = 4 } @@ -243,6 +245,11 @@ func (g *game) Update() error { // Pan camera via keyboard. pan := 0.05 + // TODO debug only + if ebiten.IsKeyPressed(ebiten.KeyShift) { + pan *= 5 + } + if ebiten.IsKeyPressed(ebiten.KeyLeft) || ebiten.IsKeyPressed(ebiten.KeyA) { g.player.x -= pan } @@ -257,11 +264,7 @@ func (g *game) Update() error { } // Clamp camera position. - if g.player.y < 0.6 { - g.player.y = 0.6 - } else if g.player.y > float64(g.currentLevel.h)-1.4 { - g.player.y = float64(g.currentLevel.h) - 1.4 - } + g.player.x, g.player.y = g.currentLevel.Clamp(g.player.x, g.player.y) // Update player angle. cx, cy := ebiten.CursorPosition() @@ -275,24 +278,29 @@ func (g *game) Update() error { p.y += math.Sin(p.angle) * p.speed for _, c := range g.creeps { + if c.health == 0 { + continue + } + cx, cy := c.Position() dx, dy := deltaXY(p.x, p.y, cx, cy) if dx <= bulletHitThreshold && dy <= bulletHitThreshold { - // Kill gameCreep - g.addBloodSplatter(cx, cy) - c.x = 1000 - c.y = 1000 + c.health-- + + // Killed creep. + if c.health == 0 { + g.addBloodSplatter(cx, cy) + + // Play gib sound. + g.audioPlayerGib.Pause() + g.audioPlayerGib.Rewind() + g.audioPlayerGib.Play() + } // Remove projectile g.projectiles = append(g.projectiles[:i-removed], g.projectiles[i-removed+1:]...) removed++ - // Play gib sound. - g.audioPlayerGib.SetVolume(1.0) - g.audioPlayerGib.Pause() - g.audioPlayerGib.Rewind() - g.audioPlayerGib.Play() - break } } @@ -309,18 +317,19 @@ func (g *game) Update() error { } g.projectiles = append(g.projectiles, p) - v := 0.75 + (rand.Float64() / 4) - v = 0.6 // TODO - g.player.weapon.lastFire = time.Now() // Play gunshot sound. - g.audioPlayerGunshot.SetVolume(v) g.audioPlayerGunshot.Pause() g.audioPlayerGunshot.Rewind() g.audioPlayerGunshot.Play() } + // TODO debug only + if inpututil.IsKeyJustPressed(ebiten.KeyG) { + g.godMode = !g.godMode + } + return nil } @@ -363,7 +372,7 @@ func (g *game) addBloodSplatter(x, y float64) { // Draw draws the game on the screen. func (g *game) Draw(screen *ebiten.Image) { // Game over. - if g.player.health <= 0 { + if g.player.health <= 0 && !g.godMode { screen.Fill(color.RGBA{102, 0, 0, 255}) if time.Since(g.gameOverTime).Milliseconds()%2000 < 1500 { @@ -467,12 +476,16 @@ func (g *game) renderLevel(screen *ebiten.Image) int { biteThreshold := 0.5 for _, c := range g.creeps { + if c.health == 0 { + continue + } + cx, cy := c.Position() dx, dy := deltaXY(g.player.x, g.player.y, cx, cy) if dx <= biteThreshold && dy <= biteThreshold { g.player.health-- - if g.player.health == 0 { + if g.player.health == 0 && !g.godMode { ebiten.SetCursorShape(ebiten.CursorShapeDefault) g.gameOverTime = time.Now() diff --git a/level.go b/level.go index 9a3dc29..97aee89 100644 --- a/level.go +++ b/level.go @@ -28,15 +28,15 @@ func (l *Level) Size() (width, height int) { } func (l *Level) Clamp(x, y float64) (float64, float64) { - if x < 0 { - x = 0 - } else if x > float64(l.w)-1 { - x = float64(l.w) + if x < 0.3 { + x = 0.3 + } else if x > float64(l.w)-1.3 { + x = float64(l.w) - 1.3 } - if y < 0 { - y = 0 - } else if y > float64(l.h)-1 { - y = float64(l.h) + if y < 0.4 { + y = 0.4 + } else if y > float64(l.h)-1.8 { + y = float64(l.h) - 1.8 } return x, y }