You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
5.0 KiB
217 lines
5.0 KiB
package asset |
|
|
|
import ( |
|
"bytes" |
|
"embed" |
|
"image" |
|
"image/color" |
|
"io" |
|
"math" |
|
|
|
"github.com/hajimehoshi/ebiten/v2/audio/wav" |
|
|
|
"github.com/hajimehoshi/ebiten/v2/audio" |
|
"github.com/hajimehoshi/ebiten/v2/audio/vorbis" |
|
|
|
"github.com/hajimehoshi/ebiten/v2" |
|
|
|
_ "image/png" |
|
) |
|
|
|
//go:embed image map sound |
|
var FS embed.FS |
|
|
|
var ImgWhiteSquare = newFilledImage(4, 4, color.White) |
|
|
|
var ImgBullet = newFilledImage(4, 4, color.RGBA{80, 142, 237, 255}) |
|
|
|
var ImgRobotTileset = LoadImage("image/robot-tileset/tileset.png") |
|
|
|
var ImgNewspaper = LoadImage("image/newspaper.png") |
|
|
|
const ( |
|
idleX, idleY = 208, 118 |
|
idleW, idleH = 16, 27 |
|
) |
|
|
|
var ImgPlayerIdle1 = ImgRobotTileset.SubImage(image.Rect(idleX, idleY, idleX+idleW, idleY+idleH)).(*ebiten.Image) |
|
var ImgPlayerIdle2 = ImgRobotTileset.SubImage(image.Rect(idleX+idleW, idleY, idleX+idleW+idleW, idleY+idleH)).(*ebiten.Image) |
|
var ImgPlayerIdle3 = ImgRobotTileset.SubImage(image.Rect(idleX+idleW*2, idleY, idleX+idleW*2+idleW, idleY+idleH)).(*ebiten.Image) |
|
var ImgPlayerIdle4 = ImgRobotTileset.SubImage(image.Rect(idleX+idleW*3, idleY, idleX+idleW*3+idleW, idleY+idleH)).(*ebiten.Image) |
|
|
|
var PlayerIdleFrames = []*ebiten.Image{ |
|
ImgPlayerIdle3, |
|
ImgPlayerIdle4, |
|
ImgPlayerIdle1, |
|
ImgPlayerIdle2, |
|
} |
|
|
|
var ImgPlayerIdle1Rot90 = rotate90(ImgPlayerIdle1) |
|
var ImgPlayerIdle2Rot90 = rotate90(ImgPlayerIdle2) |
|
var ImgPlayerIdle3Rot90 = rotate90(ImgPlayerIdle3) |
|
var ImgPlayerIdle4Rot90 = rotate90(ImgPlayerIdle4) |
|
|
|
var PlayerIdleFramesRot90 = []*ebiten.Image{ |
|
ImgPlayerIdle1Rot90, |
|
ImgPlayerIdle2Rot90, |
|
ImgPlayerIdle3Rot90, |
|
ImgPlayerIdle4Rot90, |
|
} |
|
|
|
const ( |
|
walkX, walkY = 288, 118 |
|
walkW, walkH = 16, 26 |
|
) |
|
|
|
var ImgPlayerWalk1 = ImgRobotTileset.SubImage(image.Rect(walkX, walkY, walkX+walkW, walkY+walkH)).(*ebiten.Image) |
|
var ImgPlayerWalk2 = ImgRobotTileset.SubImage(image.Rect(walkX+walkW, walkY, walkX+walkW+walkW, walkY+walkH)).(*ebiten.Image) |
|
var ImgPlayerWalk3 = ImgRobotTileset.SubImage(image.Rect(walkX+walkW*2, walkY, walkX+walkW*2+walkW, walkY+walkH)).(*ebiten.Image) |
|
var ImgPlayerWalk4 = ImgRobotTileset.SubImage(image.Rect(walkX+walkW*3, walkY, walkX+walkW*3+walkW, walkY+walkH)).(*ebiten.Image) |
|
|
|
var PlayerWalkFrames = []*ebiten.Image{ |
|
ImgPlayerWalk1, |
|
ImgPlayerWalk2, |
|
ImgPlayerWalk3, |
|
ImgPlayerWalk4, |
|
} |
|
|
|
var ImgPlayerWalk1Rot90 = rotate90(ImgPlayerWalk1) |
|
var ImgPlayerWalk2Rot90 = rotate90(ImgPlayerWalk2) |
|
var ImgPlayerWalk3Rot90 = rotate90(ImgPlayerWalk3) |
|
var ImgPlayerWalk4Rot90 = rotate90(ImgPlayerWalk4) |
|
|
|
var PlayerWalkFramesRot90 = []*ebiten.Image{ |
|
ImgPlayerWalk1Rot90, |
|
ImgPlayerWalk2Rot90, |
|
ImgPlayerWalk3Rot90, |
|
ImgPlayerWalk4Rot90, |
|
} |
|
|
|
const ( |
|
TileBeamOrange1 = 256 |
|
TileBeamOrange2 = 257 |
|
TileBeamOrange3 = 258 |
|
|
|
TileBeamBlue1 = 259 |
|
TileBeamBlue2 = 260 |
|
TileBeamBlue3 = 261 |
|
) |
|
|
|
var BeamTiles = []uint32{ |
|
TileBeamOrange1, |
|
TileBeamOrange2, |
|
TileBeamOrange3, |
|
TileBeamBlue1, |
|
TileBeamBlue2, |
|
TileBeamBlue3, |
|
} |
|
|
|
func rotate90(src *ebiten.Image) *ebiten.Image { |
|
bounds := src.Bounds() |
|
width, height := bounds.Dx(), bounds.Dy() |
|
img := ebiten.NewImage(height*2, width) |
|
op := &ebiten.DrawImageOptions{} |
|
op.GeoM.Translate(0, -float64(height)/2) |
|
op.GeoM.Rotate(math.Pi / 2) |
|
op.GeoM.Translate(float64(width)-4, 0) |
|
img.DrawImage(src, op) |
|
return img |
|
} |
|
|
|
func newFilledImage(w int, h int, c color.Color) *ebiten.Image { |
|
img := ebiten.NewImage(w, h) |
|
img.Fill(c) |
|
return img |
|
} |
|
|
|
func LoadImage(p string) *ebiten.Image { |
|
f, err := FS.Open(p) |
|
if err != nil { |
|
panic(err) |
|
} |
|
defer f.Close() |
|
|
|
baseImg, _, err := image.Decode(f) |
|
if err != nil { |
|
panic(err) |
|
} |
|
|
|
return ebiten.NewImageFromImage(baseImg) |
|
} |
|
|
|
func LoadBytes(p string) []byte { |
|
b, err := FS.ReadFile(p) |
|
if err != nil { |
|
panic(err) |
|
} |
|
return b |
|
} |
|
|
|
const sampleRate = 44100 |
|
|
|
var audioContext = audio.NewContext(sampleRate) |
|
|
|
var ( |
|
SoundFire = LoadWAV(audioContext, "sound/fire.wav") |
|
SoundHit = LoadWAV(audioContext, "sound/hit.wav") |
|
SoundExplode = LoadWAV(audioContext, "sound/explode.wav") |
|
SoundAlarm = LoadWAV(audioContext, "sound/alarm.wav") |
|
SoundMusic = LoadOGG(audioContext, "sound/mechanical_spider_theme.ogg", true) |
|
) |
|
|
|
func LoadWAV(context *audio.Context, p string) *audio.Player { |
|
f, err := FS.Open(p) |
|
if err != nil { |
|
panic(err) |
|
} |
|
defer f.Close() |
|
|
|
stream, err := wav.DecodeWithSampleRate(sampleRate, f) |
|
if err != nil { |
|
panic(err) |
|
} |
|
|
|
player, err := context.NewPlayer(stream) |
|
if err != nil { |
|
panic(err) |
|
} |
|
|
|
// Workaround to prevent delays when playing for the first time. |
|
player.SetVolume(0) |
|
player.Play() |
|
player.Pause() |
|
player.Rewind() |
|
player.SetVolume(1) |
|
|
|
return player |
|
} |
|
|
|
func LoadOGG(context *audio.Context, p string, loop bool) *audio.Player { |
|
b := LoadBytes(p) |
|
|
|
stream, err := vorbis.DecodeWithSampleRate(sampleRate, bytes.NewReader(b)) |
|
if err != nil { |
|
panic(err) |
|
} |
|
|
|
var s io.Reader |
|
if loop { |
|
s = audio.NewInfiniteLoop(stream, stream.Length()) |
|
} else { |
|
s = stream |
|
} |
|
|
|
player, err := context.NewPlayer(s) |
|
if err != nil { |
|
panic(err) |
|
} |
|
|
|
// Workaround to prevent delays when playing for the first time. |
|
player.SetVolume(0) |
|
player.Play() |
|
player.Pause() |
|
player.Rewind() |
|
player.SetVolume(1) |
|
|
|
return player |
|
}
|
|
|