mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
Remove some methods; Add Game.Initialize
This commit is contained in:
parent
343916ad29
commit
a39f0e904d
@ -18,7 +18,6 @@ package blocks
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Size struct {
|
||||
@ -39,21 +38,24 @@ type GameState struct {
|
||||
}
|
||||
|
||||
type Game struct {
|
||||
gameContext ebiten.GameContext
|
||||
sceneManager *SceneManager
|
||||
ebiten *Input
|
||||
input *Input
|
||||
textures *Textures
|
||||
}
|
||||
|
||||
func NewGame() *Game {
|
||||
game := &Game{
|
||||
sceneManager: NewSceneManager(NewTitleScene()),
|
||||
ebiten: NewInput(),
|
||||
textures: NewTextures(),
|
||||
input: NewInput(),
|
||||
}
|
||||
return game
|
||||
}
|
||||
|
||||
func (game *Game) isInitialized() bool {
|
||||
if game.textures == nil {
|
||||
return false
|
||||
}
|
||||
for name := range texturePaths {
|
||||
if !game.textures.Has(name) {
|
||||
return false
|
||||
@ -67,32 +69,33 @@ func (game *Game) isInitialized() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var once sync.Once
|
||||
func (game *Game) Initialize(g ebiten.GameContext) {
|
||||
game.gameContext = g
|
||||
game.textures = NewTextures(g)
|
||||
for name, path := range texturePaths {
|
||||
game.textures.RequestTexture(name, path)
|
||||
}
|
||||
for name, size := range renderTargetSizes {
|
||||
game.textures.RequestRenderTarget(name, size)
|
||||
}
|
||||
}
|
||||
|
||||
func (game *Game) Update() error {
|
||||
once.Do(func() {
|
||||
for name, path := range texturePaths {
|
||||
game.textures.RequestTexture(name, path)
|
||||
}
|
||||
for name, size := range renderTargetSizes {
|
||||
game.textures.RequestRenderTarget(name, size)
|
||||
}
|
||||
})
|
||||
if !game.isInitialized() {
|
||||
return nil
|
||||
}
|
||||
game.ebiten.Update()
|
||||
game.input.Update(game.gameContext)
|
||||
game.sceneManager.Update(&GameState{
|
||||
SceneManager: game.sceneManager,
|
||||
Input: game.ebiten,
|
||||
Input: game.input,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (game *Game) Draw(context ebiten.GraphicsContext) error {
|
||||
func (game *Game) Draw(g ebiten.GraphicsContext) error {
|
||||
if !game.isInitialized() {
|
||||
return nil
|
||||
}
|
||||
game.sceneManager.Draw(context, game.textures)
|
||||
game.sceneManager.Draw(g, game.textures)
|
||||
return nil
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ func (i *Input) StateForKey(key ebiten.Key) int {
|
||||
return i.states[key]
|
||||
}
|
||||
|
||||
func (i *Input) Update() {
|
||||
func (i *Input) Update(g ebiten.GameContext) {
|
||||
for key := range i.states {
|
||||
if !ebiten.IsKeyPressed(key) {
|
||||
if !g.IsKeyPressed(key) {
|
||||
i.states[key] = 0
|
||||
continue
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ type nameSize struct {
|
||||
}
|
||||
|
||||
type Textures struct {
|
||||
gameContext ebiten.GameContext
|
||||
texturePaths chan namePath
|
||||
renderTargetSizes chan nameSize
|
||||
textures map[string]ebiten.TextureID
|
||||
@ -42,8 +43,9 @@ type Textures struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewTextures() *Textures {
|
||||
func NewTextures(g ebiten.GameContext) *Textures {
|
||||
textures := &Textures{
|
||||
gameContext: g,
|
||||
texturePaths: make(chan namePath),
|
||||
renderTargetSizes: make(chan nameSize),
|
||||
textures: map[string]ebiten.TextureID{},
|
||||
@ -81,7 +83,7 @@ func (t *Textures) loopMain() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
id, err := ebiten.NewTextureID(img, ebiten.FilterNearest)
|
||||
id, err := t.gameContext.NewTextureID(img, ebiten.FilterNearest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -93,7 +95,7 @@ func (t *Textures) loopMain() {
|
||||
name := s.name
|
||||
size := s.size
|
||||
go func() {
|
||||
id, err := ebiten.NewRenderTargetID(size.Width, size.Height, ebiten.FilterNearest)
|
||||
id, err := t.gameContext.NewRenderTargetID(size.Width, size.Height, ebiten.FilterNearest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -20,6 +20,12 @@ import (
|
||||
"image"
|
||||
)
|
||||
|
||||
type Game interface {
|
||||
Initialize(g GameContext)
|
||||
Update() error
|
||||
Draw(gr GraphicsContext) error
|
||||
}
|
||||
|
||||
type GameContext interface {
|
||||
IsKeyPressed(key Key) bool
|
||||
CursorPosition() (x, y int)
|
||||
@ -27,9 +33,3 @@ type GameContext interface {
|
||||
NewRenderTargetID(width, height int, filter Filter) (RenderTargetID, error)
|
||||
NewTextureID(img image.Image, filter Filter) (TextureID, error)
|
||||
}
|
||||
|
||||
var currentGameContext GameContext
|
||||
|
||||
func SetGameContext(g GameContext) {
|
||||
currentGameContext = g
|
||||
}
|
||||
|
@ -50,7 +50,33 @@ type GraphicsContext interface {
|
||||
Fill(r, g, b uint8)
|
||||
Texture(id TextureID) Drawer
|
||||
RenderTarget(id RenderTargetID) Drawer
|
||||
|
||||
ResetOffscreen()
|
||||
SetOffscreen(id RenderTargetID)
|
||||
}
|
||||
|
||||
// Filter represents the type of filter to be used when a texture or a render
|
||||
// target is maginified or minified.
|
||||
type Filter int
|
||||
|
||||
const (
|
||||
FilterNearest Filter = iota
|
||||
FilterLinear
|
||||
)
|
||||
|
||||
// TextureID represents an ID of a texture.
|
||||
type TextureID int
|
||||
|
||||
// IsNil returns true if the texture is nil.
|
||||
func (i TextureID) IsNil() bool {
|
||||
return i == 0
|
||||
}
|
||||
|
||||
// RenderTargetID represents an ID of a render target.
|
||||
// A render target is essentially same as a texture, but it is assumed that the
|
||||
// all alpha of a render target is maximum.
|
||||
type RenderTargetID int
|
||||
|
||||
// IsNil returns true if the render target is nil.
|
||||
func (i RenderTargetID) IsNil() bool {
|
||||
return i == 0
|
||||
}
|
21
input.go
21
input.go
@ -36,24 +36,3 @@ const (
|
||||
MouseButtonMiddle
|
||||
MouseButtonMax
|
||||
)
|
||||
|
||||
func IsKeyPressed(key Key) bool {
|
||||
if currentGameContext == nil {
|
||||
panic("ebiten.IsKeyPressed: currentGameContext is not set")
|
||||
}
|
||||
return currentGameContext.IsKeyPressed(key)
|
||||
}
|
||||
|
||||
func CursorPosition() (x, y int) {
|
||||
if currentGameContext == nil {
|
||||
panic("ebiten.CurrentPosition: currentGameContext is not set")
|
||||
}
|
||||
return currentGameContext.CursorPosition()
|
||||
}
|
||||
|
||||
func IsMouseButtonPressed(button MouseButton) bool {
|
||||
if currentGameContext == nil {
|
||||
panic("ebiten.IsMouseButtonPressed: currentGameContext is not set")
|
||||
}
|
||||
return currentGameContext.IsMouseButtonPressed(button)
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ type canvas struct {
|
||||
funcsDone chan struct{}
|
||||
}
|
||||
|
||||
func (c *canvas) draw(d GraphicsContextDrawer) (err error) {
|
||||
func (c *canvas) draw(game ebiten.Game) (err error) {
|
||||
c.use(func() {
|
||||
c.graphicsContext.PreUpdate()
|
||||
})
|
||||
if err = d.Draw(&graphicsContext{c}); err != nil {
|
||||
if err = game.Draw(&graphicsContext{c}); err != nil {
|
||||
return
|
||||
}
|
||||
c.use(func() {
|
||||
|
@ -30,15 +30,11 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
type GraphicsContextDrawer interface {
|
||||
Draw(d ebiten.GraphicsContext) error
|
||||
}
|
||||
|
||||
type UI struct {
|
||||
canvas *canvas
|
||||
}
|
||||
|
||||
func (u *UI) Start(width, height, scale int, title string) error {
|
||||
func (u *UI) Start(game ebiten.Game, width, height, scale int, title string) error {
|
||||
if !glfw.Init() {
|
||||
return errors.New("glfw.Init() fails")
|
||||
}
|
||||
@ -53,7 +49,6 @@ func (u *UI) Start(width, height, scale int, title string) error {
|
||||
funcs: make(chan func()),
|
||||
funcsDone: make(chan struct{}),
|
||||
}
|
||||
ebiten.SetGameContext(c)
|
||||
|
||||
c.run(width, height, scale)
|
||||
|
||||
@ -68,6 +63,7 @@ func (u *UI) Start(width, height, scale int, title string) error {
|
||||
}
|
||||
|
||||
u.canvas = c
|
||||
game.Initialize(c)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -81,10 +77,10 @@ func (u *UI) Terminate() {
|
||||
glfw.Terminate()
|
||||
}
|
||||
|
||||
func (u *UI) Draw(drawer GraphicsContextDrawer) error {
|
||||
return u.canvas.draw(drawer)
|
||||
}
|
||||
|
||||
func (u *UI) IsClosed() bool {
|
||||
return u.canvas.isClosed()
|
||||
}
|
||||
|
||||
func (u *UI) DrawGame(game ebiten.Game) error {
|
||||
return u.canvas.draw(game)
|
||||
}
|
||||
|
@ -25,26 +25,19 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Game interface {
|
||||
Update() error
|
||||
Draw(context ebiten.GraphicsContext) error
|
||||
}
|
||||
|
||||
// Run runs the game. Basically, this function executes ui.Start() at the start,
|
||||
// calls ui.DoEvent(), game.Update() and game.Draw() at a regular interval, and finally
|
||||
// calls ui.Terminate().
|
||||
func Run(game Game, width, height, scale int, title string, fps int) error {
|
||||
// Run runs the game.
|
||||
func Run(game ebiten.Game, width, height, scale int, title string, fps int) error {
|
||||
ui := new(glfw.UI)
|
||||
if err := ui.Start(width, height, scale, title); err != nil {
|
||||
if err := ui.Start(game, width, height, scale, title); err != nil {
|
||||
return err
|
||||
}
|
||||
defer ui.Terminate()
|
||||
|
||||
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 ui.Terminate()
|
||||
for {
|
||||
ui.DoEvents()
|
||||
if ui.IsClosed() {
|
||||
@ -52,7 +45,7 @@ func Run(game Game, width, height, scale int, title string, fps int) error {
|
||||
}
|
||||
select {
|
||||
default:
|
||||
if err := ui.Draw(game); err != nil {
|
||||
if err := ui.DrawGame(game); err != nil {
|
||||
return err
|
||||
}
|
||||
case <-tick:
|
||||
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 Hajime Hoshi
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"image"
|
||||
)
|
||||
|
||||
// Filter represents the type of filter to be used when a texture or a render
|
||||
// target is maginified or minified.
|
||||
type Filter int
|
||||
|
||||
const (
|
||||
FilterNearest Filter = iota
|
||||
FilterLinear
|
||||
)
|
||||
|
||||
// TextureID represents an ID of a texture.
|
||||
type TextureID int
|
||||
|
||||
// IsNil returns true if the texture is nil.
|
||||
func (i TextureID) IsNil() bool {
|
||||
return i == 0
|
||||
}
|
||||
|
||||
// RenderTargetID represents an ID of a render target.
|
||||
// A render target is essentially same as a texture, but it is assumed that the
|
||||
// all alpha of a render target is maximum.
|
||||
type RenderTargetID int
|
||||
|
||||
// IsNil returns true if the render target is nil.
|
||||
func (i RenderTargetID) IsNil() bool {
|
||||
return i == 0
|
||||
}
|
||||
|
||||
// NewRenderTargetID returns an ID of a newly created render target.
|
||||
func NewRenderTargetID(width, height int, filter Filter) (RenderTargetID, error) {
|
||||
if currentGameContext == nil {
|
||||
panic("graphics.NewRenderTarget: currentGameContext is not set.")
|
||||
}
|
||||
return currentGameContext.NewRenderTargetID(width, height, filter)
|
||||
}
|
||||
|
||||
// NewRenderTargetID returns an ID of a newly created texture.
|
||||
func NewTextureID(img image.Image, filter Filter) (TextureID, error) {
|
||||
if currentGameContext == nil {
|
||||
panic("graphics.NewTexture: currentGameContext is not set")
|
||||
}
|
||||
return currentGameContext.NewTextureID(img, filter)
|
||||
}
|
Loading…
Reference in New Issue
Block a user