Files
survive/screens/primary.go

251 lines
6.0 KiB
Go
Raw Normal View History

package screens
import (
"math"
"mover/assets"
"mover/gamedata"
"mover/gameelement"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/audio"
"github.com/hajimehoshi/ebiten/v2/inpututil"
)
type Primary struct {
events map[ScreenManagerEvent]func()
dimensions gamedata.Area
elements []gameelement.GameElement
gameevents map[gamedata.GameEvent]bool
paused bool
gameover bool
musicInitialized bool
audioplayer *audio.Player
}
func NewPrimary() *Primary {
p := &Primary{
events: make(map[ScreenManagerEvent]func()),
paused: false,
gameover: false,
musicInitialized: false,
}
2024-11-16 12:31:22 -05:00
gamearea := gamedata.Area{Width: 640, Height: 480}
//initialize our layer map
p.gameevents = make(map[gamedata.GameEvent]bool)
2024-11-16 12:31:22 -05:00
//create background layer
p.elements = append(p.elements, gameelement.NewBackground(gamearea))
2024-11-16 12:31:22 -05:00
//create canvas (game) layer
canvas := gameelement.NewCanvas(gamearea)
canvas.RegisterEvents(gamedata.GameEventPlayerDeath, p.EventHandlerPlayerDeath)
canvas.RegisterEvents(gamedata.GameEventCharge, p.EventHandlerCharge)
canvas.RegisterEvents(gamedata.GameEventNewShot, p.EventHandlerNewShot)
canvas.RegisterEvents(gamedata.GameEventTargetHit, p.EventHandlerTargetHit)
canvas.RegisterEvents(gamedata.GameEventExplosion, p.EventHandlerExplosion)
canvas.RegisterEvents(gamedata.GameEventFireball, p.EventHandlerFireball)
p.elements = append(p.elements, canvas)
2024-11-23 01:13:55 -05:00
//rainlayer
rain := gameelement.NewRainLayer(gamearea)
rain.Initialize()
p.elements = append(p.elements, rain)
2024-11-16 12:31:22 -05:00
//create foreground cloud layer
clouds := gameelement.NewCloudLayer(gamearea)
clouds.Initialize()
p.elements = append(p.elements, clouds)
return p
}
func (p *Primary) Update() error {
if !p.musicInitialized {
s := audio.NewInfiniteLoop(assets.SoundBank[assets.MainLoop], assets.SoundBank[assets.MainLoop].Length())
p.audioplayer, _ = audioContext.NewPlayer(s)
p.audioplayer.Play()
p.musicInitialized = true
}
//collect all inputs
inputs := p.CollectInputs()
if inputs.Quit {
p.events[EventEndgame]()
}
if inputs.Reset {
p.Reset()
}
p.ProcessEventAudio()
if inputs.Start {
if p.gameover {
p.Reset()
} else {
p.TogglePause()
}
}
//primary game loop, for each element pass along the inputs
//and process its update logic
if !p.paused {
for _, ge := range p.elements {
ge.SetInputs(inputs)
ge.Update()
}
}
return nil
}
func (p *Primary) Draw(screen *ebiten.Image) {
//here we simply call each game elements draw function
//as a layer on top of each other
for _, ge := range p.elements {
ge.Draw(screen)
}
}
func (p *Primary) SetEventHandler(e ScreenManagerEvent, f func()) {
p.events[e] = f
}
func (p *Primary) SetDimensions(a gamedata.Area) {
p.dimensions = a
}
func (p *Primary) CollectInputs() gamedata.GameInputs {
if inpututil.IsKeyJustPressed(ebiten.KeyQ) {
p.events[EventEndgame]()
}
gi := gamedata.GameInputs{}
//axes
inpx := ebiten.GamepadAxisValue(0, 0)
inpy := ebiten.GamepadAxisValue(0, 1)
//handle wasd input
if ebiten.IsKeyPressed(ebiten.KeyD) {
inpx = 1
}
if ebiten.IsKeyPressed(ebiten.KeyA) {
inpx = -1
}
if ebiten.IsKeyPressed(ebiten.KeyS) {
inpy = 1
}
if ebiten.IsKeyPressed(ebiten.KeyW) {
inpy = -1
}
gi.XAxis = inpx
gi.YAxis = inpy
xaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickHorizontal)
yaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickVertical)
if yaxis <= 0.09 && yaxis >= -0.09 {
yaxis = 0
}
if xaxis <= 0.09 && xaxis >= -0.09 {
xaxis = 0
}
gi.ShotAngle = math.Atan2(yaxis, xaxis)
2024-11-21 16:26:25 -05:00
gi.CycleWeapon = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonFrontTopRight)
gi.Charge = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonRightStick)
gi.Start = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonCenterRight)
gi.Shot = ebiten.IsStandardGamepadButtonPressed(0, ebiten.StandardGamepadButtonFrontBottomRight)
gi.Quit = inpututil.IsKeyJustPressed(ebiten.KeyQ)
gi.Reset = inpututil.IsKeyJustPressed(ebiten.KeyR)
return gi
}
func (p *Primary) TogglePause() {
p.paused = !p.paused
var player *audio.Player
if p.paused {
player = audioContext.NewPlayerFromBytes(assets.PauseIn)
p.audioplayer.Pause()
} else {
player = audioContext.NewPlayerFromBytes(assets.PauseOut)
p.audioplayer.Play()
}
player.Play()
}
func (p *Primary) Reset() {
p.paused = false
p.gameover = false
for _, ge := range p.elements {
ge.Initialize()
}
}
func (p *Primary) ProcessEventAudio() {
for event, occurred := range p.gameevents {
if occurred {
p.PlayAudio(event)
p.gameevents[event] = false
}
}
}
func (p *Primary) PlayAudio(e gamedata.GameEvent) {
switch e {
case gamedata.GameEventPlayerDeath:
player := audioContext.NewPlayerFromBytes(assets.HeroDeath)
player.Play()
case gamedata.GameEventCharge:
player := audioContext.NewPlayerFromBytes(assets.Magic)
player.Play()
case gamedata.GameEventNewShot:
player := audioContext.NewPlayerFromBytes(assets.Shot)
player.Play()
case gamedata.GameEventTargetHit:
player := audioContext.NewPlayerFromBytes(assets.TargetHit)
player.Play()
case gamedata.GameEventExplosion:
player := audioContext.NewPlayerFromBytes(assets.Splode)
player.Play()
case gamedata.GameEventFireball:
player := audioContext.NewPlayerFromBytes(assets.Flare)
player.Play()
}
}
func (p *Primary) EventHandlerPlayerDeath() {
p.gameevents[gamedata.GameEventPlayerDeath] = true
p.gameover = true
}
func (p *Primary) EventHandlerCharge() {
p.gameevents[gamedata.GameEventCharge] = true
}
func (p *Primary) EventHandlerNewShot() {
p.gameevents[gamedata.GameEventNewShot] = true
}
func (p *Primary) EventHandlerTargetHit() {
p.gameevents[gamedata.GameEventTargetHit] = true
}
func (p *Primary) EventHandlerExplosion() {
p.gameevents[gamedata.GameEventExplosion] = true
}
func (p *Primary) EventHandlerFireball() {
p.gameevents[gamedata.GameEventFireball] = true
}