Remove ebiten.GameContext

This commit is contained in:
Hajime Hoshi 2013-11-30 04:24:52 +09:00
parent 2a8af24518
commit da30a83491
10 changed files with 174 additions and 80 deletions

View File

@ -4,12 +4,6 @@ import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
) )
// TODO: Remove this
type GameContext interface {
ScreenWidth() int
ScreenHeight() int
}
type ScreenSizeUpdatedEvent struct { type ScreenSizeUpdatedEvent struct {
Width int Width int
Height int Height int
@ -20,17 +14,11 @@ type InputStateUpdatedEvent struct {
Y int Y int
} }
type UIEvents interface {
ScreenSizeUpdated() <-chan ScreenSizeUpdatedEvent
}
type UI interface { type UI interface {
PollEvents() PollEvents()
InitTextures(func(graphics.TextureFactory)) InitTextures(func(graphics.TextureFactory))
Draw(func(graphics.Canvas)) Draw(func(graphics.Canvas))
ScreenSizeUpdated() <-chan ScreenSizeUpdatedEvent
InputStateUpdated() <-chan InputStateUpdatedEvent InputStateUpdated() <-chan InputStateUpdatedEvent
// TODO: Remove this
Update(func(GameContext))
} }

View File

@ -1,7 +1,6 @@
package blank package blank
import ( import (
"github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
) )
@ -15,7 +14,7 @@ func New() *Blank {
func (game *Blank) InitTextures(tf graphics.TextureFactory) { func (game *Blank) InitTextures(tf graphics.TextureFactory) {
} }
func (game *Blank) Update(context ebiten.GameContext) { func (game *Blank) Update() {
} }
func (game *Blank) Draw(canvas graphics.Canvas) { func (game *Blank) Draw(canvas graphics.Canvas) {

View File

@ -10,22 +10,22 @@ import (
) )
type Input struct { type Input struct {
textTextureId graphics.TextureId textTextureId graphics.TextureId
inputStateCh chan ebiten.InputStateUpdatedEvent inputStateUpdatedCh chan ebiten.InputStateUpdatedEvent
x int x int
y int y int
} }
func New() *Input { func New() *Input {
return &Input{ return &Input{
inputStateCh: make(chan ebiten.InputStateUpdatedEvent, 1), inputStateUpdatedCh: make(chan ebiten.InputStateUpdatedEvent),
x: -1, x: -1,
y: -1, y: -1,
} }
} }
func (game *Input) InputStateUpdated() chan<- ebiten.InputStateUpdatedEvent { func (game *Input) InputStateUpdated() chan<- ebiten.InputStateUpdatedEvent {
return game.inputStateCh return game.inputStateUpdatedCh
} }
func (game *Input) InitTextures(tf graphics.TextureFactory) { func (game *Input) InitTextures(tf graphics.TextureFactory) {
@ -44,11 +44,11 @@ func (game *Input) InitTextures(tf graphics.TextureFactory) {
} }
} }
func (game *Input) Update(context ebiten.GameContext) { func (game *Input) Update() {
events: events:
for { for {
select { select {
case e := <-game.inputStateCh: case e := <-game.inputStateUpdatedCh:
game.x, game.y = e.X, e.Y game.x, game.y = e.X, e.Y
default: default:
break events break events

View File

@ -15,20 +15,28 @@ const (
) )
type Monochrome struct { type Monochrome struct {
ebitenTextureId graphics.TextureId ebitenTextureId graphics.TextureId
ch chan bool ch chan bool
colorMatrix matrix.Color colorMatrix matrix.Color
geometryMatrix matrix.Geometry geometryMatrix matrix.Geometry
screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
} }
func New() *Monochrome { func New() *Monochrome {
return &Monochrome{ return &Monochrome{
ch: make(chan bool), ch: make(chan bool),
colorMatrix: matrix.IdentityColor(), colorMatrix: matrix.IdentityColor(),
geometryMatrix: matrix.IdentityGeometry(), geometryMatrix: matrix.IdentityGeometry(),
screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent),
} }
} }
func (game *Monochrome) ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent {
return game.screenSizeUpdatedCh
}
func (game *Monochrome) InitTextures(tf graphics.TextureFactory) { func (game *Monochrome) InitTextures(tf graphics.TextureFactory) {
file, err := os.Open("images/ebiten.png") file, err := os.Open("images/ebiten.png")
if err != nil { if err != nil {
@ -90,13 +98,23 @@ func (game *Monochrome) update() {
} }
} }
func (game *Monochrome) Update(context ebiten.GameContext) { func (game *Monochrome) Update() {
events:
for {
select {
case e := <-game.screenSizeUpdatedCh:
game.screenWidth, game.screenHeight = e.Width, e.Height
default:
break events
}
}
game.ch <- true game.ch <- true
<-game.ch <-game.ch
game.geometryMatrix = matrix.IdentityGeometry() game.geometryMatrix = matrix.IdentityGeometry()
tx := context.ScreenWidth()/2 - ebitenTextureWidth/2 tx := game.screenWidth/2 - ebitenTextureWidth/2
ty := context.ScreenHeight()/2 - ebitenTextureHeight/2 ty := game.screenHeight/2 - ebitenTextureHeight/2
game.geometryMatrix.Translate(float64(tx), float64(ty)) game.geometryMatrix.Translate(float64(tx), float64(ty))
} }

View File

@ -17,6 +17,9 @@ type Rects struct {
offscreenInited bool offscreenInited bool
rectBounds *graphics.Rect rectBounds *graphics.Rect
rectColor *color.RGBA rectColor *color.RGBA
screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
} }
const ( const (
@ -32,9 +35,14 @@ func New() *Rects {
offscreenInited: false, offscreenInited: false,
rectBounds: &graphics.Rect{}, rectBounds: &graphics.Rect{},
rectColor: &color.RGBA{}, rectColor: &color.RGBA{},
screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent),
} }
} }
func (game *Rects) ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent {
return game.screenSizeUpdatedCh
}
func (game *Rects) InitTextures(tf graphics.TextureFactory) { func (game *Rects) InitTextures(tf graphics.TextureFactory) {
var err error var err error
game.rectTextureId, err = tf.CreateRenderTarget(rectTextureWidth, rectTextureHeight) game.rectTextureId, err = tf.CreateRenderTarget(rectTextureWidth, rectTextureHeight)
@ -61,11 +69,25 @@ func abs(a int) int {
return a return a
} }
func (game *Rects) Update(context ebiten.GameContext) { func (game *Rects) Update() {
x1 := rand.Intn(context.ScreenWidth()) events:
x2 := rand.Intn(context.ScreenWidth()) for {
y1 := rand.Intn(context.ScreenHeight()) select {
y2 := rand.Intn(context.ScreenHeight()) case e := <-game.screenSizeUpdatedCh:
game.screenWidth, game.screenHeight = e.Width, e.Height
default:
break events
}
}
if game.screenWidth == 0 || game.screenHeight == 0 {
return
}
x1 := rand.Intn(game.screenWidth)
x2 := rand.Intn(game.screenWidth)
y1 := rand.Intn(game.screenHeight)
y2 := rand.Intn(game.screenHeight)
game.rectBounds.X = min(x1, x2) game.rectBounds.X = min(x1, x2)
game.rectBounds.Y = min(y1, y2) game.rectBounds.Y = min(y1, y2)
game.rectBounds.Width = abs(x1 - x2) game.rectBounds.Width = abs(x1 - x2)

View File

@ -19,10 +19,19 @@ type Rotating struct {
ebitenTextureId graphics.TextureId ebitenTextureId graphics.TextureId
x int x int
geometryMatrix matrix.Geometry geometryMatrix matrix.Geometry
screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
} }
func New() *Rotating { func New() *Rotating {
return &Rotating{} return &Rotating{
screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent),
}
}
func (game *Rotating) ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent {
return game.screenSizeUpdatedCh
} }
func (game *Rotating) InitTextures(tf graphics.TextureFactory) { func (game *Rotating) InitTextures(tf graphics.TextureFactory) {
@ -41,7 +50,21 @@ func (game *Rotating) InitTextures(tf graphics.TextureFactory) {
} }
} }
func (game *Rotating) Update(context ebiten.GameContext) { func (game *Rotating) Update() {
events:
for {
select {
case e := <-game.screenSizeUpdatedCh:
game.screenWidth, game.screenHeight = e.Width, e.Height
default:
break events
}
}
if game.screenWidth == 0 || game.screenHeight == 0 {
return
}
const fps = 60 const fps = 60
game.x++ game.x++
@ -51,8 +74,8 @@ func (game *Rotating) Update(context ebiten.GameContext) {
game.geometryMatrix.Translate(-tx/2, -ty/2) game.geometryMatrix.Translate(-tx/2, -ty/2)
game.geometryMatrix.Rotate(float64(game.x) * 2 * math.Pi / float64(fps*10)) game.geometryMatrix.Rotate(float64(game.x) * 2 * math.Pi / float64(fps*10))
game.geometryMatrix.Translate(tx/2, ty/2) game.geometryMatrix.Translate(tx/2, ty/2)
centerX := float64(context.ScreenWidth()) / 2 centerX := float64(game.screenWidth) / 2
centerY := float64(context.ScreenHeight()) / 2 centerY := float64(game.screenHeight) / 2
game.geometryMatrix.Translate(centerX-tx/2, centerY-ty/2) game.geometryMatrix.Translate(centerX-tx/2, centerY-ty/2)
} }

View File

@ -66,13 +66,19 @@ func (sprite *Sprite) Update() {
type Sprites struct { type Sprites struct {
ebitenTextureId graphics.TextureId ebitenTextureId graphics.TextureId
sprites []*Sprite sprites []*Sprite
screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
} }
func New() *Sprites { func New() *Sprites {
go func() { return &Sprites{
screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent),
}
}
}() func (game *Sprites) ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent {
return &Sprites{} return game.screenSizeUpdatedCh
} }
func (game *Sprites) InitTextures(tf graphics.TextureFactory) { func (game *Sprites) InitTextures(tf graphics.TextureFactory) {
@ -91,13 +97,27 @@ func (game *Sprites) InitTextures(tf graphics.TextureFactory) {
} }
} }
func (game *Sprites) Update(context ebiten.GameContext) { func (game *Sprites) Update() {
events:
for {
select {
case e := <-game.screenSizeUpdatedCh:
game.screenWidth, game.screenHeight = e.Width, e.Height
default:
break events
}
}
if game.screenWidth == 0 || game.screenHeight == 0 {
return
}
if game.sprites == nil { if game.sprites == nil {
game.sprites = []*Sprite{} game.sprites = []*Sprite{}
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
sprite := newSprite( sprite := newSprite(
context.ScreenWidth(), game.screenWidth,
context.ScreenHeight(), game.screenHeight,
ebitenTextureWidth, ebitenTextureWidth,
ebitenTextureHeight) ebitenTextureHeight)
game.sprites = append(game.sprites, sprite) game.sprites = append(game.sprites, sprite)

View File

@ -1,7 +1,6 @@
package testpattern package testpattern
import ( import (
"github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/matrix"
"image" "image"
@ -40,7 +39,7 @@ func (game *TestPattern) InitTextures(tf graphics.TextureFactory) {
game.textureHeight = size.Y game.textureHeight = size.Y
} }
func (game *TestPattern) Update(context ebiten.GameContext) { func (game *TestPattern) Update() {
geo := matrix.IdentityGeometry() geo := matrix.IdentityGeometry()
geo.Translate(13, 13) geo.Translate(13, 13)
game.geos = append(game.geos, geo) game.geos = append(game.geos, geo)

View File

@ -19,7 +19,7 @@ import (
type Game interface { type Game interface {
InitTextures(tf graphics.TextureFactory) InitTextures(tf graphics.TextureFactory)
Update(context ebiten.GameContext) Update()
Draw(canvas graphics.Canvas) Draw(canvas graphics.Canvas)
} }
@ -66,25 +66,33 @@ func main() {
tick := time.Tick(frameTime) tick := time.Tick(frameTime)
for { for {
<-tick <-tick
ui.Update(func(c ebiten.GameContext) { func() {
lock.Lock() lock.Lock()
defer lock.Unlock() defer lock.Unlock()
game.Update(c) game.Update()
}) }()
} }
}() }()
inputStateUpdated := ui.InputStateUpdated() inputStateUpdated := ui.InputStateUpdated()
screenSizeUpdated := ui.ScreenSizeUpdated()
for { for {
ui.PollEvents() ui.PollEvents()
events: events:
for { for {
select { select {
case e := <-screenSizeUpdated:
type Handler interface {
ScreenSizeUpdated() chan<- ebiten.ScreenSizeUpdatedEvent
}
if game2, ok := game.(Handler); ok {
game2.ScreenSizeUpdated() <- e
}
case e := <-inputStateUpdated: case e := <-inputStateUpdated:
type InputStateUpdatedHandler interface { type Handler interface {
InputStateUpdated() chan<- ebiten.InputStateUpdatedEvent InputStateUpdated() chan<- ebiten.InputStateUpdatedEvent
} }
if game2, ok := game.(InputStateUpdatedHandler); ok { if game2, ok := game.(Handler); ok {
game2.InputStateUpdated() <- e game2.InputStateUpdated() <- e
} }
default: default:

View File

@ -27,28 +27,17 @@ func init() {
runtime.LockOSThread() runtime.LockOSThread()
} }
type GameContext struct {
screenWidth int
screenHeight int
}
func (context *GameContext) ScreenWidth() int {
return context.screenWidth
}
func (context *GameContext) ScreenHeight() int {
return context.screenHeight
}
type UI struct { type UI struct {
screenWidth int screenWidth int
screenHeight int screenHeight int
screenScale int screenScale int
graphicsDevice *opengl.Device graphicsDevice *opengl.Device
gameContext *GameContext
window unsafe.Pointer window unsafe.Pointer
initialEventSent bool
inputStateUpdatedChs chan chan ebiten.InputStateUpdatedEvent inputStateUpdatedChs chan chan ebiten.InputStateUpdatedEvent
inputStateUpdatedNotified chan ebiten.InputStateUpdatedEvent inputStateUpdatedNotified chan ebiten.InputStateUpdatedEvent
screenSizeUpdatedChs chan chan ebiten.ScreenSizeUpdatedEvent
screenSizeUpdatedNotified chan ebiten.ScreenSizeUpdatedEvent
} }
var currentUI *UI var currentUI *UI
@ -61,12 +50,11 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
screenWidth: screenWidth, screenWidth: screenWidth,
screenHeight: screenHeight, screenHeight: screenHeight,
screenScale: screenScale, screenScale: screenScale,
gameContext: &GameContext{ initialEventSent: false,
screenWidth: screenWidth,
screenHeight: screenHeight,
},
inputStateUpdatedChs: make(chan chan ebiten.InputStateUpdatedEvent), inputStateUpdatedChs: make(chan chan ebiten.InputStateUpdatedEvent),
inputStateUpdatedNotified: make(chan ebiten.InputStateUpdatedEvent), inputStateUpdatedNotified: make(chan ebiten.InputStateUpdatedEvent),
screenSizeUpdatedChs: make(chan chan ebiten.ScreenSizeUpdatedEvent),
screenSizeUpdatedNotified: make(chan ebiten.ScreenSizeUpdatedEvent),
} }
cTitle := C.CString(title) cTitle := C.CString(title)
@ -94,6 +82,7 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
func (ui *UI) chLoop() { func (ui *UI) chLoop() {
inputStateUpdated := []chan ebiten.InputStateUpdatedEvent{} inputStateUpdated := []chan ebiten.InputStateUpdatedEvent{}
screenSizeUpdated := []chan ebiten.ScreenSizeUpdatedEvent{}
for { for {
select { select {
case ch := <-ui.inputStateUpdatedChs: case ch := <-ui.inputStateUpdatedChs:
@ -102,12 +91,23 @@ func (ui *UI) chLoop() {
for _, ch := range inputStateUpdated { for _, ch := range inputStateUpdated {
ch <- e ch <- e
} }
case ch := <-ui.screenSizeUpdatedChs:
screenSizeUpdated = append(screenSizeUpdated, ch)
case e := <-ui.screenSizeUpdatedNotified:
for _, ch := range screenSizeUpdated {
ch <- e
}
} }
} }
} }
func (ui *UI) PollEvents() { func (ui *UI) PollEvents() {
C.PollEvents() C.PollEvents()
if !ui.initialEventSent {
e := ebiten.ScreenSizeUpdatedEvent{ui.screenWidth, ui.screenHeight}
ui.notifyScreenSizeUpdated(e)
ui.initialEventSent = true
}
} }
func (ui *UI) InitTextures(f func(graphics.TextureFactory)) { func (ui *UI) InitTextures(f func(graphics.TextureFactory)) {
@ -116,10 +116,6 @@ func (ui *UI) InitTextures(f func(graphics.TextureFactory)) {
C.EndDrawing(ui.window) C.EndDrawing(ui.window)
} }
func (ui *UI) Update(f func(ebiten.GameContext)) {
f(ui.gameContext)
}
func (ui *UI) Draw(f func(graphics.Canvas)) { func (ui *UI) Draw(f func(graphics.Canvas)) {
C.BeginDrawing(ui.window) C.BeginDrawing(ui.window)
ui.graphicsDevice.Update(f) ui.graphicsDevice.Update(f)
@ -140,6 +136,27 @@ func (ui *UI) notifyInputStateUpdated(e ebiten.InputStateUpdatedEvent) {
}() }()
} }
func (ui *UI) ScreenSizeUpdated() <-chan ebiten.ScreenSizeUpdatedEvent {
ch := make(chan ebiten.ScreenSizeUpdatedEvent)
go func() {
ui.screenSizeUpdatedChs <- ch
}()
return ch
}
func (ui *UI) notifyScreenSizeUpdated(e ebiten.ScreenSizeUpdatedEvent) {
go func() {
ui.screenSizeUpdatedNotified <- e
}()
}
//export ebiten_ScreenSizeUpdated
func ebiten_ScreenSizeUpdated(width, height int) {
ui := currentUI
e := ebiten.ScreenSizeUpdatedEvent{width, height}
ui.notifyScreenSizeUpdated(e)
}
//export ebiten_InputUpdated //export ebiten_InputUpdated
func ebiten_InputUpdated(inputType C.InputType, cx, cy C.int) { func ebiten_InputUpdated(inputType C.InputType, cx, cy C.int) {
ui := currentUI ui := currentUI