-
Notifications
You must be signed in to change notification settings - Fork 0
/
sprite.go
75 lines (59 loc) · 1.67 KB
/
sprite.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
package engine
import (
"errors"
"fmt"
"image"
"image/draw"
"strings"
)
// Sprite defines structure of single sprite
type Sprite struct {
Palette *Palette
Scanlines *[]int
}
// CreateSprite object based on a set of hex-encoded scanlines
func CreateSprite(palette *Palette, scanlines []int) (*Sprite, error) {
// Chec if scanlines consists of 32 hex groups
if len(scanlines) != 32 {
return nil, errors.New("Sprite not represented by the 32 hex groups required")
}
return &Sprite{
Palette: palette,
Scanlines: &scanlines,
}, nil
}
// Width gets the pixel width of the sprite
func (sprite *Sprite) Width() int {
return 16
}
// Height gets the pixel height of the sprite
func (sprite *Sprite) Height() int {
return 16
}
// AddToCanvas draws sprite to an existing image canvas
func (sprite *Sprite) AddToCanvas(canvas *image.RGBA, targetX int, targetY int, mirrorImage bool) {
// Return early if sprite coordinates of the off-canvas
if targetX+sprite.Width() < 0 || targetX > canvas.Bounds().Max.X || targetY+sprite.Height() < 0 || targetY > canvas.Bounds().Max.Y {
return
}
spriteImage := image.NewRGBA(image.Rect(0, 0, 16, 16))
for i, scanlines := range *sprite.Scanlines {
y := i
xOffset := 0
if (i % 2) != 0 {
y--
xOffset = 8
}
y /= 2
scanlinesString := fmt.Sprintf("%08x", scanlines)
scanlinePixels := strings.Split(scanlinesString, "")
for x, scanlinePixel := range scanlinePixels {
xPos := xOffset + x
if mirrorImage == true {
xPos = (15 - xPos)
}
spriteImage.Set(xPos, y, (*sprite.Palette)[scanlinePixel])
}
}
draw.Draw(canvas, spriteImage.Bounds().Add(image.Pt(targetX, targetY)), spriteImage, image.ZP, draw.Over)
}