Modify Game.Draw

This commit is contained in:
Hajime Hoshi 2013-07-04 23:57:53 +09:00
parent 1a1bc9f0b3
commit 508e5150de
12 changed files with 103 additions and 134 deletions

View File

@ -29,8 +29,8 @@ type Game interface {
ScreenHeight() int ScreenHeight() int
Fps() int Fps() int
Init(tf graphics.TextureFactory) Init(tf graphics.TextureFactory)
Update() Update(inputState InputState)
Draw(g graphics.Context, offscreen graphics.Texture) Draw(g graphics.Context)
} }
type UI interface { type UI interface {
@ -38,7 +38,6 @@ type UI interface {
} }
type InputState struct { type InputState struct {
IsTapped bool X int
X int Y int
Y int
} }

View File

@ -21,6 +21,7 @@
package blank package blank
import ( import (
"github.com/hajimehoshi/go.ebiten"
"github.com/hajimehoshi/go.ebiten/graphics" "github.com/hajimehoshi/go.ebiten/graphics"
) )
@ -46,8 +47,8 @@ func (game *Blank) Fps() int {
func (game *Blank) Init(tf graphics.TextureFactory) { func (game *Blank) Init(tf graphics.TextureFactory) {
} }
func (game *Blank) Update() { func (game *Blank) Update(inputState ebiten.InputState) {
} }
func (game *Blank) Draw(g graphics.Context, offscreen graphics.Texture) { func (game *Blank) Draw(context graphics.Context) {
} }

View File

@ -21,10 +21,18 @@
package input package input
import ( import (
"fmt"
"github.com/hajimehoshi/go.ebiten"
"github.com/hajimehoshi/go.ebiten/graphics" "github.com/hajimehoshi/go.ebiten/graphics"
"github.com/hajimehoshi/go.ebiten/graphics/matrix"
"image"
"image/color"
"os"
) )
type Input struct { type Input struct {
textTexture graphics.Texture
inputState ebiten.InputState
} }
func New() *Input { func New() *Input {
@ -44,10 +52,61 @@ func (game *Input) Fps() int {
} }
func (game *Input) Init(tf graphics.TextureFactory) { func (game *Input) Init(tf graphics.TextureFactory) {
file, err := os.Open("images/text.png")
if err != nil {
panic(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
if game.textTexture, err = tf.NewTextureFromImage(img); err != nil {
panic(err)
}
} }
func (game *Input) Update() { func (game *Input) Update(inputState ebiten.InputState) {
game.inputState = inputState
} }
func (game *Input) Draw(g graphics.Context, offscreen graphics.Texture) { func (game *Input) Draw(g graphics.Context) {
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
str := fmt.Sprintf(`Input State:
X: %d
Y: %d`, game.inputState.X, game.inputState.Y)
game.drawText(g, str, 5, 5)
}
func (game *Input) drawText(g graphics.Context, text string, x, y int) {
const letterWidth = 6
const letterHeight = 16
parts := []graphics.TexturePart{}
textX := 0
textY := 0
for _, c := range text {
if c == '\n' {
textX = 0
textY += letterHeight
continue
}
code := int(c)
x := (code % 32) * letterWidth
y := (code / 32) * letterHeight
source := graphics.Rect{x, y, letterWidth, letterHeight}
parts = append(parts, graphics.TexturePart{
LocationX: textX,
LocationY: textY,
Source: source,
})
textX += letterWidth
}
geometryMatrix := matrix.IdentityGeometry()
geometryMatrix.Translate(float64(x), float64(y))
colorMatrix := matrix.IdentityColor()
g.DrawTextureParts(game.textTexture.ID, parts,
geometryMatrix, colorMatrix)
} }

View File

@ -21,6 +21,7 @@
package monochrome package monochrome
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"
@ -114,12 +115,12 @@ func (game *Monochrome) update() {
} }
} }
func (game *Monochrome) Update() { func (game *Monochrome) Update(inputState ebiten.InputState) {
game.ch <- true game.ch <- true
<-game.ch <-game.ch
} }
func (game *Monochrome) Draw(g graphics.Context, offscreen graphics.Texture) { func (game *Monochrome) Draw(g graphics.Context) {
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255}) g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
geometryMatrix := matrix.IdentityGeometry() geometryMatrix := matrix.IdentityGeometry()

View File

@ -21,6 +21,7 @@
package rects package rects
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/color" "image/color"
@ -52,10 +53,10 @@ func (game *Rects) Init(tf graphics.TextureFactory) {
game.rectsTexture = tf.NewTexture(game.ScreenWidth(), game.ScreenHeight()) game.rectsTexture = tf.NewTexture(game.ScreenWidth(), game.ScreenHeight())
} }
func (game *Rects) Update() { func (game *Rects) Update(inputState ebiten.InputState) {
} }
func (game *Rects) Draw(g graphics.Context, offscreen graphics.Texture) { func (game *Rects) Draw(g graphics.Context) {
g.SetOffscreen(game.rectsTexture.ID) g.SetOffscreen(game.rectsTexture.ID)
x := rand.Intn(game.ScreenWidth()) x := rand.Intn(game.ScreenWidth())
@ -73,7 +74,7 @@ func (game *Rects) Draw(g graphics.Context, offscreen graphics.Texture) {
&color.RGBA{red, green, blue, alpha}, &color.RGBA{red, green, blue, alpha},
) )
g.SetOffscreen(offscreen.ID) g.SetOffscreen(g.Screen().ID)
g.DrawTexture(game.rectsTexture.ID, g.DrawTexture(game.rectsTexture.ID,
matrix.IdentityGeometry(), matrix.IdentityGeometry(),
matrix.IdentityColor()) matrix.IdentityColor())

View File

@ -21,6 +21,7 @@
package rotating package rotating
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"
@ -67,11 +68,11 @@ func (game *Rotating) Init(tf graphics.TextureFactory) {
} }
} }
func (game *Rotating) Update() { func (game *Rotating) Update(inputState ebiten.InputState) {
game.x++ game.x++
} }
func (game *Rotating) Draw(g graphics.Context, offscreen graphics.Texture) { func (game *Rotating) Draw(g graphics.Context) {
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255}) g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
geometryMatrix := matrix.IdentityGeometry() geometryMatrix := matrix.IdentityGeometry()

View File

@ -21,6 +21,7 @@
package sprites package sprites
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"
@ -124,13 +125,13 @@ func (game *Sprites) Init(tf graphics.TextureFactory) {
} }
} }
func (game *Sprites) Update() { func (game *Sprites) Update(inputState ebiten.InputState) {
for _, sprite := range game.sprites { for _, sprite := range game.sprites {
sprite.Update() sprite.Update()
} }
} }
func (game *Sprites) Draw(g graphics.Context, offscreen graphics.Texture) { func (game *Sprites) Draw(g graphics.Context) {
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255}) g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
// Draw the sprites // Draw the sprites

View File

@ -1,99 +0,0 @@
// Copyright 2013 Hajime Hoshi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package text
import (
"github.com/hajimehoshi/go.ebiten/graphics"
"github.com/hajimehoshi/go.ebiten/graphics/matrix"
"image"
"image/color"
"os"
)
type Text struct {
textTexture graphics.Texture
}
func New() *Text {
return &Text{}
}
func (game *Text) ScreenWidth() int {
return 256
}
func (game *Text) ScreenHeight() int {
return 240
}
func (game *Text) Fps() int {
return 60
}
func (game *Text) Init(tf graphics.TextureFactory) {
file, err := os.Open("images/text.png")
if err != nil {
panic(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
if game.textTexture, err = tf.NewTextureFromImage(img); err != nil {
panic(err)
}
}
func (game *Text) Update() {
}
func (game *Text) Draw(g graphics.Context, offscreen graphics.Texture) {
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
game.drawText(g, "Hello, World!", 10, 10)
}
func (game *Text) drawText(g graphics.Context, text string, x, y int) {
const letterWidth = 6
const letterHeight = 16
parts := []graphics.TexturePart{}
textX := 0
for _, c := range text {
code := int(c)
x := (code % 32) * letterWidth
y := (code / 32) * letterHeight
source := graphics.Rect{x, y, letterWidth, letterHeight}
parts = append(parts, graphics.TexturePart{
LocationX: textX,
LocationY: 0,
Source: source,
})
textX += letterWidth
}
geometryMatrix := matrix.IdentityGeometry()
geometryMatrix.Translate(float64(x), float64(y))
colorMatrix := matrix.IdentityColor()
g.DrawTextureParts(game.textTexture.ID, parts,
geometryMatrix, colorMatrix)
}

View File

@ -44,7 +44,6 @@ import (
"github.com/hajimehoshi/go.ebiten/example/game/rects" "github.com/hajimehoshi/go.ebiten/example/game/rects"
"github.com/hajimehoshi/go.ebiten/example/game/rotating" "github.com/hajimehoshi/go.ebiten/example/game/rotating"
"github.com/hajimehoshi/go.ebiten/example/game/sprites" "github.com/hajimehoshi/go.ebiten/example/game/sprites"
"github.com/hajimehoshi/go.ebiten/example/game/text"
"github.com/hajimehoshi/go.ebiten/graphics" "github.com/hajimehoshi/go.ebiten/graphics"
"github.com/hajimehoshi/go.ebiten/graphics/opengl" "github.com/hajimehoshi/go.ebiten/graphics/opengl"
"os" "os"
@ -145,8 +144,6 @@ func main() {
game = rotating.New() game = rotating.New()
case "sprites": case "sprites":
game = sprites.New() game = sprites.New()
case "text":
game = text.New()
default: default:
game = rotating.New() game = rotating.New()
} }
@ -191,15 +188,16 @@ func main() {
frameTime := time.Duration( frameTime := time.Duration(
int64(time.Second) / int64(game.Fps())) int64(time.Second) / int64(game.Fps()))
update := time.Tick(frameTime) update := time.Tick(frameTime)
inputState := ebiten.InputState{-1, -1}
for { for {
select { select {
case <-input: case inputState = <-input:
case <-update: case <-update:
game.Update() game.Update(inputState)
case drawing := <-draw: case drawing := <-draw:
ch := make(chan interface{}) ch := make(chan interface{})
drawing <- func(g graphics.Context, offscreen graphics.Texture) { drawing <- func(context graphics.Context) {
game.Draw(g, offscreen) game.Draw(context)
close(ch) close(ch)
} }
<-ch <-ch

View File

@ -29,7 +29,7 @@ import (
type Device interface { type Device interface {
Initializing() <-chan chan func(TextureFactory) Initializing() <-chan chan func(TextureFactory)
TextureFactory() TextureFactory TextureFactory() TextureFactory
Drawing() <-chan chan func(g Context, offscreen Texture) Drawing() <-chan chan func(Context)
} }
type Rect struct { type Rect struct {
@ -46,6 +46,7 @@ type TexturePart struct {
} }
type Context interface { type Context interface {
Screen() Texture
Clear() Clear()
Fill(clr color.Color) Fill(clr color.Color)
DrawRect(rect Rect, clr color.Color) DrawRect(rect Rect, clr color.Color)

View File

@ -36,6 +36,7 @@ import (
) )
type Context struct { type Context struct {
screen graphics.Texture
screenWidth int screenWidth int
screenHeight int screenHeight int
screenScale int screenScale int
@ -68,6 +69,14 @@ func newContext(screenWidth, screenHeight, screenScale int) *Context {
return context return context
} }
func (context *Context) setScreen(screen graphics.Texture) {
context.screen = screen
}
func (context *Context) Screen() graphics.Texture {
return context.screen
}
func (context *Context) Clear() { func (context *Context) Clear() {
C.glClearColor(0, 0, 0, 0) C.glClearColor(0, 0, 0, 0)
C.glClear(C.GL_COLOR_BUFFER_BIT) C.glClear(C.GL_COLOR_BUFFER_BIT)

View File

@ -36,7 +36,7 @@ type Device struct {
screenScale int screenScale int
context *Context context *Context
offscreenTexture graphics.Texture offscreenTexture graphics.Texture
drawing chan chan func(graphics.Context, graphics.Texture) drawing chan chan func(graphics.Context)
updating chan chan func() updating chan chan func()
} }
@ -47,12 +47,13 @@ func NewDevice(screenWidth, screenHeight, screenScale int, updating chan chan fu
screenWidth: screenWidth, screenWidth: screenWidth,
screenHeight: screenHeight, screenHeight: screenHeight,
screenScale: screenScale, screenScale: screenScale,
drawing: make(chan chan func(graphics.Context, graphics.Texture)), drawing: make(chan chan func(graphics.Context)),
context: context, context: context,
updating: updating, updating: updating,
} }
device.offscreenTexture = device.offscreenTexture =
device.context.NewTexture(screenWidth, screenHeight) device.context.NewTexture(screenWidth, screenHeight)
device.context.setScreen(device.offscreenTexture)
go func() { go func() {
for { for {
@ -64,14 +65,10 @@ func NewDevice(screenWidth, screenHeight, screenScale int, updating chan chan fu
return device return device
} }
func (device *Device) Drawing() <-chan chan func(graphics.Context, graphics.Texture) { func (device *Device) Drawing() <-chan chan func(graphics.Context) {
return device.drawing return device.drawing
} }
func (device *Device) OffscreenTexture() graphics.Texture {
return device.offscreenTexture
}
func (device *Device) Update() { func (device *Device) Update() {
g := device.context g := device.context
C.glEnable(C.GL_TEXTURE_2D) C.glEnable(C.GL_TEXTURE_2D)
@ -80,10 +77,10 @@ func (device *Device) Update() {
g.SetOffscreen(device.offscreenTexture.ID) g.SetOffscreen(device.offscreenTexture.ID)
g.Clear() g.Clear()
ch := make(chan func(graphics.Context, graphics.Texture)) ch := make(chan func(graphics.Context))
device.drawing <- ch device.drawing <- ch
drawable := <-ch drawable := <-ch
drawable(g, device.offscreenTexture) drawable(g)
g.flush() g.flush()