mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
Remove some methods; Add Game.Initialize
This commit is contained in:
parent
343916ad29
commit
a39f0e904d
@ -18,7 +18,6 @@ package blocks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Size struct {
|
type Size struct {
|
||||||
@ -39,21 +38,24 @@ type GameState struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
|
gameContext ebiten.GameContext
|
||||||
sceneManager *SceneManager
|
sceneManager *SceneManager
|
||||||
ebiten *Input
|
input *Input
|
||||||
textures *Textures
|
textures *Textures
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGame() *Game {
|
func NewGame() *Game {
|
||||||
game := &Game{
|
game := &Game{
|
||||||
sceneManager: NewSceneManager(NewTitleScene()),
|
sceneManager: NewSceneManager(NewTitleScene()),
|
||||||
ebiten: NewInput(),
|
input: NewInput(),
|
||||||
textures: NewTextures(),
|
|
||||||
}
|
}
|
||||||
return game
|
return game
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) isInitialized() bool {
|
func (game *Game) isInitialized() bool {
|
||||||
|
if game.textures == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
for name := range texturePaths {
|
for name := range texturePaths {
|
||||||
if !game.textures.Has(name) {
|
if !game.textures.Has(name) {
|
||||||
return false
|
return false
|
||||||
@ -67,32 +69,33 @@ func (game *Game) isInitialized() bool {
|
|||||||
return true
|
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 {
|
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() {
|
if !game.isInitialized() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
game.ebiten.Update()
|
game.input.Update(game.gameContext)
|
||||||
game.sceneManager.Update(&GameState{
|
game.sceneManager.Update(&GameState{
|
||||||
SceneManager: game.sceneManager,
|
SceneManager: game.sceneManager,
|
||||||
Input: game.ebiten,
|
Input: game.input,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Draw(context ebiten.GraphicsContext) error {
|
func (game *Game) Draw(g ebiten.GraphicsContext) error {
|
||||||
if !game.isInitialized() {
|
if !game.isInitialized() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
game.sceneManager.Draw(context, game.textures)
|
game.sceneManager.Draw(g, game.textures)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,9 @@ func (i *Input) StateForKey(key ebiten.Key) int {
|
|||||||
return i.states[key]
|
return i.states[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) Update() {
|
func (i *Input) Update(g ebiten.GameContext) {
|
||||||
for key := range i.states {
|
for key := range i.states {
|
||||||
if !ebiten.IsKeyPressed(key) {
|
if !g.IsKeyPressed(key) {
|
||||||
i.states[key] = 0
|
i.states[key] = 0
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ type nameSize struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Textures struct {
|
type Textures struct {
|
||||||
|
gameContext ebiten.GameContext
|
||||||
texturePaths chan namePath
|
texturePaths chan namePath
|
||||||
renderTargetSizes chan nameSize
|
renderTargetSizes chan nameSize
|
||||||
textures map[string]ebiten.TextureID
|
textures map[string]ebiten.TextureID
|
||||||
@ -42,8 +43,9 @@ type Textures struct {
|
|||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTextures() *Textures {
|
func NewTextures(g ebiten.GameContext) *Textures {
|
||||||
textures := &Textures{
|
textures := &Textures{
|
||||||
|
gameContext: g,
|
||||||
texturePaths: make(chan namePath),
|
texturePaths: make(chan namePath),
|
||||||
renderTargetSizes: make(chan nameSize),
|
renderTargetSizes: make(chan nameSize),
|
||||||
textures: map[string]ebiten.TextureID{},
|
textures: map[string]ebiten.TextureID{},
|
||||||
@ -81,7 +83,7 @@ func (t *Textures) loopMain() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
id, err := ebiten.NewTextureID(img, ebiten.FilterNearest)
|
id, err := t.gameContext.NewTextureID(img, ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -93,7 +95,7 @@ func (t *Textures) loopMain() {
|
|||||||
name := s.name
|
name := s.name
|
||||||
size := s.size
|
size := s.size
|
||||||
go func() {
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,12 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Game interface {
|
||||||
|
Initialize(g GameContext)
|
||||||
|
Update() error
|
||||||
|
Draw(gr GraphicsContext) error
|
||||||
|
}
|
||||||
|
|
||||||
type GameContext interface {
|
type GameContext interface {
|
||||||
IsKeyPressed(key Key) bool
|
IsKeyPressed(key Key) bool
|
||||||
CursorPosition() (x, y int)
|
CursorPosition() (x, y int)
|
||||||
@ -27,9 +33,3 @@ type GameContext interface {
|
|||||||
NewRenderTargetID(width, height int, filter Filter) (RenderTargetID, error)
|
NewRenderTargetID(width, height int, filter Filter) (RenderTargetID, error)
|
||||||
NewTextureID(img image.Image, filter Filter) (TextureID, 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)
|
Fill(r, g, b uint8)
|
||||||
Texture(id TextureID) Drawer
|
Texture(id TextureID) Drawer
|
||||||
RenderTarget(id RenderTargetID) Drawer
|
RenderTarget(id RenderTargetID) Drawer
|
||||||
|
|
||||||
ResetOffscreen()
|
ResetOffscreen()
|
||||||
SetOffscreen(id RenderTargetID)
|
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
|
MouseButtonMiddle
|
||||||
MouseButtonMax
|
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{}
|
funcsDone chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *canvas) draw(d GraphicsContextDrawer) (err error) {
|
func (c *canvas) draw(game ebiten.Game) (err error) {
|
||||||
c.use(func() {
|
c.use(func() {
|
||||||
c.graphicsContext.PreUpdate()
|
c.graphicsContext.PreUpdate()
|
||||||
})
|
})
|
||||||
if err = d.Draw(&graphicsContext{c}); err != nil {
|
if err = game.Draw(&graphicsContext{c}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.use(func() {
|
c.use(func() {
|
||||||
|
@ -30,15 +30,11 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type GraphicsContextDrawer interface {
|
|
||||||
Draw(d ebiten.GraphicsContext) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type UI struct {
|
type UI struct {
|
||||||
canvas *canvas
|
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() {
|
if !glfw.Init() {
|
||||||
return errors.New("glfw.Init() fails")
|
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()),
|
funcs: make(chan func()),
|
||||||
funcsDone: make(chan struct{}),
|
funcsDone: make(chan struct{}),
|
||||||
}
|
}
|
||||||
ebiten.SetGameContext(c)
|
|
||||||
|
|
||||||
c.run(width, height, scale)
|
c.run(width, height, scale)
|
||||||
|
|
||||||
@ -68,6 +63,7 @@ func (u *UI) Start(width, height, scale int, title string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u.canvas = c
|
u.canvas = c
|
||||||
|
game.Initialize(c)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -81,10 +77,10 @@ func (u *UI) Terminate() {
|
|||||||
glfw.Terminate()
|
glfw.Terminate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UI) Draw(drawer GraphicsContextDrawer) error {
|
|
||||||
return u.canvas.draw(drawer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UI) IsClosed() bool {
|
func (u *UI) IsClosed() bool {
|
||||||
return u.canvas.isClosed()
|
return u.canvas.isClosed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UI) DrawGame(game ebiten.Game) error {
|
||||||
|
return u.canvas.draw(game)
|
||||||
|
}
|
||||||
|
@ -25,26 +25,19 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Game interface {
|
// Run runs the game.
|
||||||
Update() error
|
func Run(game ebiten.Game, width, height, scale int, title string, fps int) 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 {
|
|
||||||
ui := new(glfw.UI)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
defer ui.Terminate()
|
||||||
|
|
||||||
frameTime := time.Duration(int64(time.Second) / int64(fps))
|
frameTime := time.Duration(int64(time.Second) / int64(fps))
|
||||||
tick := time.Tick(frameTime)
|
tick := time.Tick(frameTime)
|
||||||
sigterm := make(chan os.Signal, 1)
|
sigterm := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigterm, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(sigterm, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
defer ui.Terminate()
|
|
||||||
for {
|
for {
|
||||||
ui.DoEvents()
|
ui.DoEvents()
|
||||||
if ui.IsClosed() {
|
if ui.IsClosed() {
|
||||||
@ -52,7 +45,7 @@ func Run(game Game, width, height, scale int, title string, fps int) error {
|
|||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
default:
|
default:
|
||||||
if err := ui.Draw(game); err != nil {
|
if err := ui.DrawGame(game); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case <-tick:
|
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