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 (
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/internal/assets"
"image"
"image/color"
"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 {
textImage *ebiten.Image
debugPrintRenderTarget *ebiten.Image
y int
}
var defaultDebugPrintState = new(debugPrintState)
var defaultDebugPrintState = &debugPrintState{}
func DebugPrint(r *ebiten.Image, str string) {
defaultDebugPrintState.DebugPrint(r, str)
}
func (d *debugPrintState) drawText(rt *ebiten.Image, str string, x, y int, c color.Color) {
parts := []ebiten.ImagePart{}
locationX, locationY := 0, 0
for _, c := range str {
if c == '\n' {
locationX = 0
locationY += assets.TextImageCharHeight
continue
}
code := int(c)
const xCharNum = assets.TextImageWidth / assets.TextImageCharWidth
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
ur, ug, ub, ua := c.RGBA()
const max = math.MaxUint16
r := float64(ur) / max
g := float64(ug) / max
b := float64(ub) / max
a := float64(ua) / max
if 0 < a {
r /= a
g /= a
b /= a
}
cc := color.NRGBA64Model.Convert(c).(color.NRGBA64)
r := float64(cc.R) / math.MaxUint16
g := float64(cc.G) / math.MaxUint16
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),
})
op := &ebiten.DrawImageOptions{
ImageParts: debugPrintImageParts(str),
}
op.GeoM.Translate(float64(x+1), float64(y))
op.ColorM.Scale(r, g, b, a)
rt.DrawImage(d.textImage, op)
}
// 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
}
}
d.drawText(r, str, 1, d.y+1, color.NRGBA{0x00, 0x00, 0x00, 0x80})
d.drawText(r, str, 0, d.y, color.NRGBA{0xff, 0xff, 0xff, 0xff})
d.drawText(r, str, 1, 1, color.NRGBA{0x00, 0x00, 0x00, 0x80})
d.drawText(r, str, 0, 0, color.NRGBA{0xff, 0xff, 0xff, 0xff})
return nil
}

View File

@ -17,7 +17,6 @@ package blocks
import (
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil"
"image"
"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 {
count int
parts []ebiten.ImagePart
parts *titleImageParts
}
func NewTitleScene() *TitleScene {
w, h := imageBackground.Size()
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 {
w, h := imageBackground.Size()
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++
}
}
s.parts.count = c
return r.DrawImage(imageBackground, &ebiten.DrawImageOptions{
Parts: s.parts,
ImageParts: s.parts,
})
}

View File

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

View File

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