Use ImageParts

This commit is contained in:
Hajime Hoshi 2015-01-05 10:08:00 +09:00
parent cdc29210db
commit f697501531
4 changed files with 110 additions and 71 deletions

View File

@ -17,51 +17,70 @@ package ebitenutil
import ( import (
"github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/internal/assets" "github.com/hajimehoshi/ebiten/internal/assets"
"image"
"image/color" "image/color"
"math" "math"
"strings"
) )
type debugPrintImageParts string
func (f debugPrintImageParts) Len() int {
return len(f)
}
func (f debugPrintImageParts) Dst(i int) (x0, y0, x1, y1 int) {
cw, ch := assets.TextImageCharWidth, assets.TextImageCharHeight
x := i - strings.LastIndex(string(f)[:i], "\n") - 1
y := strings.Count(string(f)[:i], "\n")
x *= cw
y *= ch
if x < 0 {
return 0, 0, 0, 0
}
return x, y, x + cw, y + ch
}
func (f debugPrintImageParts) Src(i int) (x0, y0, x1, y1 int) {
cw, ch := assets.TextImageCharWidth, assets.TextImageCharHeight
const n = assets.TextImageWidth / assets.TextImageCharWidth
code := int(f[i])
if code == '\n' {
return 0, 0, 0, 0
}
x := (code % n) * cw
y := (code / n) * ch
return x, y, x + cw, y + ch
}
type debugPrintState struct { type debugPrintState struct {
textImage *ebiten.Image textImage *ebiten.Image
debugPrintRenderTarget *ebiten.Image debugPrintRenderTarget *ebiten.Image
y int
} }
var defaultDebugPrintState = new(debugPrintState) var defaultDebugPrintState = &debugPrintState{}
func DebugPrint(r *ebiten.Image, str string) { func DebugPrint(r *ebiten.Image, str string) {
defaultDebugPrintState.DebugPrint(r, str) defaultDebugPrintState.DebugPrint(r, str)
} }
func (d *debugPrintState) drawText(rt *ebiten.Image, str string, x, y int, c color.Color) { func (d *debugPrintState) drawText(rt *ebiten.Image, str string, x, y int, c color.Color) {
parts := []ebiten.ImagePart{} ur, ug, ub, ua := c.RGBA()
locationX, locationY := 0, 0 const max = math.MaxUint16
for _, c := range str { r := float64(ur) / max
if c == '\n' { g := float64(ug) / max
locationX = 0 b := float64(ub) / max
locationY += assets.TextImageCharHeight a := float64(ua) / max
continue if 0 < a {
r /= a
g /= a
b /= a
} }
code := int(c) op := &ebiten.DrawImageOptions{
const xCharNum = assets.TextImageWidth / assets.TextImageCharWidth ImageParts: debugPrintImageParts(str),
srcX := (code % xCharNum) * assets.TextImageCharWidth
srcY := (code / xCharNum) * assets.TextImageCharHeight
dst := image.Rect(locationX, locationY, locationX+assets.TextImageCharWidth, locationY+assets.TextImageCharHeight)
src := image.Rect(srcX, srcY, srcX+assets.TextImageCharWidth, srcY+assets.TextImageCharHeight)
parts = append(parts, ebiten.ImagePart{Dst: dst, Src: src})
locationX += assets.TextImageCharWidth
} }
cc := color.NRGBA64Model.Convert(c).(color.NRGBA64) op.GeoM.Translate(float64(x+1), float64(y))
r := float64(cc.R) / math.MaxUint16 op.ColorM.Scale(r, g, b, a)
g := float64(cc.G) / math.MaxUint16 rt.DrawImage(d.textImage, op)
b := float64(cc.B) / math.MaxUint16
a := float64(cc.A) / math.MaxUint16
rt.DrawImage(d.textImage, &ebiten.DrawImageOptions{
Parts: parts,
GeoM: ebiten.TranslateGeo(float64(x+1), float64(y)),
ColorM: ebiten.ScaleColor(r, g, b, a),
})
} }
// DebugPrint prints the given text str on the given image r. // DebugPrint prints the given text str on the given image r.
@ -84,7 +103,7 @@ func (d *debugPrintState) DebugPrint(r *ebiten.Image, str string) error {
return err return err
} }
} }
d.drawText(r, str, 1, d.y+1, color.NRGBA{0x00, 0x00, 0x00, 0x80}) d.drawText(r, str, 1, 1, color.NRGBA{0x00, 0x00, 0x00, 0x80})
d.drawText(r, str, 0, d.y, color.NRGBA{0xff, 0xff, 0xff, 0xff}) d.drawText(r, str, 0, 0, color.NRGBA{0xff, 0xff, 0xff, 0xff})
return nil return nil
} }

View File

@ -17,7 +17,6 @@ package blocks
import ( import (
"github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil" "github.com/hajimehoshi/ebiten/ebitenutil"
"image"
"image/color" "image/color"
) )
@ -31,15 +30,39 @@ func init() {
} }
} }
type titleImageParts struct {
image *ebiten.Image
count int
}
func (t *titleImageParts) Len() int {
w, h := t.image.Size()
return (ScreenWidth/w + 1) * (ScreenHeight/h + 2)
}
func (t *titleImageParts) Dst(i int) (x0, y0, x1, y1 int) {
w, h := t.image.Size()
i, j := i%(ScreenWidth/w+1), i/(ScreenWidth/w+1)-1
dx := (-t.count / 4) % w
dy := (t.count / 4) % h
dstX := i*w + dx
dstY := j*h + dy
return dstX, dstY, dstX + w, dstY + h
}
func (t *titleImageParts) Src(i int) (x0, y0, x1, y1 int) {
w, h := t.image.Size()
return 0, 0, w, h
}
type TitleScene struct { type TitleScene struct {
count int count int
parts []ebiten.ImagePart parts *titleImageParts
} }
func NewTitleScene() *TitleScene { func NewTitleScene() *TitleScene {
w, h := imageBackground.Size()
return &TitleScene{ return &TitleScene{
parts: make([]ebiten.ImagePart, (ScreenHeight/h+2)*(ScreenWidth/w+2)), parts: &titleImageParts{imageBackground, 0},
} }
} }
@ -66,23 +89,9 @@ func (s *TitleScene) Draw(r *ebiten.Image) error {
} }
func (s *TitleScene) drawTitleBackground(r *ebiten.Image, c int) error { func (s *TitleScene) drawTitleBackground(r *ebiten.Image, c int) error {
w, h := imageBackground.Size() s.parts.count = c
dx := (-c / 4) % w
dy := (c / 4) % h
index := 0
for j := -1; j < ScreenHeight/h+1; j++ {
for i := 0; i < ScreenWidth/w+1; i++ {
dstX := i*w + dx
dstY := j*h + dy
s.parts[index].Dst = image.Rect(dstX, dstY, dstX+w, dstY+h)
s.parts[index].Src = image.Rect(0, 0, w, h)
index++
}
}
return r.DrawImage(imageBackground, &ebiten.DrawImageOptions{ return r.DrawImage(imageBackground, &ebiten.DrawImageOptions{
Parts: s.parts, ImageParts: s.parts,
}) })
} }

View File

@ -17,7 +17,6 @@ package main
import ( import (
"github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil" "github.com/hajimehoshi/ebiten/ebitenutil"
"image"
_ "image/jpeg" _ "image/jpeg"
"log" "log"
) )
@ -31,24 +30,36 @@ var (
gophersImage *ebiten.Image gophersImage *ebiten.Image
) )
func update(screen *ebiten.Image) error { type parts struct {
parts := []ebiten.ImagePart{} image *ebiten.Image
w, h := gophersImage.Size() }
for i := 0; i < h; i++ {
func (p parts) Len() int {
_, h := p.image.Size()
return h
}
func (p parts) Dst(i int) (x0, y0, x1, y1 int) {
w, h := p.image.Size()
width := w + i*3/4 width := w + i*3/4
x := ((h - i) * 3 / 4) / 2 x := ((h - i) * 3 / 4) / 2
parts = append(parts, ebiten.ImagePart{ return x, i, x + width, i + 1
Dst: image.Rect(x, i, x+width, i+1), }
Src: image.Rect(0, i, w, i+1),
}) func (p parts) Src(i int) (x0, y0, x1, y1 int) {
w, _ := p.image.Size()
return 0, i, w, i + 1
}
func update(screen *ebiten.Image) error {
op := &ebiten.DrawImageOptions{
ImageParts: &parts{gophersImage},
} }
w, h := gophersImage.Size()
maxWidth := float64(w) + float64(h)*0.75 maxWidth := float64(w) + float64(h)*0.75
geo := ebiten.TranslateGeo(-maxWidth/2, -float64(h)/2) op.GeoM.Translate(-maxWidth/2, -float64(h)/2)
geo.Concat(ebiten.TranslateGeo(screenWidth/2, screenHeight/2)) op.GeoM.Translate(screenWidth/2, screenHeight/2)
screen.DrawImage(gophersImage, &ebiten.DrawImageOptions{ screen.DrawImage(gophersImage, op)
Parts: parts,
GeoM: geo,
})
return nil return nil
} }

View File

@ -169,7 +169,7 @@ func (i *Image) Fill(clr color.Color) (err error) {
// After determining parts to draw, this applies the geometry matrix and the color matrix. // After determining parts to draw, this applies the geometry matrix and the color matrix.
// //
// Here are the default values: // Here are the default values:
// Parts: (0, 0) - (source width, source height) to (0, 0) - (source width, source height) // ImageParts: (0, 0) - (source width, source height) to (0, 0) - (source width, source height)
// (i.e. the whole source image) // (i.e. the whole source image)
// GeoM: Identity matrix // GeoM: Identity matrix
// ColorM: Identity matrix (that changes no colors) // ColorM: Identity matrix (that changes no colors)