From f88d5ab1ef168a7266551abe424f979bca9bbe62 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 28 May 2017 02:24:23 +0900 Subject: [PATCH] example: Use SourceRect (#277) --- examples/airship/main.go | 58 ++++++++++++---------------- examples/alphablending/main.go | 29 +++----------- examples/blocks/blocks/piece.go | 54 +++++++++++--------------- examples/blocks/blocks/titlescene.go | 45 ++++++--------------- examples/keyboard/main.go | 34 ++++++---------- examples/perspective/main.go | 43 +++++++-------------- 6 files changed, 91 insertions(+), 172 deletions(-) diff --git a/examples/airship/main.go b/examples/airship/main.go index b098c6993..252cadfe6 100644 --- a/examples/airship/main.go +++ b/examples/airship/main.go @@ -133,43 +133,35 @@ func updateGroundImage(ground *ebiten.Image) { ground.DrawImage(repeatedGophersImage, op) } -type groundParts struct { - image *ebiten.Image -} - -func (g *groundParts) Len() int { - _, h := g.image.Size() - return h -} - -func (g *groundParts) Src(i int) (int, int, int, int) { - w, _ := g.image.Size() - return 0, i, w, i + 1 -} - -func (g *groundParts) scaleForLine(x float64) float64 { - _, h := g.image.Size() - x = float64(h) - x - return 200*((-x+50)/(x+50)+1) - 200*((-float64(h)+50)/(float64(h)+50)+1) -} - -func (g *groundParts) Dst(i int) (int, int, int, int) { - w, _ := g.image.Size() - r := g.scaleForLine(float64(i)) - j1 := g.scaleForLine(float64(i)) - j2 := g.scaleForLine(float64(i + 1)) - return -int(r), int(j1), w + int(r), int(math.Ceil(j2)) +func scaleForLine(h int, x int) float64 { + x = h - x + return 200*((-float64(x)+50)/(float64(x)+50)+1) - 200*((-float64(h)+50)/(float64(h)+50)+1) } func drawGroundImage(screen *ebiten.Image, ground *ebiten.Image) { - w, _ := ground.Size() + w, h := ground.Size() op := &ebiten.DrawImageOptions{} - op.GeoM.Translate(-float64(w)/2, 0) - op.GeoM.Rotate(-1 * float64(thePlayer.lean) / maxLean * math.Pi / 8) - op.GeoM.Translate(float64(w)/2, 0) - op.GeoM.Translate(float64(screenWidth-w)/2, screenHeight/3) - op.ImageParts = &groundParts{ground} - screen.DrawImage(ground, op) + for i := 0; i < h; i++ { + op.GeoM.Reset() + // TODO: Refactoring + r := scaleForLine(h, i) + j1 := scaleForLine(h, i) + j2 := scaleForLine(h, i+1) + dx0, dy0, dx1, dy1 := -int(r), int(j1), w+int(r), int(math.Ceil(j2)) + sw := float64(dx1-dx0) / float64(w) + sh := float64(dy1 - dy0) + op.GeoM.Scale(sw, sh) + op.GeoM.Translate(float64(dx0), float64(dy0)) + + op.GeoM.Translate(-float64(w)/2, 0) + op.GeoM.Rotate(-1 * float64(thePlayer.lean) / maxLean * math.Pi / 8) + op.GeoM.Translate(float64(w)/2, 0) + op.GeoM.Translate(float64(screenWidth-w)/2, screenHeight/3) + + p := image.Rect(0, i, w, i+1) + op.SourceRect = &p + screen.DrawImage(ground, op) + } op = &ebiten.DrawImageOptions{} op.GeoM.Translate(-float64(w)/2, 0) op.GeoM.Rotate(-1 * float64(thePlayer.lean) / maxLean * math.Pi / 8) diff --git a/examples/alphablending/main.go b/examples/alphablending/main.go index 995045bae..90ebf3bf1 100644 --- a/examples/alphablending/main.go +++ b/examples/alphablending/main.go @@ -35,26 +35,6 @@ var ( ebitenImage *ebiten.Image ) -type imageParts struct { - diff float64 -} - -func (p *imageParts) Src(i int) (int, int, int, int) { - w, h := ebitenImage.Size() - return 0, 0, w, h -} - -func (p *imageParts) Dst(i int) (int, int, int, int) { - x := int(float64(i%10)*p.diff + 15) - y := int(float64(i/10)*p.diff + 20) - w, h := ebitenImage.Size() - return x, y, x + w, y + h -} - -func (p *imageParts) Len() int { - return 10 * 10 -} - func update(screen *ebiten.Image) error { count++ count %= ebiten.FPS * 10 @@ -71,10 +51,13 @@ func update(screen *ebiten.Image) error { screen.Fill(color.NRGBA{0x00, 0x00, 0x80, 0xff}) op := &ebiten.DrawImageOptions{} op.ColorM.Scale(1.0, 1.0, 1.0, 0.5) - op.ImageParts = &imageParts{ - diff: diff, + for i := 0; i < 10*10; i++ { + op.GeoM.Reset() + x := float64(i%10)*diff + 15 + y := float64(i/10)*diff + 20 + op.GeoM.Translate(x, y) + screen.DrawImage(ebitenImage, op) } - screen.DrawImage(ebitenImage, op) return nil } diff --git a/examples/blocks/blocks/piece.go b/examples/blocks/blocks/piece.go index 77f320202..d0aae4a37 100644 --- a/examples/blocks/blocks/piece.go +++ b/examples/blocks/blocks/piece.go @@ -17,6 +17,8 @@ package blocks import ( + "image" + "github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten/ebitenutil" ) @@ -146,41 +148,29 @@ var Pieces = map[BlockType]*Piece{ }, } -const blockWidth = 10 -const blockHeight = 10 -const fieldBlockNumX = 10 -const fieldBlockNumY = 20 - -type blocksImageParts [][]BlockType - -func (b blocksImageParts) Len() int { - return len(b) * len(b[0]) -} - -func (b blocksImageParts) Dst(i int) (x0, y0, x1, y1 int) { - i, j := i%len(b), i/len(b) - x := i * blockWidth - y := j * blockHeight - return x, y, x + blockWidth, y + blockHeight -} - -func (b blocksImageParts) Src(i int) (x0, y0, x1, y1 int) { - i, j := i%len(b), i/len(b) - block := b[i][j] - if block == BlockTypeNone { - return 0, 0, 0, 0 - } - x := (int(block) - 1) * blockWidth - return x, 0, x + blockWidth, blockHeight -} +const ( + blockWidth = 10 + blockHeight = 10 + fieldBlockNumX = 10 + fieldBlockNumY = 20 +) func drawBlocks(r *ebiten.Image, blocks [][]BlockType, x, y int, clr ebiten.ColorM) { - op := &ebiten.DrawImageOptions{ - ImageParts: blocksImageParts(blocks), - ColorM: clr, + op := &ebiten.DrawImageOptions{} + for j := 0; j < len(blocks[0]); j++ { + for i := 0; i < len(blocks); i++ { + op.GeoM.Reset() + op.GeoM.Translate(float64(i*blockWidth+x), float64(j*blockHeight+y)) + block := blocks[i][j] + if block == BlockTypeNone { + continue + } + x := (int(block) - 1) * blockWidth + p := image.Rect(x, 0, x+blockWidth, blockHeight) + op.SourceRect = &p + r.DrawImage(imageBlocks, op) + } } - op.GeoM.Translate(float64(x), float64(y)) - r.DrawImage(imageBlocks, op) } func (p *Piece) InitialPosition() (int, int) { diff --git a/examples/blocks/blocks/titlescene.go b/examples/blocks/blocks/titlescene.go index f3b775fef..e0b3bcb37 100644 --- a/examples/blocks/blocks/titlescene.go +++ b/examples/blocks/blocks/titlescene.go @@ -34,40 +34,12 @@ 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 *titleImageParts } func NewTitleScene() *TitleScene { - return &TitleScene{ - parts: &titleImageParts{imageBackground, 0}, - } + return &TitleScene{} } func anyGamepadAbstractButtonPressed(i *Input) bool { @@ -117,10 +89,17 @@ func (s *TitleScene) Draw(r *ebiten.Image) { } func (s *TitleScene) drawTitleBackground(r *ebiten.Image, c int) { - s.parts.count = c - r.DrawImage(imageBackground, &ebiten.DrawImageOptions{ - ImageParts: s.parts, - }) + w, h := imageBackground.Size() + op := &ebiten.DrawImageOptions{} + for i := 0; i < (ScreenWidth/w+1)*(ScreenHeight/h+2); i++ { + op.GeoM.Reset() + dx := (-c / 4) % w + dy := (c / 4) % h + dstX := (i%(ScreenWidth/w+1))*w + dx + dstY := (i/(ScreenWidth/w+1)-1)*h + dy + op.GeoM.Translate(float64(dstX), float64(dstY)) + r.DrawImage(imageBackground, op) + } } func drawLogo(r *ebiten.Image, str string) { diff --git a/examples/keyboard/main.go b/examples/keyboard/main.go index e226165b6..2747fb0ac 100644 --- a/examples/keyboard/main.go +++ b/examples/keyboard/main.go @@ -70,25 +70,6 @@ var keyNames = map[ebiten.Key]string{ ebiten.KeyAlt: "Alt", } -type pressedKeysParts []string - -func (p pressedKeysParts) Len() int { - return len(p) -} - -func (p pressedKeysParts) Dst(i int) (x0, y0, x1, y1 int) { - k := p[i] - r, ok := keyboard.KeyRect(k) - if !ok { - return 0, 0, 0, 0 - } - return r.Min.X, r.Min.Y, r.Max.X, r.Max.Y -} - -func (p pressedKeysParts) Src(i int) (x0, y0, x1, y1 int) { - return p.Dst(i) -} - func update(screen *ebiten.Image) error { if ebiten.IsRunningSlowly() { return nil @@ -121,11 +102,18 @@ func update(screen *ebiten.Image) error { } } - op = &ebiten.DrawImageOptions{ - ImageParts: pressedKeysParts(pressed), + op = &ebiten.DrawImageOptions{} + for _, p := range pressed { + op.GeoM.Reset() + r, ok := keyboard.KeyRect(p) + if !ok { + continue + } + op.GeoM.Translate(float64(r.Min.X), float64(r.Min.Y)) + op.GeoM.Translate(offsetX, offsetY) + op.SourceRect = &r + screen.DrawImage(keyboardImage, op) } - op.GeoM.Translate(offsetX, offsetY) - screen.DrawImage(keyboardImage, op) return nil } diff --git a/examples/perspective/main.go b/examples/perspective/main.go index 547a7711e..b4f543f7e 100644 --- a/examples/perspective/main.go +++ b/examples/perspective/main.go @@ -17,6 +17,7 @@ package main import ( + "image" _ "image/jpeg" "log" @@ -33,39 +34,25 @@ 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 { if ebiten.IsRunningSlowly() { return nil } - op := &ebiten.DrawImageOptions{ - ImageParts: &parts{gophersImage}, - } + op := &ebiten.DrawImageOptions{} w, h := gophersImage.Size() - maxWidth := float64(w) + float64(h)*0.75 - op.GeoM.Translate(-maxWidth/2, -float64(h)/2) - op.GeoM.Translate(screenWidth/2, screenHeight/2) - screen.DrawImage(gophersImage, op) + for i := 0; i < h; i++ { + op.GeoM.Reset() + width := w + i*3/4 + x := ((h - i) * 3 / 4) / 2 + op.GeoM.Scale(float64(width)/float64(w), 1) + op.GeoM.Translate(float64(x), float64(i)) + maxWidth := float64(w) + float64(h)*3/4 + op.GeoM.Translate(-maxWidth/2, -float64(h)/2) + op.GeoM.Translate(screenWidth/2, screenHeight/2) + p := image.Rect(0, i, w, i+1) + op.SourceRect = &p + screen.DrawImage(gophersImage, op) + } return nil }