Add sound effects and music
parent
5dc4cbb245
commit
659d8a86ea
|
@ -28,9 +28,10 @@ Please share issues and suggestions [here](https://code.rocketnine.space/tslocum
|
|||
## Credits
|
||||
|
||||
- [Trevor Slocum](https://rocketnine.space) - Game design and programming
|
||||
- [node punk](https://open.spotify.com/artist/15eFpWQPNRxB89PnFNWvjU?si=z-jfVwYHTxugaC-BGZiyNg) - Music
|
||||
- [node punk](https://soundcloud.com/solve_x) - Music
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [ebiten](https://github.com/hajimehoshi/ebiten) - Game engine
|
||||
- [gohan](https://code.rocketnine.space/tslocum/gohan) - Entity Component System framework
|
||||
- [go-tiled](https://github.com/lafriks/go-tiled) - Tiled map file (.TMX) parser
|
||||
|
|
|
@ -16,20 +16,46 @@ import (
|
|||
|
||||
const sampleRate = 44100
|
||||
|
||||
//go:embed image map
|
||||
//go:embed image map sound
|
||||
var FS embed.FS
|
||||
|
||||
var ImgWhiteSquare = ebiten.NewImage(128, 128)
|
||||
var ImgBlackSquare = ebiten.NewImage(128, 128)
|
||||
var ImgBlank = ebiten.NewImage(1, 1)
|
||||
|
||||
var SoundMusic *audio.Player
|
||||
var SoundSelect *audio.Player
|
||||
|
||||
var (
|
||||
SoundPop1 *audio.Player
|
||||
SoundPop2 *audio.Player
|
||||
SoundPop3 *audio.Player
|
||||
SoundPop4 *audio.Player
|
||||
SoundPop5 *audio.Player
|
||||
)
|
||||
|
||||
func init() {
|
||||
ImgWhiteSquare.Fill(color.White)
|
||||
ImgBlackSquare.Fill(color.Black)
|
||||
}
|
||||
|
||||
func LoadSounds(ctx *audio.Context) {
|
||||
// TODO
|
||||
SoundMusic = LoadOGG(ctx, "sound/we_will_build_it.ogg", true)
|
||||
SoundMusic.SetVolume(0.6)
|
||||
|
||||
SoundSelect = LoadWAV(ctx, "sound/select/select.wav")
|
||||
SoundSelect.SetVolume(0.6)
|
||||
|
||||
SoundPop1 = LoadWAV(ctx, "sound/pop/pop1.wav")
|
||||
SoundPop2 = LoadWAV(ctx, "sound/pop/pop2.wav")
|
||||
SoundPop3 = LoadWAV(ctx, "sound/pop/pop3.wav")
|
||||
SoundPop4 = LoadWAV(ctx, "sound/pop/pop4.wav")
|
||||
SoundPop5 = LoadWAV(ctx, "sound/pop/pop5.wav")
|
||||
SoundPop1.SetVolume(0.2)
|
||||
SoundPop2.SetVolume(0.2)
|
||||
SoundPop3.SetVolume(0.2)
|
||||
SoundPop4.SetVolume(0.2)
|
||||
SoundPop5.SetVolume(0.2)
|
||||
}
|
||||
|
||||
func LoadImage(p string) *ebiten.Image {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
67,67,67,67,
|
||||
67,67,67,67,
|
||||
67,67,67,67,
|
||||
67,67,527,67
|
||||
67,67,67,527
|
||||
</data>
|
||||
</layer>
|
||||
<layer id="2" name="2" width="4" height="4" offsetx="0" offsety="-80">
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
These sound clips were made available for use by onikage22 under the
|
||||
Creative Commons 0 License.
|
||||
|
||||
Source: https://freesound.org/people/onikage22/sounds/240566/
|
||||
|
||||
License: http://creativecommons.org/publicdomain/zero/1.0/
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
These sound clips were made available for use by soiboi under the
|
||||
Creative Commons 0 License.
|
||||
|
||||
Source: https://freesound.org/people/soiboi/sounds/556823/
|
||||
|
||||
License: http://creativecommons.org/publicdomain/zero/1.0/
|
Binary file not shown.
Binary file not shown.
1
flags.go
1
flags.go
|
@ -18,6 +18,7 @@ func parseFlags() {
|
|||
flag.BoolVar(&fullscreen, "fullscreen", false, "run in fullscreen mode")
|
||||
flag.BoolVar(&world.World.NativeResolution, "native", false, "display at native resolution")
|
||||
flag.BoolVar(&noSplash, "no-splash", false, "skip splash screen")
|
||||
flag.BoolVar(&world.World.MuteMusic, "mute-music", false, "mute music")
|
||||
flag.IntVar(&world.World.Debug, "debug", 0, "print debug information")
|
||||
flag.Parse()
|
||||
|
||||
|
|
|
@ -252,6 +252,7 @@ func (g *game) Draw(screen *ebiten.Image) {
|
|||
}
|
||||
var sprite *ebiten.Image
|
||||
colorScale := 1.0
|
||||
alpha := 1.0
|
||||
if tile.HoverSprite != nil {
|
||||
sprite = tile.HoverSprite
|
||||
colorScale = 0.6
|
||||
|
@ -260,12 +261,16 @@ func (g *game) Draw(screen *ebiten.Image) {
|
|||
}
|
||||
} else if tile.Sprite != nil {
|
||||
sprite = tile.Sprite
|
||||
// TODO
|
||||
/*if i > 0 && world.World.HoverStructure == world.StructureRoad {
|
||||
alpha = 0.6
|
||||
}*/
|
||||
} else if tile.EnvironmentSprite != nil {
|
||||
sprite = tile.EnvironmentSprite
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
drawn += g.renderSprite(float64(x), float64(y), 0, float64(i*-80), 0, 1, colorScale, 1, false, false, sprite, screen)
|
||||
drawn += g.renderSprite(float64(x), float64(y), 0, float64(i*-80), 0, 1, colorScale, alpha, false, false, sprite, screen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"os"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/audio"
|
||||
|
||||
"code.rocketnine.space/tslocum/citylimits/asset"
|
||||
|
||||
"code.rocketnine.space/tslocum/citylimits/component"
|
||||
"code.rocketnine.space/tslocum/citylimits/world"
|
||||
"code.rocketnine.space/tslocum/gohan"
|
||||
|
@ -78,7 +83,12 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyM) {
|
||||
// TODO mute sound
|
||||
world.World.MuteMusic = !world.World.MuteMusic
|
||||
if world.World.MuteMusic {
|
||||
asset.SoundMusic.Pause()
|
||||
} else {
|
||||
asset.SoundMusic.Play()
|
||||
}
|
||||
}
|
||||
|
||||
if world.World.GameOver {
|
||||
|
@ -119,10 +129,10 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
world.World.CamScale -= (world.World.CamScale - world.World.CamScaleTarget) / div
|
||||
}
|
||||
|
||||
pressLeft := ebiten.IsKeyPressed(ebiten.KeyLeft)
|
||||
pressRight := ebiten.IsKeyPressed(ebiten.KeyRight)
|
||||
pressUp := ebiten.IsKeyPressed(ebiten.KeyUp)
|
||||
pressDown := ebiten.IsKeyPressed(ebiten.KeyDown)
|
||||
pressLeft := ebiten.IsKeyPressed(ebiten.KeyLeft) || ebiten.IsKeyPressed(ebiten.KeyA)
|
||||
pressRight := ebiten.IsKeyPressed(ebiten.KeyRight) || ebiten.IsKeyPressed(ebiten.KeyD)
|
||||
pressUp := ebiten.IsKeyPressed(ebiten.KeyUp) || ebiten.IsKeyPressed(ebiten.KeyW)
|
||||
pressDown := ebiten.IsKeyPressed(ebiten.KeyDown) || ebiten.IsKeyPressed(ebiten.KeyS)
|
||||
|
||||
const camSpeed = 10
|
||||
if (pressLeft && !pressRight) ||
|
||||
|
@ -194,6 +204,8 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
} else {
|
||||
world.SetHoverStructure(button.StructureType)
|
||||
}
|
||||
asset.SoundSelect.Rewind()
|
||||
asset.SoundSelect.Play()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +225,19 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
world.World.Level.Tiles[i][int(tileX)][int(tileY)].EnvironmentSprite = img
|
||||
}
|
||||
} else {
|
||||
world.BuildStructure(world.World.HoverStructure, false, int(tileX), int(tileY))
|
||||
_, err := world.BuildStructure(world.World.HoverStructure, false, int(tileX), int(tileY))
|
||||
if err == nil {
|
||||
sounds := []*audio.Player{
|
||||
asset.SoundPop1,
|
||||
asset.SoundPop2,
|
||||
asset.SoundPop3,
|
||||
asset.SoundPop4,
|
||||
asset.SoundPop5,
|
||||
}
|
||||
sound := sounds[rand.Intn(len(sounds))]
|
||||
sound.Rewind()
|
||||
sound.Play()
|
||||
}
|
||||
}
|
||||
world.BuildStructure(world.World.HoverStructure, true, int(tileX), int(tileY))
|
||||
} else if int(tileX) != world.World.HoverX || int(tileY) != world.World.HoverY {
|
||||
|
|
|
@ -107,6 +107,9 @@ type GameWorld struct {
|
|||
|
||||
ResetGame bool
|
||||
|
||||
MuteMusic bool
|
||||
MuteSoundEffects bool // TODO
|
||||
|
||||
GotCursorPosition bool
|
||||
|
||||
tilesets []*ebiten.Image
|
||||
|
@ -292,16 +295,23 @@ func BuildStructure(structureType int, hover bool, placeX int, placeY int) (*Str
|
|||
// TODO Add entity
|
||||
|
||||
valid := true
|
||||
var existingRoadTiles int
|
||||
VALIDBUILD:
|
||||
for y := 0; y < m.Height; y++ {
|
||||
for x := 0; x < m.Width; x++ {
|
||||
tx, ty := (x+placeX)-w, (y+placeY)-h
|
||||
if structureType == StructureRoad && World.Level.Tiles[0][tx][ty].Sprite == World.TileImages[World.TileImagesFirstGID] {
|
||||
existingRoadTiles++
|
||||
}
|
||||
if World.Level.Tiles[1][tx][ty].Sprite != nil || (World.Level.Tiles[0][tx][ty].Sprite != nil && (structureType != StructureRoad || World.Level.Tiles[0][tx][ty].Sprite != World.TileImages[World.TileImagesFirstGID])) {
|
||||
valid = false
|
||||
break VALIDBUILD
|
||||
}
|
||||
}
|
||||
}
|
||||
if structureType == StructureRoad && existingRoadTiles == 4 {
|
||||
valid = false
|
||||
}
|
||||
if hover {
|
||||
World.HoverValid = valid
|
||||
} else if !valid {
|
||||
|
@ -412,6 +422,10 @@ func StartGame() {
|
|||
return
|
||||
}
|
||||
World.GameStarted = true
|
||||
|
||||
if !World.MuteMusic {
|
||||
asset.SoundMusic.Play()
|
||||
}
|
||||
}
|
||||
|
||||
func SetMessage(message string, duration int) {
|
||||
|
|
Loading…
Reference in New Issue