-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsprite_sheet.go
90 lines (70 loc) · 2.02 KB
/
sprite_sheet.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// (c) 2022 Jacek Olszak
// This code is licensed under MIT license (see LICENSE for details)
package pi
import (
"bytes"
"errors"
"fmt"
"io/fs"
"github.com/elgopher/pi/image"
)
const (
SpriteHeight = 8
SpriteWidth = 8
)
var sprSheet = newSpriteSheet(defaultSpriteSheetWidth, defaultSpriteSheetHeight)
func loadSpriteSheet(resources fs.ReadFileFS) error {
fileContents, err := resources.ReadFile("sprite-sheet.png")
if errors.Is(err, fs.ErrNotExist) {
return nil
}
if err != nil {
return fmt.Errorf("error loading sprite-sheet.png file: %w", err)
}
if err = useSpriteSheet(fileContents); err != nil {
return fmt.Errorf("invalid sprite-sheet.png: %w", err)
}
return nil
}
func useSpriteSheet(b []byte) error {
img, err := image.DecodePNG(bytes.NewReader(b))
if err != nil {
return fmt.Errorf("error decoding file: %w", err)
}
Palette = img.Palette
sprSheet = newSpriteSheet(img.Width, img.Height)
copy(sprSheet.Pix(), img.Pix)
return nil
}
type spriteSheet struct {
PixMap
numberOfSprites int
spritesInLine int
}
// SprSheet returns the sprite-sheet PixMap
func SprSheet() PixMap {
return sprSheet.PixMap
}
const maxSpriteSheetSize = 65536
func newSpriteSheet(w int, h int) spriteSheet {
if w%8 != 0 || w == 0 {
panic(fmt.Sprintf("sprite sheet width %d is not a multiplication of 8", w))
}
if h%8 != 0 || h == 0 {
panic(fmt.Sprintf("sprite sheet height %d is not a multiplication of 8", h))
}
size := w * h
if size > maxSpriteSheetSize {
panic(fmt.Sprintf("number of pixels for sprite-sheet resolution %dx%d is higher than maximum %d. Please use a smaller one.", w, h, maxSpriteSheetSize))
}
return spriteSheet{
PixMap: NewPixMap(w, h),
numberOfSprites: size / (SpriteWidth * SpriteHeight),
spritesInLine: w / SpriteWidth,
}
}
// UseEmptySpriteSheet initializes empty sprite-sheet with given size. Could be used
// when you don't have sprite-sheet.png in resources. The maximum number of pixels is 65536 (64KB).
func UseEmptySpriteSheet(w, h int) {
sprSheet = newSpriteSheet(w, h)
}