Remove games

This commit is contained in:
Hajime Hoshi 2013-12-08 16:19:24 +09:00
parent 4489557c84
commit cbc5c38db6
11 changed files with 49 additions and 736 deletions

View File

@ -1,53 +1,48 @@
package input
package main
import (
"fmt"
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image"
"os"
)
type Input struct {
textTextureId graphics.TextureId
var TexturePaths = map[string]string{
"ebiten": "images/ebiten.png",
"text": "images/text.png",
}
type Game struct {
textures map[string]graphics.TextureId
inputStateUpdatedCh chan ui.InputStateUpdatedEvent
x int
y int
}
func New() *Input {
return &Input{
func NewGame() *Game {
return &Game{
textures: map[string]graphics.TextureId{},
inputStateUpdatedCh: make(chan ui.InputStateUpdatedEvent),
x: -1,
y: -1,
}
}
func (game *Input) OnInputStateUpdated(e ui.InputStateUpdatedEvent) {
func (game *Game) OnTextureCreated(e graphics.TextureCreatedEvent) {
if e.Error != nil {
panic(e.Error)
}
game.textures[e.Tag.(string)] = e.Id
}
func (game *Game) OnInputStateUpdated(e ui.InputStateUpdatedEvent) {
go func() {
e := e
game.inputStateUpdatedCh <- e
}()
}
func (game *Input) InitTextures(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.textTextureId, err = tf.CreateTextureFromImage("text", img); err != nil {
panic(err)
}
}
func (game *Input) Update() {
func (game *Game) Update() {
events:
for {
select {
@ -59,7 +54,11 @@ events:
}
}
func (game *Input) Draw(g graphics.Canvas) {
func (game *Game) Draw(g graphics.Canvas) {
if len(game.textures) < len(TexturePaths) {
return
}
g.Fill(128, 128, 255)
str := fmt.Sprintf(`Input State:
X: %d
@ -67,7 +66,7 @@ func (game *Input) Draw(g graphics.Canvas) {
game.drawText(g, str, 5, 5)
}
func (game *Input) drawText(g graphics.Canvas, text string, x, y int) {
func (game *Game) drawText(g graphics.Canvas, text string, x, y int) {
const letterWidth = 6
const letterHeight = 16
@ -95,6 +94,6 @@ func (game *Input) drawText(g graphics.Canvas, text string, x, y int) {
geometryMatrix := matrix.IdentityGeometry()
geometryMatrix.Translate(float64(x), float64(y))
colorMatrix := matrix.IdentityColor()
g.DrawTextureParts(game.textTextureId, parts,
g.DrawTextureParts(game.textures["text"], parts,
geometryMatrix, colorMatrix)
}

View File

@ -1,21 +0,0 @@
package blank
import (
"github.com/hajimehoshi/go-ebiten/graphics"
)
type Blank struct {
}
func New() *Blank {
return &Blank{}
}
func (game *Blank) InitTextures(tf graphics.TextureFactory) {
}
func (game *Blank) Update() {
}
func (game *Blank) Draw(canvas graphics.Canvas) {
}

View File

@ -1,129 +0,0 @@
package monochrome
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image"
_ "image/png"
"os"
)
const (
ebitenTextureWidth = 57
ebitenTextureHeight = 26
)
type Monochrome struct {
ebitenTextureId graphics.TextureId
ch chan bool
colorMatrix matrix.Color
geometryMatrix matrix.Geometry
screenSizeUpdatedCh chan ui.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
}
func New() *Monochrome {
return &Monochrome{
ch: make(chan bool),
colorMatrix: matrix.IdentityColor(),
geometryMatrix: matrix.IdentityGeometry(),
screenSizeUpdatedCh: make(chan ui.ScreenSizeUpdatedEvent),
}
}
func (game *Monochrome) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() {
e := e
game.screenSizeUpdatedCh <- e
}()
}
func (game *Monochrome) InitTextures(tf graphics.TextureFactory) {
file, err := os.Open("images/ebiten.png")
if err != nil {
panic(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
if game.ebitenTextureId, err = tf.CreateTextureFromImage("ebiten", img); err != nil {
panic(err)
}
go game.update()
}
func mean(a, b matrix.Color, k float64) matrix.Color {
dim := a.Dim()
result := matrix.Color{}
for i := 0; i < dim-1; i++ {
for j := 0; j < dim; j++ {
result.Elements[i][j] =
a.Elements[i][j]*(1-k) +
b.Elements[i][j]*k
}
}
return result
}
func (game *Monochrome) update() {
const fps = 60
colorI := matrix.IdentityColor()
colorMonochrome := matrix.Monochrome()
for {
for i := 0; i < fps; i++ {
<-game.ch
rate := float64(i) / float64(fps)
game.colorMatrix = mean(colorI, colorMonochrome, rate)
game.ch <- true
}
for i := 0; i < fps; i++ {
<-game.ch
game.colorMatrix = colorMonochrome
game.ch <- true
}
for i := 0; i < fps; i++ {
<-game.ch
rate := float64(i) / float64(fps)
game.colorMatrix = mean(colorMonochrome, colorI, rate)
game.ch <- true
}
for i := 0; i < fps; i++ {
<-game.ch
game.colorMatrix = colorI
game.ch <- true
}
}
}
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
game.geometryMatrix = matrix.IdentityGeometry()
tx := game.screenWidth/2 - ebitenTextureWidth/2
ty := game.screenHeight/2 - ebitenTextureHeight/2
game.geometryMatrix.Translate(float64(tx), float64(ty))
}
func (game *Monochrome) Draw(g graphics.Canvas) {
g.Fill(128, 128, 255)
g.DrawTexture(game.ebitenTextureId,
game.geometryMatrix, game.colorMatrix)
}

View File

@ -1,154 +0,0 @@
package rects
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image/color"
"math"
"math/rand"
"time"
)
type Rects struct {
rectTextureId graphics.RenderTargetId
rectTextureInited bool
offscreenId graphics.RenderTargetId
offscreenInited bool
rectBounds *graphics.Rect
rectColor *color.RGBA
screenSizeUpdatedCh chan ui.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
}
const (
rectTextureWidth = 16
rectTextureHeight = 16
offscreenWidth = 256
offscreenHeight = 240
)
func New() *Rects {
return &Rects{
rectTextureInited: false,
offscreenInited: false,
rectBounds: &graphics.Rect{},
rectColor: &color.RGBA{},
screenSizeUpdatedCh: make(chan ui.ScreenSizeUpdatedEvent),
}
}
func (game *Rects) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() {
e := e
game.screenSizeUpdatedCh <- e
}()
}
func (game *Rects) InitTextures(tf graphics.TextureFactory) {
var err error
game.rectTextureId, err = tf.CreateRenderTarget("rect", rectTextureWidth, rectTextureHeight)
if err != nil {
panic(err)
}
game.offscreenId, err = tf.CreateRenderTarget("offscreen", offscreenWidth, offscreenHeight)
if err != nil {
panic(err)
}
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}
func (game *Rects) 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
}
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.Y = min(y1, y2)
game.rectBounds.Width = abs(x1 - x2)
game.rectBounds.Height = abs(y1 - y2)
game.rectColor.R = uint8(rand.Intn(math.MaxUint8))
game.rectColor.G = uint8(rand.Intn(math.MaxUint8))
game.rectColor.B = uint8(rand.Intn(math.MaxUint8))
game.rectColor.A = uint8(rand.Intn(math.MaxUint8))
}
func (game *Rects) rectGeometryMatrix() matrix.Geometry {
geometryMatrix := matrix.IdentityGeometry()
scaleX := float64(game.rectBounds.Width) /
float64(rectTextureWidth)
scaleY := float64(game.rectBounds.Height) /
float64(rectTextureHeight)
geometryMatrix.Scale(scaleX, scaleY)
geometryMatrix.Translate(
float64(game.rectBounds.X), float64(game.rectBounds.Y))
return geometryMatrix
}
func (game *Rects) rectColorMatrix() matrix.Color {
colorMatrix := matrix.IdentityColor()
colorMatrix.Elements[0][0] =
float64(game.rectColor.R) / float64(math.MaxUint8)
colorMatrix.Elements[1][1] =
float64(game.rectColor.G) / float64(math.MaxUint8)
colorMatrix.Elements[2][2] =
float64(game.rectColor.B) / float64(math.MaxUint8)
colorMatrix.Elements[3][3] =
float64(game.rectColor.A) / float64(math.MaxUint8)
return colorMatrix
}
func (game *Rects) Draw(g graphics.Canvas) {
if !game.rectTextureInited {
g.SetOffscreen(game.rectTextureId)
g.Fill(255, 255, 255)
game.rectTextureInited = true
}
g.SetOffscreen(game.offscreenId)
if !game.offscreenInited {
g.Fill(0, 0, 0)
game.offscreenInited = true
}
g.DrawRenderTarget(game.rectTextureId,
game.rectGeometryMatrix(),
game.rectColorMatrix())
g.ResetOffscreen()
g.DrawRenderTarget(game.offscreenId,
matrix.IdentityGeometry(),
matrix.IdentityColor())
}
func init() {
rand.Seed(time.Now().UnixNano())
}

View File

@ -1,90 +0,0 @@
package rotating
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image"
_ "image/png"
"math"
"os"
)
const (
ebitenTextureWidth = 57
ebitenTextureHeight = 26
)
type Rotating struct {
ebitenTextureId graphics.TextureId
x int
geometryMatrix matrix.Geometry
screenSizeUpdatedCh chan ui.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
}
func New() *Rotating {
return &Rotating{
screenSizeUpdatedCh: make(chan ui.ScreenSizeUpdatedEvent),
}
}
func (game *Rotating) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() {
e := e
game.screenSizeUpdatedCh <- e
}()
}
func (game *Rotating) InitTextures(tf graphics.TextureFactory) {
file, err := os.Open("images/ebiten.png")
if err != nil {
panic(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
if game.ebitenTextureId, err = tf.CreateTextureFromImage("ebiten", img); err != nil {
panic(err)
}
}
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
game.x++
game.geometryMatrix = matrix.IdentityGeometry()
tx, ty := float64(ebitenTextureWidth), float64(ebitenTextureHeight)
game.geometryMatrix.Translate(-tx/2, -ty/2)
game.geometryMatrix.Rotate(float64(game.x) * 2 * math.Pi / float64(fps*10))
game.geometryMatrix.Translate(tx/2, ty/2)
centerX := float64(game.screenWidth) / 2
centerY := float64(game.screenHeight) / 2
game.geometryMatrix.Translate(centerX-tx/2, centerY-ty/2)
}
func (game *Rotating) Draw(g graphics.Canvas) {
g.Fill(128, 128, 255)
g.DrawTexture(game.ebitenTextureId,
game.geometryMatrix,
matrix.IdentityColor())
}

View File

@ -1,156 +0,0 @@
package sprites
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image"
"math/rand"
"os"
"time"
)
const (
ebitenTextureWidth = 57
ebitenTextureHeight = 26
)
type Sprite struct {
width int
height int
ch chan bool
x int
y int
vx int
vy int
}
func newSprite(screenWidth, screenHeight, width, height int) *Sprite {
maxX := screenWidth - width
maxY := screenHeight - height
sprite := &Sprite{
width: width,
height: height,
ch: make(chan bool),
x: rand.Intn(maxX),
y: rand.Intn(maxY),
vx: rand.Intn(2)*2 - 1,
vy: rand.Intn(2)*2 - 1,
}
go sprite.update(screenWidth, screenHeight)
return sprite
}
func (sprite *Sprite) update(screenWidth, screenHeight int) {
maxX := screenWidth - sprite.width
maxY := screenHeight - sprite.height
for {
<-sprite.ch
sprite.x += sprite.vx
sprite.y += sprite.vy
if sprite.x < 0 || maxX <= sprite.x {
sprite.vx = -sprite.vx
}
if sprite.y < 0 || maxY <= sprite.y {
sprite.vy = -sprite.vy
}
sprite.ch <- true
}
}
func (sprite *Sprite) Update() {
sprite.ch <- true
<-sprite.ch
}
type Sprites struct {
ebitenTextureId graphics.TextureId
sprites []*Sprite
screenSizeUpdatedCh chan ui.ScreenSizeUpdatedEvent
screenWidth int
screenHeight int
}
func New() *Sprites {
return &Sprites{
screenSizeUpdatedCh: make(chan ui.ScreenSizeUpdatedEvent),
}
}
func (game *Sprites) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() {
game.screenSizeUpdatedCh <- e
}()
}
func (game *Sprites) InitTextures(tf graphics.TextureFactory) {
file, err := os.Open("images/ebiten.png")
if err != nil {
panic(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
if game.ebitenTextureId, err = tf.CreateTextureFromImage("ebiten", img); err != nil {
panic(err)
}
}
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 {
game.sprites = []*Sprite{}
for i := 0; i < 100; i++ {
sprite := newSprite(
game.screenWidth,
game.screenHeight,
ebitenTextureWidth,
ebitenTextureHeight)
game.sprites = append(game.sprites, sprite)
}
}
for _, sprite := range game.sprites {
sprite.Update()
}
}
func (game *Sprites) Draw(g graphics.Canvas) {
g.Fill(128, 128, 255)
// Draw the sprites
locations := make([]graphics.TexturePart, 0, len(game.sprites))
for _, sprite := range game.sprites {
location := graphics.TexturePart{
LocationX: sprite.x,
LocationY: sprite.y,
Source: graphics.Rect{
0, 0, ebitenTextureWidth, ebitenTextureHeight,
},
}
locations = append(locations, location)
}
geometryMatrix := matrix.IdentityGeometry()
g.DrawTextureParts(game.ebitenTextureId, locations,
geometryMatrix, matrix.IdentityColor())
}
func init() {
rand.Seed(time.Now().UnixNano())
}

View File

@ -1,78 +0,0 @@
package testpattern
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"image"
_ "image/png"
"math"
"os"
)
type TestPattern struct {
textureId graphics.TextureId
textureWidth int
textureHeight int
geos []matrix.Geometry
}
func New() *TestPattern {
return &TestPattern{}
}
func (game *TestPattern) InitTextures(tf graphics.TextureFactory) {
file, err := os.Open("images/test_pattern.png")
if err != nil {
panic(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
if game.textureId, err = tf.CreateTextureFromImage("test", img); err != nil {
panic(err)
}
size := img.Bounds().Size()
game.textureWidth = size.X
game.textureHeight = size.Y
}
func (game *TestPattern) Update() {
geo := matrix.IdentityGeometry()
geo.Translate(13, 13)
game.geos = append(game.geos, geo)
geo = matrix.IdentityGeometry()
geo.Translate(float64(13+game.textureWidth), 13)
game.geos = append(game.geos, geo)
geo = matrix.IdentityGeometry()
geo.Translate(float64(13+game.textureWidth*2), 13)
game.geos = append(game.geos, geo)
geo = matrix.IdentityGeometry()
geo.Translate(float64(13+game.textureWidth*3), 13)
game.geos = append(game.geos, geo)
geo = matrix.IdentityGeometry()
geo.Scale(2, 2)
geo.Translate(13, float64(13+game.textureHeight))
game.geos = append(game.geos, geo)
geo = matrix.IdentityGeometry()
geo.Rotate(math.Pi)
geo.Scale(2, 2)
geo.Translate(float64(game.textureWidth*2),
float64(game.textureHeight*2))
geo.Translate(float64(13+game.textureWidth*2),
float64(13+game.textureHeight))
game.geos = append(game.geos, geo)
}
func (game *TestPattern) Draw(g graphics.Canvas) {
for _, geo := range game.geos {
g.DrawTexture(game.textureId, geo, matrix.IdentityColor())
}
}

View File

@ -1,28 +1,16 @@
package main
import (
"github.com/hajimehoshi/go-ebiten/example/game/blank"
"github.com/hajimehoshi/go-ebiten/example/game/input"
"github.com/hajimehoshi/go-ebiten/example/game/monochrome"
"github.com/hajimehoshi/go-ebiten/example/game/rects"
"github.com/hajimehoshi/go-ebiten/example/game/rotating"
"github.com/hajimehoshi/go-ebiten/example/game/sprites"
"github.com/hajimehoshi/go-ebiten/example/game/testpattern"
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/ui"
"github.com/hajimehoshi/go-ebiten/ui/cocoa"
"image"
_ "image/png"
"os"
"runtime"
"time"
)
type Game interface {
InitTextures(tf graphics.TextureFactory)
Update()
Draw(canvas graphics.Canvas)
}
func loadImage(path string) (image.Image, error) {
file, err := os.Open(path)
if err != nil {
@ -41,31 +29,6 @@ func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
runtime.LockOSThread()
gameName := ""
if 2 <= len(os.Args) {
gameName = os.Args[1]
}
var game Game
switch gameName {
case "blank":
game = blank.New()
case "input":
game = input.New()
case "monochrome":
game = monochrome.New()
case "rects":
game = rects.New()
default:
fallthrough
case "rotating":
game = rotating.New()
case "sprites":
game = sprites.New()
case "testpattern":
game = testpattern.New()
}
const screenWidth = 256
const screenHeight = 240
const screenScale = 2
@ -74,53 +37,46 @@ func main() {
type UI interface {
ui.UI
graphics.TextureFactory2
graphics.TextureFactory
}
var u UI = cocoa.New(screenWidth, screenHeight, screenScale, title)
// TODO: Remove this
u.LoadResources(game.InitTextures)
textureCreated := u.TextureCreated()
inputStateUpdated := u.InputStateUpdated()
screenSizeUpdated := u.ScreenSizeUpdated()
img, err := loadImage("images/ebiten.png")
if err != nil {
panic(err)
for tag, path := range TexturePaths {
//go func() {
img, err := loadImage(path)
if err != nil {
panic(err)
}
u.CreateTexture(tag, img)
//}()
}
u.CreateTexture("ebiten", img)
drawing := make(chan *graphics.LazyCanvas)
go func() {
game := NewGame()
frameTime := time.Duration(int64(time.Second) / int64(fps))
tick := time.Tick(frameTime)
for {
select {
case e, ok := <-textureCreated:
if ok {
print(e.Error)
game.OnTextureCreated(e)
} else {
textureCreated = nil
}
case e, ok := <-inputStateUpdated:
// TODO: Use Adaptor?
if ok {
if game2, ok := game.(interface {
OnInputStateUpdated(ui.InputStateUpdatedEvent)
}); ok {
game2.OnInputStateUpdated(e)
}
game.OnInputStateUpdated(e)
} else {
inputStateUpdated = nil
}
case e, ok := <-screenSizeUpdated:
case _, ok := <-screenSizeUpdated:
if ok {
if game2, ok := game.(interface {
OnScreenSizeUpdated(ui.ScreenSizeUpdatedEvent)
}); ok {
game2.OnScreenSizeUpdated(e)
}
// Do nothing
} else {
screenSizeUpdated = nil
}

View File

@ -5,13 +5,13 @@ import (
)
type TextureCreatedEvent struct {
Tag string
Tag interface{}
Id TextureId
Error error
}
type RenderTargetCreatedEvent struct {
Tag string
Tag interface{}
Id RenderTargetId
Error error
}
@ -21,16 +21,8 @@ type TextureFactoryEvents interface {
RenderTargetCreated() <-chan RenderTargetCreatedEvent
}
// TODO: Rename this later
type TextureFactory2 interface {
CreateRenderTarget(tag string, width, height int)
CreateTexture(tag string, img image.Image)
type TextureFactory interface {
CreateRenderTarget(tag interface{}, width, height int)
CreateTexture(tag interface{}, img image.Image)
TextureFactoryEvents
}
// TODO: Deprecated
type TextureFactory interface {
CreateRenderTarget(tag string, width, height int) (RenderTargetId, error)
CreateTextureFromImage(tag string, img image.Image) (TextureId, error)
//TextureFactoryEvents
}

View File

@ -73,7 +73,7 @@ func (u *UI) PollEvents() {
}
}
func (u *UI) CreateTexture(tag string, img image.Image) {
func (u *UI) CreateTexture(tag interface{}, img image.Image) {
go func() {
var id graphics.TextureId
var err error
@ -89,7 +89,7 @@ func (u *UI) CreateTexture(tag string, img image.Image) {
}()
}
func (u *UI) CreateRenderTarget(tag string, width, height int) {
func (u *UI) CreateRenderTarget(tag interface{}, width, height int) {
go func() {
var id graphics.RenderTargetId
var err error
@ -113,11 +113,6 @@ func (u *UI) RenderTargetCreated() <-chan graphics.RenderTargetCreatedEvent {
return u.textureFactory.RenderTargetCreated()
}
func (u *UI) LoadResources(f func(graphics.TextureFactory)) {
// This should be executed on the shared-context context
f(u.graphicsDevice)
}
func (u *UI) Draw(f func(graphics.Canvas)) {
// TODO: Use UseContext instead
C.BeginDrawing(u.window)

View File

@ -21,7 +21,6 @@ type UIEvents interface {
type UI interface {
PollEvents()
LoadResources(func(graphics.TextureFactory))
Draw(func(graphics.Canvas))
UIEvents
}