Refactoring

This commit is contained in:
Hajime Hoshi 2014-12-29 13:36:29 +09:00
parent 47214fb572
commit f0277727d1
9 changed files with 57 additions and 72 deletions

View File

@ -17,10 +17,10 @@ package ebitenutil
import ( import (
"github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten"
"image" "image"
"image/png"
"os" "os"
) )
// NewImageFromFile loads the file path and returns ebiten.Image and image.Image.
func NewImageFromFile(path string, filter ebiten.Filter) (*ebiten.Image, image.Image, error) { func NewImageFromFile(path string, filter ebiten.Filter) (*ebiten.Image, image.Image, error) {
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {
@ -37,15 +37,3 @@ func NewImageFromFile(path string, filter ebiten.Filter) (*ebiten.Image, image.I
} }
return img2, img, err return img2, img, err
} }
func SaveImageAsPNG(path string, img *ebiten.Image) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
if err := png.Encode(file, img); err != nil {
return err
}
return nil
}

View File

@ -68,13 +68,6 @@ func update(screen *ebiten.Image) error {
} }
} }
if !saved && ebiten.IsKeyPressed(ebiten.KeySpace) {
if err := ebitenutil.SaveImageAsPNG("out.png", screen); err != nil {
return err
}
saved = true
}
return nil return nil
} }

View File

@ -110,11 +110,11 @@ func (f *Field) flushLine(j int) bool {
return true return true
} }
func (f *Field) Draw(r *ebiten.Image, x, y int) { func (f *Field) Draw(r *ebiten.Image, x, y int) error {
blocks := make([][]BlockType, len(f.blocks)) blocks := make([][]BlockType, len(f.blocks))
for i, blockCol := range f.blocks { for i, blockCol := range f.blocks {
blocks[i] = make([]BlockType, len(blockCol)) blocks[i] = make([]BlockType, len(blockCol))
copy(blocks[i], blockCol[:]) copy(blocks[i], blockCol[:])
} }
drawBlocks(r, blocks, x, y) return drawBlocks(r, blocks, x, y)
} }

View File

@ -19,11 +19,6 @@ import (
"sync" "sync"
) )
type Size struct {
Width int
Height int
}
const ScreenWidth = 256 const ScreenWidth = 256
const ScreenHeight = 240 const ScreenHeight = 240

View File

@ -54,7 +54,7 @@ const fieldWidth = blockWidth * fieldBlockNumX
const fieldHeight = blockHeight * fieldBlockNumY const fieldHeight = blockHeight * fieldBlockNumY
func (s *GameScene) choosePiece() *Piece { func (s *GameScene) choosePiece() *Piece {
num := NormalBlockTypeNum num := int(BlockTypeMax)
blockType := BlockType(s.rand.Intn(num) + 1) blockType := BlockType(s.rand.Intn(num) + 1)
return Pieces[blockType] return Pieces[blockType]
} }
@ -67,7 +67,7 @@ func (s *GameScene) initCurrentPiece(piece *Piece) {
s.currentPieceAngle = Angle0 s.currentPieceAngle = Angle0
} }
func (s *GameScene) Update(state *GameState) { func (s *GameScene) Update(state *GameState) error {
const maxLandingCount = 60 const maxLandingCount = 60
if s.currentPiece == nil { if s.currentPiece == nil {
@ -112,23 +112,31 @@ func (s *GameScene) Update(state *GameState) {
s.landingCount = 0 s.landingCount = 0
} }
} }
return nil
} }
func (s *GameScene) Draw(r *ebiten.Image) { func (s *GameScene) Draw(r *ebiten.Image) error {
r.Fill(color.White) if err := r.Fill(color.White); err != nil {
return err
}
field := imageEmpty field := imageEmpty
w, h := field.Size() w, h := field.Size()
geo := ebiten.ScaleGeo(float64(fieldWidth)/float64(w), float64(fieldHeight)/float64(h)) geo := ebiten.ScaleGeo(float64(fieldWidth)/float64(w), float64(fieldHeight)/float64(h))
geo.Concat(ebiten.TranslateGeo(20, 20)) // TODO: magic number? geo.Concat(ebiten.TranslateGeo(20, 20)) // TODO: magic number?
r.DrawImage(field, &ebiten.DrawImageOptions{ if err := r.DrawImage(field, &ebiten.DrawImageOptions{
GeoM: geo, GeoM: geo,
ColorM: ebiten.ScaleColor(0.0, 0.0, 0.0, 0.5), ColorM: ebiten.ScaleColor(0.0, 0.0, 0.0, 0.5),
}) }); err != nil {
return err
}
s.field.Draw(r, 20, 20) if err := s.field.Draw(r, 20, 20); err != nil {
return err
}
if s.currentPiece != nil { if s.currentPiece != nil {
s.currentPiece.Draw(r, 20, 20, s.currentPieceX, s.currentPieceY, s.currentPieceAngle) return s.currentPiece.Draw(r, 20, 20, s.currentPieceX, s.currentPieceY, s.currentPieceAngle)
} }
return nil
} }

View File

@ -27,9 +27,7 @@ func NewInput() *Input {
for key := ebiten.Key(0); key < ebiten.KeyMax; key++ { for key := ebiten.Key(0); key < ebiten.KeyMax; key++ {
states[key] = 0 states[key] = 0
} }
return &Input{ return &Input{states}
states: states,
}
} }
func (i *Input) StateForKey(key ebiten.Key) int { func (i *Input) StateForKey(key ebiten.Key) int {
@ -42,6 +40,6 @@ func (i *Input) Update() {
i.states[key] = 0 i.states[key] = 0
continue continue
} }
i.states[key] += 1 i.states[key]++
} }
} }

View File

@ -57,10 +57,9 @@ const (
BlockType5 BlockType5
BlockType6 BlockType6
BlockType7 BlockType7
BlockTypeMax = BlockType7
) )
const NormalBlockTypeNum = 7
type Piece struct { type Piece struct {
blockType BlockType blockType BlockType
blocks [][]bool blocks [][]bool
@ -144,7 +143,7 @@ const blockHeight = 10
const fieldBlockNumX = 10 const fieldBlockNumX = 10
const fieldBlockNumY = 20 const fieldBlockNumY = 20
func drawBlocks(r *ebiten.Image, blocks [][]BlockType, x, y int) { func drawBlocks(r *ebiten.Image, blocks [][]BlockType, x, y int) error {
parts := []ebiten.ImagePart{} parts := []ebiten.ImagePart{}
for i, blockCol := range blocks { for i, blockCol := range blocks {
for j, block := range blockCol { for j, block := range blockCol {
@ -160,7 +159,7 @@ func drawBlocks(r *ebiten.Image, blocks [][]BlockType, x, y int) {
}) })
} }
} }
r.DrawImage(imageBlocks, &ebiten.DrawImageOptions{ return r.DrawImage(imageBlocks, &ebiten.DrawImageOptions{
Parts: parts, Parts: parts,
}) })
} }
@ -222,7 +221,7 @@ func (p *Piece) AbsorbInto(field *Field, x, y int, angle Angle) {
} }
} }
func (p *Piece) Draw(r *ebiten.Image, fieldX, fieldY int, pieceX, pieceY int, angle Angle) { func (p *Piece) Draw(r *ebiten.Image, fieldX, fieldY int, pieceX, pieceY int, angle Angle) error {
size := len(p.blocks) size := len(p.blocks)
blocks := make([][]BlockType, size) blocks := make([][]BlockType, size)
for i := range p.blocks { for i := range p.blocks {
@ -236,5 +235,5 @@ func (p *Piece) Draw(r *ebiten.Image, fieldX, fieldY int, pieceX, pieceY int, an
x := fieldX + pieceX*blockWidth x := fieldX + pieceX*blockWidth
y := fieldY + pieceY*blockHeight y := fieldY + pieceY*blockHeight
drawBlocks(r, blocks, x, y) return drawBlocks(r, blocks, x, y)
} }

View File

@ -36,8 +36,8 @@ func init() {
} }
type Scene interface { type Scene interface {
Update(state *GameState) Update(state *GameState) error
Draw(r *ebiten.Image) Draw(screen *ebiten.Image) error
} }
const transitionMaxCount = 20 const transitionMaxCount = 20
@ -55,10 +55,9 @@ func NewSceneManager(initScene Scene) *SceneManager {
} }
} }
func (s *SceneManager) Update(state *GameState) { func (s *SceneManager) Update(state *GameState) error {
if s.transitionCount == -1 { if s.transitionCount == -1 {
s.current.Update(state) return s.current.Update(state)
return
} }
s.transitionCount++ s.transitionCount++
if transitionMaxCount <= s.transitionCount { if transitionMaxCount <= s.transitionCount {
@ -66,23 +65,29 @@ func (s *SceneManager) Update(state *GameState) {
s.next = nil s.next = nil
s.transitionCount = -1 s.transitionCount = -1
} }
return nil
} }
func (s *SceneManager) Draw(r *ebiten.Image) { func (s *SceneManager) Draw(r *ebiten.Image) error {
if s.transitionCount == -1 { if s.transitionCount == -1 {
s.current.Draw(r) return s.current.Draw(r)
return
} }
transitionFrom.Clear() transitionFrom.Clear()
s.current.Draw(transitionFrom) if err := s.current.Draw(transitionFrom); err != nil {
return err
}
transitionTo.Clear() transitionTo.Clear()
s.next.Draw(transitionTo) if err := s.next.Draw(transitionTo); err != nil {
return err
}
r.DrawImage(transitionFrom, nil) if err := r.DrawImage(transitionFrom, nil); err != nil {
return err
}
alpha := float64(s.transitionCount) / float64(transitionMaxCount) alpha := float64(s.transitionCount) / float64(transitionMaxCount)
r.DrawImage(transitionTo, &ebiten.DrawImageOptions{ return r.DrawImage(transitionTo, &ebiten.DrawImageOptions{
ColorM: ebiten.ScaleColor(1, 1, 1, alpha), ColorM: ebiten.ScaleColor(1, 1, 1, alpha),
}) })
} }

View File

@ -39,14 +39,15 @@ func NewTitleScene() *TitleScene {
return &TitleScene{} return &TitleScene{}
} }
func (s *TitleScene) Update(state *GameState) { func (s *TitleScene) Update(state *GameState) error {
s.count++ s.count++
if state.Input.StateForKey(ebiten.KeySpace) == 1 { if state.Input.StateForKey(ebiten.KeySpace) == 1 {
state.SceneManager.GoTo(NewGameScene()) state.SceneManager.GoTo(NewGameScene())
} }
return nil
} }
func (s *TitleScene) Draw(r *ebiten.Image) { func (s *TitleScene) Draw(r *ebiten.Image) error {
drawTitleBackground(r, s.count) drawTitleBackground(r, s.count)
drawLogo(r, "BLOCKS") drawLogo(r, "BLOCKS")
@ -54,29 +55,27 @@ func (s *TitleScene) Draw(r *ebiten.Image) {
x := (ScreenWidth - textWidth(message)) / 2 x := (ScreenWidth - textWidth(message)) / 2
y := ScreenHeight - 48 y := ScreenHeight - 48
drawTextWithShadow(r, message, x, y, 1, color.NRGBA{0x80, 0, 0, 0xff}) drawTextWithShadow(r, message, x, y, 1, color.NRGBA{0x80, 0, 0, 0xff})
return nil
} }
func drawTitleBackground(r *ebiten.Image, c int) { func drawTitleBackground(r *ebiten.Image, c int) {
const imageWidth = 32 w, h := imageBackground.Size()
const imageHeight = 32 dx := (-c / 4) % w
dy := (c / 4) % h
dx := (-c / 4) % imageWidth
dy := (c / 4) % imageHeight
backgroundImage := imageBackground
parts := []ebiten.ImagePart{} parts := []ebiten.ImagePart{}
for j := -1; j < ScreenHeight/imageHeight+1; j++ { for j := -1; j < ScreenHeight/h+1; j++ {
for i := 0; i < ScreenWidth/imageWidth+1; i++ { for i := 0; i < ScreenWidth/w+1; i++ {
dstX := i*imageWidth + dx dstX := i*w + dx
dstY := j*imageHeight + dy dstY := j*h + dy
parts = append(parts, ebiten.ImagePart{ parts = append(parts, ebiten.ImagePart{
Dst: image.Rect(dstX, dstY, dstX+imageWidth, dstY+imageHeight), Dst: image.Rect(dstX, dstY, dstX+w, dstY+h),
Src: image.Rect(0, 0, imageWidth, imageHeight), Src: image.Rect(0, 0, w, h),
}) })
} }
} }
r.DrawImage(backgroundImage, &ebiten.DrawImageOptions{ r.DrawImage(imageBackground, &ebiten.DrawImageOptions{
Parts: parts, Parts: parts,
}) })
} }