mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
example: Use SourceRect (#277)
This commit is contained in:
parent
e84b717c95
commit
f88d5ab1ef
@ -133,43 +133,35 @@ func updateGroundImage(ground *ebiten.Image) {
|
|||||||
ground.DrawImage(repeatedGophersImage, op)
|
ground.DrawImage(repeatedGophersImage, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
type groundParts struct {
|
func scaleForLine(h int, x int) float64 {
|
||||||
image *ebiten.Image
|
x = h - x
|
||||||
}
|
return 200*((-float64(x)+50)/(float64(x)+50)+1) - 200*((-float64(h)+50)/(float64(h)+50)+1)
|
||||||
|
|
||||||
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 drawGroundImage(screen *ebiten.Image, ground *ebiten.Image) {
|
func drawGroundImage(screen *ebiten.Image, ground *ebiten.Image) {
|
||||||
w, _ := ground.Size()
|
w, h := ground.Size()
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
op.GeoM.Translate(-float64(w)/2, 0)
|
for i := 0; i < h; i++ {
|
||||||
op.GeoM.Rotate(-1 * float64(thePlayer.lean) / maxLean * math.Pi / 8)
|
op.GeoM.Reset()
|
||||||
op.GeoM.Translate(float64(w)/2, 0)
|
// TODO: Refactoring
|
||||||
op.GeoM.Translate(float64(screenWidth-w)/2, screenHeight/3)
|
r := scaleForLine(h, i)
|
||||||
op.ImageParts = &groundParts{ground}
|
j1 := scaleForLine(h, i)
|
||||||
screen.DrawImage(ground, op)
|
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 = &ebiten.DrawImageOptions{}
|
||||||
op.GeoM.Translate(-float64(w)/2, 0)
|
op.GeoM.Translate(-float64(w)/2, 0)
|
||||||
op.GeoM.Rotate(-1 * float64(thePlayer.lean) / maxLean * math.Pi / 8)
|
op.GeoM.Rotate(-1 * float64(thePlayer.lean) / maxLean * math.Pi / 8)
|
||||||
|
@ -35,26 +35,6 @@ var (
|
|||||||
ebitenImage *ebiten.Image
|
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 {
|
func update(screen *ebiten.Image) error {
|
||||||
count++
|
count++
|
||||||
count %= ebiten.FPS * 10
|
count %= ebiten.FPS * 10
|
||||||
@ -71,10 +51,13 @@ func update(screen *ebiten.Image) error {
|
|||||||
screen.Fill(color.NRGBA{0x00, 0x00, 0x80, 0xff})
|
screen.Fill(color.NRGBA{0x00, 0x00, 0x80, 0xff})
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
op.ColorM.Scale(1.0, 1.0, 1.0, 0.5)
|
op.ColorM.Scale(1.0, 1.0, 1.0, 0.5)
|
||||||
op.ImageParts = &imageParts{
|
for i := 0; i < 10*10; i++ {
|
||||||
diff: diff,
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"image"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||||
)
|
)
|
||||||
@ -146,41 +148,29 @@ var Pieces = map[BlockType]*Piece{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const blockWidth = 10
|
const (
|
||||||
const blockHeight = 10
|
blockWidth = 10
|
||||||
const fieldBlockNumX = 10
|
blockHeight = 10
|
||||||
const fieldBlockNumY = 20
|
fieldBlockNumX = 10
|
||||||
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawBlocks(r *ebiten.Image, blocks [][]BlockType, x, y int, clr ebiten.ColorM) {
|
func drawBlocks(r *ebiten.Image, blocks [][]BlockType, x, y int, clr ebiten.ColorM) {
|
||||||
op := &ebiten.DrawImageOptions{
|
op := &ebiten.DrawImageOptions{}
|
||||||
ImageParts: blocksImageParts(blocks),
|
for j := 0; j < len(blocks[0]); j++ {
|
||||||
ColorM: clr,
|
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) {
|
func (p *Piece) InitialPosition() (int, int) {
|
||||||
|
@ -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 {
|
type TitleScene struct {
|
||||||
count int
|
count int
|
||||||
parts *titleImageParts
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTitleScene() *TitleScene {
|
func NewTitleScene() *TitleScene {
|
||||||
return &TitleScene{
|
return &TitleScene{}
|
||||||
parts: &titleImageParts{imageBackground, 0},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func anyGamepadAbstractButtonPressed(i *Input) bool {
|
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) {
|
func (s *TitleScene) drawTitleBackground(r *ebiten.Image, c int) {
|
||||||
s.parts.count = c
|
w, h := imageBackground.Size()
|
||||||
r.DrawImage(imageBackground, &ebiten.DrawImageOptions{
|
op := &ebiten.DrawImageOptions{}
|
||||||
ImageParts: s.parts,
|
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) {
|
func drawLogo(r *ebiten.Image, str string) {
|
||||||
|
@ -70,25 +70,6 @@ var keyNames = map[ebiten.Key]string{
|
|||||||
ebiten.KeyAlt: "Alt",
|
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 {
|
func update(screen *ebiten.Image) error {
|
||||||
if ebiten.IsRunningSlowly() {
|
if ebiten.IsRunningSlowly() {
|
||||||
return nil
|
return nil
|
||||||
@ -121,11 +102,18 @@ func update(screen *ebiten.Image) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
op = &ebiten.DrawImageOptions{
|
op = &ebiten.DrawImageOptions{}
|
||||||
ImageParts: pressedKeysParts(pressed),
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"image"
|
||||||
_ "image/jpeg"
|
_ "image/jpeg"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@ -33,39 +34,25 @@ var (
|
|||||||
gophersImage *ebiten.Image
|
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 {
|
func update(screen *ebiten.Image) error {
|
||||||
if ebiten.IsRunningSlowly() {
|
if ebiten.IsRunningSlowly() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
op := &ebiten.DrawImageOptions{
|
op := &ebiten.DrawImageOptions{}
|
||||||
ImageParts: &parts{gophersImage},
|
|
||||||
}
|
|
||||||
w, h := gophersImage.Size()
|
w, h := gophersImage.Size()
|
||||||
maxWidth := float64(w) + float64(h)*0.75
|
for i := 0; i < h; i++ {
|
||||||
op.GeoM.Translate(-maxWidth/2, -float64(h)/2)
|
op.GeoM.Reset()
|
||||||
op.GeoM.Translate(screenWidth/2, screenHeight/2)
|
width := w + i*3/4
|
||||||
screen.DrawImage(gophersImage, op)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user