206 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package data /* import "udico.de/fun/gosl/data" */
 | |
| 
 | |
| import (
 | |
| 	"encoding/gob"
 | |
| 	"log"
 | |
| 	"os"
 | |
| 	"sort"
 | |
| )
 | |
| 
 | |
| 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
 | |
| 	DIR_NW                        //  only 4,5,6 supported
 | |
| 	DIR_N
 | |
| 	DIR_NE
 | |
| )
 | |
| 
 | |
| type Direction interface {
 | |
| 	Base() directionType
 | |
| }
 | |
| 
 | |
| func (i directionType) Base() directionType { return i }
 | |
| 
 | |
| type Layer struct {
 | |
| 	Z      int           `json:"Z-Index"`
 | |
| 	D      directionType `json:"Direction"`
 | |
| 	S      int           `json:"Speed"`
 | |
| 	T      string        `json:"Transparent"`
 | |
| 	V      int           `json:"V-Offset"`
 | |
| 	Repeat bool
 | |
| 	Frames map[int]([][]rune)
 | |
| }
 | |
| 
 | |
| type Level struct {
 | |
| 	Name   string
 | |
| 	FPS    int
 | |
| 	Layers map[string]*Layer
 | |
| 	lorder []zString // ordered key list (by z index)
 | |
| }
 | |
| 
 | |
| //func (lvl *Level) AddLayer(z int, l *Layer) {
 | |
| //	lvl.Layers[z] = l
 | |
| //}
 | |
| 
 | |
| func LoadLevel(filename string) *Level {
 | |
| 	log.Println("Loading lvl", filename)
 | |
| 	ret := &Level{}
 | |
| 	file, err := os.Open(filename)
 | |
| 	if err != nil {
 | |
| 		log.Println("Error reading lvl:", err)
 | |
| 		return nil
 | |
| 	}
 | |
| 	dec := gob.NewDecoder(file)
 | |
| 	dec.Decode(ret)
 | |
| 	//log.Println(ret.Layers["locomotive"])
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| // that's a func
 | |
| func (lvl *Level) Height() int {
 | |
| 	max := 0
 | |
| 	for _, l := range lvl.Layers {
 | |
| 		for _, f := range l.Frames {
 | |
| 			if (len(f) + l.V) > max {
 | |
| 				max = len(f) + l.V
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return max
 | |
| }
 | |
| 
 | |
| 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
 | |
| }
 | |
| 
 | |
| // Implement Sorter
 | |
| type zString struct {
 | |
| 	id string
 | |
| 	z  int
 | |
| }
 | |
| type ByZ []zString
 | |
| 
 | |
| func (a ByZ) Len() int           { return len(a) }
 | |
| 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))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //testcomment
 | |
| func (lvl *Level) GetFrame(o, w, maxW, frameNo int) (ret *Frame) {
 | |
| 	lvl.initOrder()
 | |
| 	h := lvl.Height()
 | |
| 
 | |
| 	ret = &Frame{
 | |
| 		W: w,
 | |
| 		H: h,
 | |
| 	}
 | |
| 
 | |
| 	// generate an array by initializing a slice and …
 | |
| 	var mdata = make([]rune, w*h)
 | |
| 	for y := 0; y < h; y++ {
 | |
| 		// … let the resulting Frame data point into it:
 | |
| 		ret.Data = append(ret.Data, mdata[y*w:(y+1)*w])
 | |
| 	}
 | |
| 
 | |
| 	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
 | |
| 			case 6:
 | |
| 				off = -(frameNo * layer.S) + o
 | |
| 			}
 | |
| 
 | |
| 			// max width
 | |
| 			lW := layer.Width()
 | |
| 			if !layer.Repeat {
 | |
| 				lW += maxW
 | |
| 				if layer.D != 0 {
 | |
| 					off += maxW
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			for off < 0 {
 | |
| 				off += lW
 | |
| 			}
 | |
| 			off %= lW
 | |
| 			// log.Println(lW, off, o, w, maxW, frameNo)
 | |
| 			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]
 | |
| 					} else {
 | |
| 						if zli == 0 {
 | |
| 							ret.Data[row+layer.V][col] = rune(' ')
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				//for col := 0
 | |
| 				//log.Println(len(layer.Frames[f][row]))
 | |
| 				//ret.Data[row] = append(ret.Data[row], (layer.Frames[f][row][off%w:])...)
 | |
| 			} else {
 | |
| 				if zli == 0 {
 | |
| 					for col := 0; col < w; col++ {
 | |
| 						ret.Data[row][col] = rune(' ')
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		//}
 | |
| 	}
 | |
| 
 | |
| 	return
 | |
| }
 | 
