Skip to content

Commit

Permalink
Enemies spawn
Browse files Browse the repository at this point in the history
  • Loading branch information
depsypher committed Jun 21, 2024
1 parent 43764ad commit 234a4e1
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 65 deletions.
14 changes: 7 additions & 7 deletions app/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ var (
time.Millisecond * time.Duration(9),
}
SpawnPoints = [][]int{
{230, 90}, // right
{230, 96}, // right
{132, 168}, // bottom
{109, 47}, // top
{16, 98}, // left
{109, 53}, // top
{16, 104}, // left
}
Controls = map[Control]ebiten.Key{
LeftButton: ebiten.KeyLeft,
Expand All @@ -51,26 +51,26 @@ var (
SoundButton: ebiten.KeyS,
}

White = color.NRGBA{
White = color.RGBA{
R: 255,
G: 255,
B: 255,
A: 255,
}
Grey = color.NRGBA{
Grey = color.RGBA{
R: 127,
G: 127,
B: 127,
A: 255,
}
Yellow = color.NRGBA{
Yellow = color.RGBA{
R: 255,
G: 255,
B: 86,
A: 255,
}

SpawnColors = []color.NRGBA{
SpawnColors = []color.RGBA{
White,
Grey,
Yellow,
Expand Down
104 changes: 85 additions & 19 deletions entity/buzzard.go
Original file line number Diff line number Diff line change
@@ -1,50 +1,116 @@
package entity

import (
"github.com/depsypher/gojoust/app"
"github.com/depsypher/gojoust/assets/audio"
"github.com/hajimehoshi/ebiten/v2"
"log"
"math/rand"
"time"
)

type Buzzard struct {
*Sprite
*MountSprite
bounder *ebiten.Image
lastAnimate time.Time
state PlayerState
}

func MakeBuzzard(ss *Sheet) *Buzzard {
return &Buzzard{
Sprite: MakeSprite(ss.Buzzard),
MountSprite: MakeMountSprite(ss.Buzzard),
bounder: ss.Bounder,
lastAnimate: time.Now(),
}
}

func (b *Buzzard) buildMount() *ebiten.Image {
image := ebiten.NewImageFromImage(b.Images[b.Frame])
op := ebiten.DrawImageOptions{}
op.GeoM.Translate(float64(6), float64(0))
image.DrawImage(b.bounder, &op)
return image
func (b *Buzzard) spawning(gs *GameState) {
if time.Now().Before(b.lastAnimate.Add(time.Millisecond * time.Duration(30))) {
return
}
if b.spawn <= 20 {
// emerging
b.buildSpawn(b, b.spawn)
b.spawn += 1
if b.spawn == 20 {
if err := gs.Sounds[audio.SpawnSound].Play(gs.SoundOn); err != nil {
log.Fatal("Error playing sound", err)
}
}
} else {
b.state = MOUNTED
b.image = b.buildMount()
b.spawn = 0
b.Vy = 1
}
b.lastAnimate = time.Now()
}

func (b *Buzzard) Draw(screen *ebiten.Image) {
s := b.Sprite
s.DrawSprite(screen)
func (b *Buzzard) buildMount() *ebiten.Image {
frame := b.Images[b.Frame]
composite := ebiten.NewImage(frame.Bounds().Dx(), frame.Bounds().Dy())

body := ebiten.NewImageFromImage(frame)
if b.state == SPAWNING {
col := app.SpawnColors[rand.Intn(3)]
body = b.drawSolid(composite.Bounds(), col, body)
}
// draw rider
op := ebiten.DrawImageOptions{}
y := 0
op.GeoM.Translate(float64(4), float64(y))
rider := ebiten.NewImageFromImage(b.bounder)
if b.state == SPAWNING {
col := app.SpawnColors[rand.Intn(3)]
rider = b.drawSolid(rider.Bounds(), col, rider)
}
composite.DrawImage(rider, &op)
op.GeoM.Reset()
composite.DrawImage(body, &op)
if !b.facingRight {
return b.flipX(composite, op)
}
return composite
}

func (b *Buzzard) Update(g *GameState) {
func (b *Buzzard) mounted(gs *GameState) {
if time.Now().After(b.lastAnimate.Add(time.Millisecond * time.Duration(500))) {
b.Frame += 1
if b.Frame == 5 {
b.Frame = 6
} else {
b.Frame = 5
}
b.lastAnimate = time.Now()
}
b.Frame = (b.Frame) % len(b.Images)
b.image = b.buildMount()
b.X += 1
if b.X > 300 {
b.X = float64(-b.Width)
}
b.Wrap()

b.Collisions(g.CliffAsSprites(), func(c *Sprite) {
// fmt.Printf("colliding %s\n", c.rect())
b.Collisions(gs.CliffAsSprites(), func(c *Sprite) {
//fmt.Printf("colliding %s\n", c.rect())
})
}

func (b *Buzzard) unmounted(gs *GameState) {
}

func (b *Buzzard) dead(gs *GameState) {
}

func (b *Buzzard) Draw(screen *ebiten.Image) {
s := b.Sprite
s.DrawSprite(screen)
}

func (b *Buzzard) Update(gs *GameState) {
switch b.state {
case SPAWNING:
b.spawning(gs)
case MOUNTED:
b.mounted(gs)
case UNMOUNTED:
b.unmounted(gs)
case DEAD:
b.dead(gs)
}
}
25 changes: 3 additions & 22 deletions entity/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,23 @@ const (
)

type Player struct {
*Sprite
*MountSprite
rider *ebiten.Image
lastAnimate time.Time
lastAccel time.Time
skid time.Time
xSpeed int
walking bool
facingRight bool
spawn int
flap int
walkStep bool
state PlayerState
}

func MakePlayer(ss *Sheet) *Player {
return &Player{
Sprite: MakeSprite(ss.Ostrich),
MountSprite: MakeMountSprite(ss.Ostrich),
rider: ss.P1Rider,
lastAnimate: time.Now(),
lastAccel: time.Now(),
skid: time.Time{},
facingRight: true,
}
}

Expand Down Expand Up @@ -70,7 +65,7 @@ func (p *Player) spawning(gs *GameState) {
}
if p.spawn <= 20 {
// emerging
p.buildSpawn(p.spawn)
p.buildSpawn(p, p.spawn)
p.spawn += 1
if p.spawn == 20 {
if err := gs.Sounds[audio.EnergizeSound].Play(gs.SoundOn); err != nil {
Expand Down Expand Up @@ -347,17 +342,3 @@ func (p *Player) buildMount() *ebiten.Image {
}
return composite
}

func (p *Player) buildSpawn(index int) {
p.Frame = 3
p.walking = true
mount := p.buildMount()
if p.image == nil {
p.image = ebiten.NewImage(mount.Bounds().Dx(), mount.Bounds().Dy())
} else {
p.image.Clear()
}
op := ebiten.DrawImageOptions{}
op.GeoM.Translate(float64(0), float64(mount.Bounds().Dy()-index))
p.image.DrawImage(mount, &op)
}
38 changes: 38 additions & 0 deletions entity/sprite.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ type Collider interface {
Collides()
}

type Mount interface {
buildMount() *ebiten.Image
}

type Sprite struct {
Images []*ebiten.Image
image *ebiten.Image
Expand All @@ -34,6 +38,14 @@ type Sprite struct {
center bool
}

type MountSprite struct {
*Sprite
flap int
spawn int
walking bool
facingRight bool
}

func MakeSprite(images []*ebiten.Image, pos ...float64) *Sprite {
position := []float64{0, 0}
if len(pos) == 2 {
Expand All @@ -50,6 +62,32 @@ func MakeSprite(images []*ebiten.Image, pos ...float64) *Sprite {
}
}

func MakeMountSprite(images []*ebiten.Image, pos ...float64) *MountSprite {
position := []float64{0, 0}
if len(pos) == 2 {
position = pos
}
return &MountSprite{
Sprite: MakeSprite(images, position[0], position[1]),
flap: 0,
facingRight: true,
}
}

func (p *MountSprite) buildSpawn(mount Mount, index int) {
p.Frame = 3
p.walking = true
m := mount.buildMount()
if p.image == nil {
p.image = ebiten.NewImage(m.Bounds().Dx(), m.Bounds().Dy())
} else {
p.image.Clear()
}
op := ebiten.DrawImageOptions{}
op.GeoM.Translate(float64(0), float64(m.Bounds().Dy()-index))
p.image.DrawImage(m, &op)
}

func (s *Sprite) drawSolid(bounds image.Rectangle, color color.Color, mask image.Image) *ebiten.Image {
img := ebiten.NewImage(bounds.Dx(), bounds.Dy())
img.Fill(color)
Expand Down
21 changes: 12 additions & 9 deletions entity/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@ package entity
import (
"github.com/depsypher/gojoust/app"
"github.com/depsypher/gojoust/assets/audio"
"time"
)

type GameObject interface {
Update(g *GameState)
}

type GameState struct {
Buzzards []*Buzzard
Cliffs []*Cliff
Player *Player
Keys map[app.Control]bool
GodMode bool
SoundOn bool
Pause bool
Debug string
Sounds audio.GameSounds
Buzzards []*Buzzard
Cliffs []*Cliff
Player *Player
Keys map[app.Control]bool
GodMode bool
SoundOn bool
Pause bool
Debug string
Sounds audio.GameSounds
WaveStart time.Time
NextSpawn time.Time
}

func (gs *GameState) CliffAsSprites() []*Sprite {
Expand Down
23 changes: 15 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
"log"
"math/rand"
"time"
)

var (
Expand All @@ -35,14 +37,9 @@ func (g *Game) init() {
defer func() {
g.inited = true
g.state = &entity.GameState{
Keys: make(map[app.Control]bool),
GodMode: false,
}

for i := 1; i < 2; i++ {
buzz := entity.MakeBuzzard(ss)
buzz.SetPos(app.ScreenWidth/2, app.ScreenHeight/(float64(i)+1))
// g.state.Buzzards = append(g.state.Buzzards, buzz)
Keys: make(map[app.Control]bool),
GodMode: false,
WaveStart: time.Now(),
}

g.state.Player = entity.MakePlayer(ss)
Expand Down Expand Up @@ -89,6 +86,16 @@ func (g *Game) Update() error {
g.state.SoundOn = !g.state.SoundOn
})

if time.Now().After(g.state.WaveStart.Add(time.Duration(3) * time.Second)) {
if len(g.state.Buzzards) < 3 && time.Now().After(g.state.NextSpawn) {
buzz := entity.MakeBuzzard(ss)
point := app.SpawnPoints[rand.Intn(len(app.SpawnPoints))]
buzz.SetPos(float64(point[0]), float64(point[1]))
g.state.Buzzards = append(g.state.Buzzards, buzz)
g.state.NextSpawn = time.Now().Add(time.Duration(1) * time.Second)
}
}

if !g.state.Pause {
g.state.Player.Update(g.state)
for _, b := range g.state.Buzzards {
Expand Down

0 comments on commit 234a4e1

Please sign in to comment.