Speed up: avoid allocating

This commit is contained in:
Hajime Hoshi 2015-01-03 23:20:17 +09:00
parent ea98fefc4f
commit 9bec0cf1c6
3 changed files with 26 additions and 25 deletions

View File

@ -15,12 +15,12 @@
package blocks package blocks
import ( import (
"errors"
"github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil" "github.com/hajimehoshi/ebiten/ebitenutil"
"image" "image"
"image/color" "image/color"
"math" "math"
"strings"
) )
var imageFont *ebiten.Image var imageFont *ebiten.Image
@ -41,11 +41,15 @@ func textWidth(str string) int {
return charWidth * len(str) return charWidth * len(str)
} }
var fontImageParts = make([]ebiten.ImagePart, 0, 256)
func drawText(rt *ebiten.Image, str string, ox, oy, scale int, c color.Color) error { func drawText(rt *ebiten.Image, str string, ox, oy, scale int, c color.Color) error {
parts := make([]ebiten.ImagePart, len(strings.Replace(str, "\n", "", -1))) if cap(fontImageParts) < len(str) {
return errors.New("str is too long")
}
parts := fontImageParts[:0]
locationX, locationY := 0, 0 locationX, locationY := 0, 0
i := 0
for _, c := range str { for _, c := range str {
if c == '\n' { if c == '\n' {
locationX = 0 locationX = 0
@ -55,9 +59,10 @@ func drawText(rt *ebiten.Image, str string, ox, oy, scale int, c color.Color) er
code := int(c) code := int(c)
x := (code % 16) * charWidth x := (code % 16) * charWidth
y := ((code - 32) / 16) * charHeight y := ((code - 32) / 16) * charHeight
parts[i].Dst = image.Rect(locationX, locationY, locationX+charWidth, locationY+charHeight) parts = append(parts, ebiten.ImagePart{
parts[i].Src = image.Rect(x, y, x+charWidth, y+charHeight) Dst: image.Rect(locationX, locationY, locationX+charWidth, locationY+charHeight),
i++ Src: image.Rect(x, y, x+charWidth, y+charHeight),
})
locationX += charWidth locationX += charWidth
} }

View File

@ -143,17 +143,10 @@ const blockHeight = 10
const fieldBlockNumX = 10 const fieldBlockNumX = 10
const fieldBlockNumY = 20 const fieldBlockNumY = 20
var blocksImageParts = make([]ebiten.ImagePart, 0, fieldBlockNumX*fieldBlockNumY)
func drawBlocks(r *ebiten.Image, blocks [][]BlockType, x, y int, clr ebiten.ColorM) error { func drawBlocks(r *ebiten.Image, blocks [][]BlockType, x, y int, clr ebiten.ColorM) error {
l := 0 parts := blocksImageParts[:0]
for _, blockCol := range blocks {
for _, block := range blockCol {
if block == BlockTypeNone {
continue
}
l++
}
}
parts := make([]ebiten.ImagePart, 0, l)
for i, blockCol := range blocks { for i, blockCol := range blocks {
for j, block := range blockCol { for j, block := range blockCol {
if block == BlockTypeNone { if block == BlockTypeNone {

View File

@ -33,10 +33,14 @@ func init() {
type TitleScene struct { type TitleScene struct {
count int count int
parts []ebiten.ImagePart
} }
func NewTitleScene() *TitleScene { func NewTitleScene() *TitleScene {
return &TitleScene{} w, h := imageBackground.Size()
return &TitleScene{
parts: make([]ebiten.ImagePart, (ScreenHeight/h+2)*(ScreenWidth/w+2)),
}
} }
func (s *TitleScene) Update(state *GameState) error { func (s *TitleScene) Update(state *GameState) error {
@ -48,7 +52,7 @@ func (s *TitleScene) Update(state *GameState) error {
} }
func (s *TitleScene) Draw(r *ebiten.Image) error { func (s *TitleScene) Draw(r *ebiten.Image) error {
if err := drawTitleBackground(r, s.count); err != nil { if err := s.drawTitleBackground(r, s.count); err != nil {
return err return err
} }
if err := drawLogo(r, "BLOCKS"); err != nil { if err := drawLogo(r, "BLOCKS"); err != nil {
@ -61,25 +65,24 @@ func (s *TitleScene) Draw(r *ebiten.Image) error {
return drawTextWithShadow(r, message, x, y, 1, color.NRGBA{0x80, 0, 0, 0xff}) return drawTextWithShadow(r, message, x, y, 1, color.NRGBA{0x80, 0, 0, 0xff})
} }
func drawTitleBackground(r *ebiten.Image, c int) error { func (s *TitleScene) drawTitleBackground(r *ebiten.Image, c int) error {
w, h := imageBackground.Size() w, h := imageBackground.Size()
dx := (-c / 4) % w dx := (-c / 4) % w
dy := (c / 4) % h dy := (c / 4) % h
parts := []ebiten.ImagePart{} index := 0
for j := -1; j < ScreenHeight/h+1; j++ { for j := -1; j < ScreenHeight/h+1; j++ {
for i := 0; i < ScreenWidth/w+1; i++ { for i := 0; i < ScreenWidth/w+1; i++ {
dstX := i*w + dx dstX := i*w + dx
dstY := j*h + dy dstY := j*h + dy
parts = append(parts, ebiten.ImagePart{ s.parts[index].Dst = image.Rect(dstX, dstY, dstX+w, dstY+h)
Dst: image.Rect(dstX, dstY, dstX+w, dstY+h), s.parts[index].Src = image.Rect(0, 0, w, h)
Src: image.Rect(0, 0, w, h), index++
})
} }
} }
return r.DrawImage(imageBackground, &ebiten.DrawImageOptions{ return r.DrawImage(imageBackground, &ebiten.DrawImageOptions{
Parts: parts, Parts: s.parts,
}) })
} }