Render multiple Z levels
Performance regression warning: this is now quite slow to render when showing all 7 Z levels. Bounds clipping may be enough to get it back to acceptable levels, or we may have to do something cleverer
This commit is contained in:
@@ -112,10 +112,10 @@ func (e *env) run() {
|
||||
})
|
||||
}
|
||||
|
||||
func (e *env) getSprite(palette []string, ref maps.ObjRef) (*conv.Sprite, *conv.Object) {
|
||||
func (e *env) getSprite(palette []string, ref maps.ObjRef) *conv.Sprite {
|
||||
if ref.Index() >= len(palette) {
|
||||
log.Printf("Palette too small: %v requested", ref.Index())
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
name := palette[ref.Index()]
|
||||
@@ -123,15 +123,15 @@ func (e *env) getSprite(palette []string, ref maps.ObjRef) (*conv.Sprite, *conv.
|
||||
obj := e.objects[name]
|
||||
if obj == nil {
|
||||
log.Printf("Failed to find surface sprite %#v -> %q", ref, name)
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
if ref.Frame() >= len(obj.Sprites) {
|
||||
log.Printf("Out-of-index sprite %v requested for %v", ref.Frame(), name)
|
||||
return nil, obj
|
||||
return nil
|
||||
}
|
||||
|
||||
return &obj.Sprites[ref.Frame()], obj
|
||||
return &obj.Sprites[ref.Frame()]
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -142,8 +142,6 @@ var (
|
||||
// TODO: build all the sprites in the set into a single spritesheet so we can
|
||||
// use pixel.Batch
|
||||
func (s *state) present(pWin *pixelgl.Window) {
|
||||
gameMap := s.env.gameMap
|
||||
|
||||
pWin.Clear(colornames.Black)
|
||||
|
||||
center := pWin.Bounds().Center()
|
||||
@@ -156,45 +154,56 @@ func (s *state) present(pWin *pixelgl.Window) {
|
||||
s.cam = cam
|
||||
pWin.SetMatrix(cam)
|
||||
|
||||
// TODO: bounds clipping
|
||||
z := int(s.zIdx)
|
||||
for y := int(gameMap.MinLength); y < int(gameMap.MaxLength); y++ {
|
||||
for x := int(gameMap.MinWidth); x < int(gameMap.MaxWidth); x++ {
|
||||
// TODO: we should be able to perform bounds clipping on these
|
||||
minX := int(s.env.gameMap.MinWidth)
|
||||
maxX := int(s.env.gameMap.MaxWidth)
|
||||
minY := int(s.env.gameMap.MinLength)
|
||||
maxY := int(s.env.gameMap.MaxLength)
|
||||
minZ := 0
|
||||
maxZ := int(s.zIdx) + 1
|
||||
|
||||
cell := gameMap.Cells.At(x, y, z)
|
||||
|
||||
surfaceSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Surface)
|
||||
centerSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Center)
|
||||
leftSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Left)
|
||||
rightSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Right)
|
||||
|
||||
fX := float64(x)
|
||||
fY := float64(y)
|
||||
|
||||
xPos := fX * cellWidth
|
||||
yPos := fY * cellLength
|
||||
|
||||
// The rotation translates the rectangular coordinates to diamond
|
||||
// ones \o/
|
||||
// FIXME: these are off by a bit
|
||||
orig := pixel.V(xPos, yPos)
|
||||
iso := pixel.V(orig.X-orig.Y, (orig.X+orig.Y)/2.0)
|
||||
|
||||
if surfaceSprite != nil {
|
||||
surfaceSprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
||||
for z := minZ; z < maxZ; z++ {
|
||||
for y := minY; y < maxY; y++ {
|
||||
for x := minX; x < maxX; x++ {
|
||||
s.renderCell(x, y, z, pWin)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if centerSprite != nil {
|
||||
centerSprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
||||
}
|
||||
func (s *state) renderCell(x, y, z int, pWin *pixelgl.Window) {
|
||||
var sprites []*conv.Sprite
|
||||
|
||||
if leftSprite != nil {
|
||||
leftSprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
||||
}
|
||||
cell := s.env.gameMap.Cells.At(x, y, z)
|
||||
|
||||
if rightSprite != nil {
|
||||
rightSprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
||||
}
|
||||
// Try optimizing zero surfaces out, they tend to be? all-transparent
|
||||
if cell.Surface.Index() != 0 {
|
||||
sprites = append(sprites, s.env.getSprite(s.env.set.Palette, cell.Surface))
|
||||
}
|
||||
|
||||
sprites = append(
|
||||
sprites,
|
||||
s.env.getSprite(s.env.set.Palette, cell.Center),
|
||||
s.env.getSprite(s.env.set.Palette, cell.Left),
|
||||
s.env.getSprite(s.env.set.Palette, cell.Right),
|
||||
)
|
||||
|
||||
// Taking the Z index away *seems* to draw the object in the correct place.
|
||||
// FIXME: There are some artifacts, investigate more
|
||||
fX := float64(x - z)
|
||||
fY := float64(y - z)
|
||||
|
||||
xPos := fX * cellWidth
|
||||
yPos := fY * cellLength
|
||||
|
||||
// The rotation translates the rectangular coordinates to diamond
|
||||
// ones \o/
|
||||
orig := pixel.V(xPos, yPos)
|
||||
iso := pixel.V(orig.X-orig.Y, (orig.X+orig.Y)/2.0)
|
||||
|
||||
for _, sprite := range sprites {
|
||||
if sprite != nil {
|
||||
sprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user