gosl/data/level.go

204 lines
4.1 KiB
Go
Raw Normal View History

2016-02-06 01:48:29 +01:00
package data // code.bitsetter.de/fun/gosl/data
2016-02-07 00:16:30 +01:00
import (
"encoding/gob"
"log"
"os"
2016-02-08 19:54:28 +01:00
"sort"
2016-02-07 00:16:30 +01:00
)
type directionType int
const (
DIR_NULL directionType = iota // Undefined direction: NO Motion
DIR_SW //
DIR_S // NW N NE
DIR_SE // 7 8 9
DIR_W // W 4 5 6 E
DIR_NONE // 1 2 3
DIR_E // SW S SE
2016-02-08 15:29:43 +01:00
DIR_NW // only 4,5,6 supported
2016-02-07 00:16:30 +01:00
DIR_N
DIR_NE
)
type Direction interface {
Base() directionType
}
func (i directionType) Base() directionType { return i }
2016-02-06 01:48:29 +01:00
type Layer struct {
2016-02-07 00:16:30 +01:00
Z int `json:"Z-Index"`
D directionType `json:"Direction"`
S int `json:"Speed"`
T string `json:"Transparent"`
2016-02-08 21:58:33 +01:00
V int `json:"V-Offset"`
2016-02-07 00:16:30 +01:00
Repeat bool
Frames map[int]([][]rune)
2016-02-06 01:48:29 +01:00
}
type Level struct {
2016-02-07 00:16:30 +01:00
Name string
FPS int
Layers map[string]*Layer
2016-02-08 19:54:28 +01:00
lorder []zString // ordered key list (by z index)
2016-02-06 01:48:29 +01:00
}
2016-02-07 00:16:30 +01:00
//func (lvl *Level) AddLayer(z int, l *Layer) {
// lvl.Layers[z] = l
//}
2016-02-06 13:26:01 +01:00
2016-02-06 14:42:38 +01:00
func LoadLevel(filename string) *Level {
log.Println("Loading lvl", filename)
2016-02-07 00:16:30 +01:00
ret := &Level{}
file, err := os.Open(filename)
if err != nil {
log.Println("Error reading lvl:", err)
2016-02-07 00:16:30 +01:00
return nil
}
dec := gob.NewDecoder(file)
dec.Decode(ret)
//log.Println(ret.Layers["locomotive"])
return ret
2016-02-06 14:42:38 +01:00
}
2016-02-07 12:16:58 +01:00
2016-02-08 00:13:49 +01:00
// that's a func
2016-02-07 12:16:58 +01:00
func (lvl *Level) Height() int {
max := 0
for _, l := range lvl.Layers {
for _, f := range l.Frames {
2016-02-08 21:58:33 +01:00
if (len(f) + l.V) > max {
2016-02-07 12:16:58 +01:00
max = len(f)
}
}
}
return max
}
2016-02-08 15:29:43 +01:00
func (l *Layer) Width() (max int) {
max = 0
for _, frame := range l.Frames {
for _, row := range frame {
if len(row) > max {
max = len(row)
}
}
}
return
}
// Funzt so nicht: Layer liegen nicht zwingend übereinander
func (lvl *Level) Width() (max int) {
for _, lay := range lvl.Layers {
for _, fra := range lay.Frames {
for _, fra2 := range fra {
if len(fra2) > max {
max = len(fra2)
}
}
}
}
return
}
2016-02-08 19:54:28 +01:00
// Implement Sorter
type zString struct {
id string
z int
}
type ByZ []zString
2016-02-08 21:58:33 +01:00
func (a ByZ) Len() int { return len(a) }
2016-02-08 19:54:28 +01:00
func (a ByZ) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByZ) Less(i, j int) bool { return a[i].z < a[j].z }
func (lvl *Level) initOrder() {
if lvl.lorder == nil {
lvl.lorder = []zString{}
for k, v := range lvl.Layers {
lvl.lorder = append(lvl.lorder, zString{k, v.Z})
}
sort.Sort(ByZ(lvl.lorder))
sort.Reverse(ByZ(lvl.lorder))
}
}
2016-02-08 00:13:49 +01:00
//testcomment
2016-02-08 15:29:43 +01:00
func (lvl *Level) GetFrame(o, w, maxW, frameNo int) (ret *Frame) {
2016-02-08 19:54:28 +01:00
lvl.initOrder()
2016-02-07 12:16:58 +01:00
h := lvl.Height()
ret = &Frame{
W: w,
H: h,
}
2016-02-08 15:29:43 +01:00
// generate an array by initializing a slice and …
2016-02-08 00:13:49 +01:00
var mdata = make([]rune, w*h)
for y := 0; y < h; y++ {
2016-02-08 15:29:43 +01:00
// … let the resulting Frame data point into it:
2016-02-08 00:13:49 +01:00
ret.Data = append(ret.Data, mdata[y*w:(y+1)*w])
}
2016-02-07 12:16:58 +01:00
2016-02-08 19:54:28 +01:00
for zli, zl := range lvl.lorder {
layer := lvl.Layers[zl.id]
//for _, layer := range lvl.Layers {
//if layer.Z == 0 {
for row := 0; row < h; row++ {
//ret.Data = append(ret.Data, []rune{})
// which frame of the layer to use
f := (frameNo % len(layer.Frames)) + 1
off := 0
switch layer.D {
case 4:
off = (frameNo * layer.S) + o
case 5:
off = o
2016-02-08 19:54:28 +01:00
case 6:
off = -(frameNo * layer.S) + o
}
2016-02-08 19:13:05 +01:00
2016-02-08 19:54:28 +01:00
// max width
lW := layer.Width()
if !layer.Repeat {
lW += maxW
off += maxW
}
2016-02-08 19:13:05 +01:00
2016-02-08 19:54:28 +01:00
for off < 0 {
off += lW
}
off %= lW
2016-02-08 20:07:53 +01:00
// log.Println(lW, off, o, w, maxW, frameNo)
2016-02-08 19:54:28 +01:00
if row < len(layer.Frames[f]) {
r := layer.Frames[f][row][:]
for col := 0; col < w; col++ {
ro := (off + col) % lW
if 0 < ro && ro < len(r) && string(r[ro]) != layer.T {
ret.Data[row+layer.V][col] = r[ro]
2016-02-08 19:54:28 +01:00
} else {
if zli == 0 {
ret.Data[row+layer.V][col] = rune(' ')
2016-02-08 15:29:43 +01:00
}
}
2016-02-07 12:16:58 +01:00
}
2016-02-08 19:54:28 +01:00
//for col := 0
//log.Println(len(layer.Frames[f][row]))
//ret.Data[row] = append(ret.Data[row], (layer.Frames[f][row][off%w:])...)
2016-02-08 20:07:53 +01:00
} else {
if zli == 0 {
for col := 0; col < w; col++ {
ret.Data[row][col] = rune(' ')
}
}
2016-02-07 12:16:58 +01:00
}
}
2016-02-08 19:54:28 +01:00
//}
2016-02-07 12:16:58 +01:00
}
return
}