Add ui.Run

This commit is contained in:
Hajime Hoshi 2014-12-07 01:09:59 +09:00
parent d47dd79e1c
commit f0f77c1a2f
14 changed files with 70 additions and 114 deletions

1
.gitignore vendored
View File

@ -1,3 +1,2 @@
.DS_Store .DS_Store
*~ *~

View File

@ -93,7 +93,7 @@ func (f *Field) Flush() {
} }
} }
func (f *Field) Draw(context graphics.Context, textures Textures, geo matrix.Geometry) { func (f *Field) Draw(context graphics.Context, textures *Textures, geo matrix.Geometry) {
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))

View File

@ -17,12 +17,7 @@ func textWidth(str string) int {
return charWidth * len(str) return charWidth * len(str)
} }
func drawText( func drawText(context graphics.Context, textures *Textures, str string, x, y, scale int, clr color.Color) {
context graphics.Context,
textures Textures,
str string,
x, y, scale int,
clr color.Color) {
fontTextureId := textures.GetTexture("font") fontTextureId := textures.GetTexture("font")
parts := []graphics.TexturePart{} parts := []graphics.TexturePart{}
@ -53,12 +48,7 @@ func drawText(
context.Texture(fontTextureId).Draw(parts, geoMat, clrMat) context.Texture(fontTextureId).Draw(parts, geoMat, clrMat)
} }
func drawTextWithShadow( func drawTextWithShadow(context graphics.Context, textures *Textures, str string, x, y, scale int, clr color.Color) {
context graphics.Context,
textures Textures,
str string,
x, y, scale int,
clr color.Color) {
drawText(context, textures, str, x+1, y+1, scale, color.RGBA{0, 0, 0, 0x80}) drawText(context, textures, str, x+1, y+1, scale, color.RGBA{0, 0, 0, 0x80})
drawText(context, textures, str, x, y, scale, clr) drawText(context, textures, str, x, y, scale, clr)
} }

View File

@ -23,33 +23,28 @@ type GameState struct {
Input *Input Input *Input
} }
type Textures interface {
RequestTexture(name string, path string)
RequestRenderTarget(name string, size Size)
Has(name string) bool
GetTexture(name string) graphics.TextureId
GetRenderTarget(name string) graphics.RenderTargetId
}
type Game struct { type Game struct {
sceneManager *SceneManager sceneManager *SceneManager
input *Input input *Input
textures Textures textures *Textures
} }
func NewGame(textures Textures) *Game { func NewGame() *Game {
game := &Game{ game := &Game{
sceneManager: NewSceneManager(NewTitleScene()), sceneManager: NewSceneManager(NewTitleScene()),
input: NewInput(), input: NewInput(),
textures: textures,
} }
return game
}
func (game *Game) SetTextureFactory(textureFactory graphics.TextureFactory) {
game.textures = NewTextures(textureFactory)
for name, path := range texturePaths { for name, path := range texturePaths {
game.textures.RequestTexture(name, path) game.textures.RequestTexture(name, path)
} }
for name, size := range renderTargetSizes { for name, size := range renderTargetSizes {
game.textures.RequestRenderTarget(name, size) game.textures.RequestRenderTarget(name, size)
} }
return game
} }
func (game *Game) isInitialized() bool { func (game *Game) isInitialized() bool {

View File

@ -97,7 +97,7 @@ func (s *GameScene) Update(state *GameState) {
} }
} }
func (s *GameScene) Draw(context graphics.Context, textures Textures) { func (s *GameScene) Draw(context graphics.Context, textures *Textures) {
context.Fill(0xff, 0xff, 0xff) context.Fill(0xff, 0xff, 0xff)
field := textures.GetTexture("empty") field := textures.GetTexture("empty")
@ -108,24 +108,13 @@ func (s *GameScene) Draw(context graphics.Context, textures Textures) {
geoMat.Translate(20, 20) // magic number? geoMat.Translate(20, 20) // magic number?
colorMat := matrix.ColorI() colorMat := matrix.ColorI()
colorMat.Scale(color.RGBA{0, 0, 0, 0x80}) colorMat.Scale(color.RGBA{0, 0, 0, 0x80})
graphics.DrawWhole( graphics.DrawWhole(context.Texture(field), emptyWidth, emptyHeight, geoMat, colorMat)
context.Texture(field),
emptyWidth,
emptyHeight,
geoMat,
colorMat)
geoMat = matrix.GeometryI() geoMat = matrix.GeometryI()
geoMat.Translate(20, 20) geoMat.Translate(20, 20)
s.field.Draw(context, textures, geoMat) s.field.Draw(context, textures, geoMat)
if s.currentPiece != nil { if s.currentPiece != nil {
s.currentPiece.Draw( s.currentPiece.Draw(context, textures, 20, 20, s.currentPieceX, s.currentPieceY, s.currentPieceAngle)
context,
textures,
20, 20,
s.currentPieceX,
s.currentPieceY,
s.currentPieceAngle)
} }
} }

View File

@ -123,11 +123,7 @@ const blockHeight = 10
const fieldBlockNumX = 10 const fieldBlockNumX = 10
const fieldBlockNumY = 20 const fieldBlockNumY = 20
func drawBlocks( func drawBlocks(context graphics.Context, textures *Textures, blocks [][]BlockType, geo matrix.Geometry) {
context graphics.Context,
textures Textures,
blocks [][]BlockType,
geo matrix.Geometry) {
parts := []graphics.TexturePart{} parts := []graphics.TexturePart{}
for i, blockCol := range blocks { for i, blockCol := range blocks {
for j, block := range blockCol { for j, block := range blockCol {
@ -209,12 +205,7 @@ func (p *Piece) AbsorbInto(field *Field, x, y int, angle Angle) {
} }
} }
func (p *Piece) Draw( func (p *Piece) Draw(context graphics.Context, textures *Textures, fieldX, fieldY int, pieceX, pieceY int, angle Angle) {
context graphics.Context,
textures Textures,
fieldX, fieldY int,
pieceX, pieceY int,
angle Angle) {
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 {

View File

@ -14,7 +14,7 @@ func init() {
type Scene interface { type Scene interface {
Update(state *GameState) Update(state *GameState)
Draw(context graphics.Context, textures Textures) Draw(context graphics.Context, textures *Textures)
} }
const transitionMaxCount = 20 const transitionMaxCount = 20
@ -45,7 +45,7 @@ func (s *SceneManager) Update(state *GameState) {
} }
} }
func (s *SceneManager) Draw(context graphics.Context, textures Textures) { func (s *SceneManager) Draw(context graphics.Context, textures *Textures) {
if s.transitionCount == -1 { if s.transitionCount == -1 {
s.current.Draw(context, textures) s.current.Draw(context, textures)
return return

View File

@ -1,7 +1,6 @@
package main package blocks
import ( import (
"github.com/hajimehoshi/ebiten/example/blocks"
"github.com/hajimehoshi/ebiten/graphics" "github.com/hajimehoshi/ebiten/graphics"
"image" "image"
"os" "os"
@ -15,7 +14,7 @@ type namePath struct {
type nameSize struct { type nameSize struct {
name string name string
size blocks.Size size Size
} }
type Textures struct { type Textures struct {
@ -94,7 +93,7 @@ func (t *Textures) RequestTexture(name string, path string) {
t.texturePaths <- namePath{name, path} t.texturePaths <- namePath{name, path}
} }
func (t *Textures) RequestRenderTarget(name string, size blocks.Size) { func (t *Textures) RequestRenderTarget(name string, size Size) {
t.renderTargetSizes <- nameSize{name, size} t.renderTargetSizes <- nameSize{name, size}
} }

View File

@ -26,7 +26,7 @@ func (s *TitleScene) Update(state *GameState) {
} }
} }
func (s *TitleScene) Draw(context graphics.Context, textures Textures) { func (s *TitleScene) Draw(context graphics.Context, textures *Textures) {
drawTitleBackground(context, textures, s.count) drawTitleBackground(context, textures, s.count)
drawLogo(context, textures, "BLOCKS") drawLogo(context, textures, "BLOCKS")
@ -36,7 +36,7 @@ func (s *TitleScene) Draw(context graphics.Context, textures Textures) {
drawTextWithShadow(context, textures, message, x, y, 1, color.RGBA{0x80, 0, 0, 0xff}) drawTextWithShadow(context, textures, message, x, y, 1, color.RGBA{0x80, 0, 0, 0xff})
} }
func drawTitleBackground(context graphics.Context, textures Textures, c int) { func drawTitleBackground(context graphics.Context, textures *Textures, c int) {
const textureWidth = 32 const textureWidth = 32
const textureHeight = 32 const textureHeight = 32
@ -60,7 +60,7 @@ func drawTitleBackground(context graphics.Context, textures Textures, c int) {
context.Texture(backgroundTextureId).Draw(parts, geo, clr) context.Texture(backgroundTextureId).Draw(parts, geo, clr)
} }
func drawLogo(context graphics.Context, textures Textures, str string) { func drawLogo(context graphics.Context, textures *Textures, str string) {
scale := 4 scale := 4
textWidth := textWidth(str) * scale textWidth := textWidth(str) * scale
x := (ScreenWidth - textWidth) / 2 x := (ScreenWidth - textWidth) / 2

View File

@ -2,57 +2,17 @@ package main
import ( import (
"github.com/hajimehoshi/ebiten/example/blocks" "github.com/hajimehoshi/ebiten/example/blocks"
"github.com/hajimehoshi/ebiten/graphics"
"github.com/hajimehoshi/ebiten/ui" "github.com/hajimehoshi/ebiten/ui"
"github.com/hajimehoshi/ebiten/ui/glfw" "github.com/hajimehoshi/ebiten/ui/glfw"
"os"
"os/signal"
"runtime" "runtime"
"syscall"
"time"
) )
type Game interface {
Update(state ui.InputState)
Draw(c graphics.Context)
}
func init() { func init() {
runtime.LockOSThread() runtime.LockOSThread()
} }
func main() { func main() {
const screenWidth = blocks.ScreenWidth
const screenHeight = blocks.ScreenHeight
const screenScale = 2
const fps = 60
const frameTime = time.Duration(int64(time.Second) / int64(fps))
const title = "Ebiten Demo"
u := new(glfw.UI) u := new(glfw.UI)
canvas := u.CreateCanvas(screenWidth, screenHeight, screenScale, title) game := blocks.NewGame()
ui.Run(u, game, blocks.ScreenWidth, blocks.ScreenHeight, 2, "Ebiten Demo", 60)
textureFactory := u.TextureFactory()
game := blocks.NewGame(NewTextures(textureFactory))
tick := time.Tick(frameTime)
sigterm := make(chan os.Signal, 1)
signal.Notify(sigterm, os.Interrupt, syscall.SIGTERM)
u.Start()
defer u.Terminate()
for {
u.DoEvents()
select {
default:
canvas.Draw(game.Draw)
case <-tick:
game.Update(canvas.InputState())
if canvas.IsClosed() {
return
}
case <-sigterm:
return
}
}
} }

View File

@ -23,7 +23,7 @@ changed easily.
``` ```
:; cd $GOHOME/src/github.com/hajimehoshi/ebiten/example :; cd $GOHOME/src/github.com/hajimehoshi/ebiten/example
:; go run *.go :; go run main.go
``` ```
## License ## License

View File

@ -17,16 +17,13 @@ type UI struct {
canvas *Canvas canvas *Canvas
} }
func (u *UI) CreateCanvas(width, height, scale int, title string) ui.Canvas { func (u *UI) Start(width, height, scale int, title string) (ui.Canvas, graphics.TextureFactory) {
if !glfw.Init() { if !glfw.Init() {
panic("glfw.Init() fails") panic("glfw.Init() fails")
} }
glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.Resizable, glfw.False)
u.canvas = NewCanvas(width, height, scale, title) u.canvas = NewCanvas(width, height, scale, title)
return u.canvas return u.canvas, u.canvas
}
func (u *UI) Start() {
} }
func (u *UI) DoEvents() { func (u *UI) DoEvents() {
@ -37,7 +34,3 @@ func (u *UI) DoEvents() {
func (u *UI) Terminate() { func (u *UI) Terminate() {
glfw.Terminate() glfw.Terminate()
} }
func (u *UI) TextureFactory() graphics.TextureFactory {
return u.canvas
}

41
ui/run.go Normal file
View File

@ -0,0 +1,41 @@
package ui
import (
"github.com/hajimehoshi/ebiten/graphics"
"os"
"os/signal"
"syscall"
"time"
)
type Game interface {
Draw(context graphics.Context)
Update(inputState InputState)
SetTextureFactory(textureFactory graphics.TextureFactory)
}
func Run(u UI, game Game, width, height, scale int, title string, fps int) {
canvas, textureFactory := u.Start(width, height, scale, title)
game.SetTextureFactory(textureFactory)
frameTime := time.Duration(int64(time.Second) / int64(fps))
tick := time.Tick(frameTime)
sigterm := make(chan os.Signal, 1)
signal.Notify(sigterm, os.Interrupt, syscall.SIGTERM)
defer u.Terminate()
for {
u.DoEvents()
select {
default:
canvas.Draw(game.Draw)
case <-tick:
game.Update(canvas.InputState())
if canvas.IsClosed() {
return
}
case <-sigterm:
return
}
}
}

View File

@ -16,8 +16,7 @@ const (
) )
type UI interface { type UI interface {
CreateCanvas(widht, height, scale int, title string) Canvas Start(widht, height, scale int, title string) (Canvas, graphics.TextureFactory)
Start()
DoEvents() DoEvents()
Terminate() Terminate()
} }