Add game.Sprites

This commit is contained in:
Hajime Hoshi 2013-06-21 23:16:52 +09:00
parent faa9c1bfe8
commit b84cc9a57b
4 changed files with 122 additions and 32 deletions

View File

@ -7,22 +7,21 @@ import (
) )
type Game interface { type Game interface {
ScreenWidth() int
ScreenHeight() int
Init(tf graphics.TextureFactory) Init(tf graphics.TextureFactory)
Update() Update()
Draw(g graphics.GraphicsContext, offscreen graphics.Texture) Draw(g graphics.GraphicsContext, offscreen graphics.Texture)
} }
type UI interface { type UI interface {
ScreenWidth() int
ScreenHeight() int
ScreenScale() int
Run(device graphics.Device) Run(device graphics.Device)
} }
func OpenGLRun(game Game, ui UI) { func OpenGLRun(game Game, ui UI, screenScale int) {
ch := make(chan bool, 1) ch := make(chan bool, 1)
device := opengl.NewDevice( device := opengl.NewDevice(
ui.ScreenWidth(), ui.ScreenHeight(), ui.ScreenScale(), game.ScreenWidth(), game.ScreenHeight(), screenScale,
func(g graphics.GraphicsContext, offscreen graphics.Texture) { func(g graphics.GraphicsContext, offscreen graphics.Texture) {
ticket := <-ch ticket := <-ch
game.Draw(g, offscreen) game.Draw(g, offscreen)

View File

@ -18,6 +18,14 @@ func NewRotatingImage() *RotatingImage {
return &RotatingImage{} return &RotatingImage{}
} }
func (game *RotatingImage) ScreenWidth() int {
return 256
}
func (game *RotatingImage) ScreenHeight() int {
return 240
}
func (game *RotatingImage) Init(tf graphics.TextureFactory) { func (game *RotatingImage) Init(tf graphics.TextureFactory) {
file, err := os.Open("ebiten.png") file, err := os.Open("ebiten.png")
if err != nil { if err != nil {
@ -44,8 +52,10 @@ func (game *RotatingImage) Draw(g graphics.GraphicsContext, offscreen graphics.T
geometryMatrix.Translate(-tx/2, -ty/2) geometryMatrix.Translate(-tx/2, -ty/2)
geometryMatrix.Rotate(float64(game.x) / 60) geometryMatrix.Rotate(float64(game.x) / 60)
geometryMatrix.Translate(tx/2, ty/2) geometryMatrix.Translate(tx/2, ty/2)
centerX, centerY := float64(offscreen.Width)/2, float64(offscreen.Height)/2 centerX := float64(game.ScreenWidth()) / 2
centerY := float64(game.ScreenHeight()) / 2
geometryMatrix.Translate(centerX-tx/2, centerY-ty/2) geometryMatrix.Translate(centerX-tx/2, centerY-ty/2)
g.DrawTexture(game.ebitenTexture.ID, g.DrawTexture(game.ebitenTexture.ID,
0, 0, int(tx), int(ty), 0, 0, int(tx), int(ty),
geometryMatrix, geometryMatrix,

View File

@ -2,21 +2,119 @@ package game
import ( import (
"github.com/hajimehoshi/go.ebiten/graphics" "github.com/hajimehoshi/go.ebiten/graphics"
"github.com/hajimehoshi/go.ebiten/graphics/matrix"
"image"
"image/color"
"math/rand"
"os"
"time"
) )
type Sprite struct {
texture graphics.Texture
ch chan bool
x int
y int
vx int
vy int
}
func NewSprite(screenWidth, screenHeight int,
texture graphics.Texture) *Sprite {
maxX := screenWidth - texture.Width
maxY := screenHeight - texture.Height
sprite := &Sprite{
texture: texture,
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 func() {
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
}
}()
return sprite
}
func (sprite *Sprite) Update() {
sprite.ch <- true
<-sprite.ch
}
func (sprite *Sprite) Draw(g graphics.GraphicsContext) {
geometryMatrix := matrix.IdentityGeometry()
geometryMatrix.Translate(float64(sprite.x), float64(sprite.y))
g.DrawTexture(sprite.texture.ID,
0, 0, sprite.texture.Width, sprite.texture.Height,
geometryMatrix,
matrix.IdentityColor())
}
type Sprites struct { type Sprites struct {
ebitenTexture graphics.Texture ebitenTexture graphics.Texture
sprites []*Sprite
} }
func NewSprites() *Sprites { func NewSprites() *Sprites {
return &Sprites{} return &Sprites{}
} }
func (game *Sprites) ScreenWidth() int {
return 256
}
func (game *Sprites) ScreenHeight() int {
return 240
}
func (game *Sprites) Init(tf graphics.TextureFactory) { func (game *Sprites) Init(tf graphics.TextureFactory) {
file, err := os.Open("ebiten.png")
if err != nil {
panic(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
game.ebitenTexture = tf.NewTextureFromImage(img)
game.sprites = []*Sprite{}
for i := 0; i < 200; i++ {
sprite := NewSprite(
game.ScreenWidth(),
game.ScreenHeight(),
game.ebitenTexture)
game.sprites = append(game.sprites, sprite)
}
} }
func (game *Sprites) Update() { func (game *Sprites) Update() {
for _, sprite := range game.sprites {
sprite.Update()
}
} }
func (game *Sprites) Draw(g graphics.GraphicsContext, offscreen graphics.Texture) { func (game *Sprites) Draw(g graphics.GraphicsContext, offscreen graphics.Texture) {
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
for _, sprite := range game.sprites {
sprite.Draw(g)
}
}
func init() {
rand.Seed(time.Now().UnixNano())
} }

View File

@ -24,9 +24,6 @@ import (
) )
type GlutUI struct { type GlutUI struct {
screenWidth int
screenHeight int
screenScale int
device graphics.Device device graphics.Device
} }
@ -43,7 +40,7 @@ func idle() {
C.glutPostRedisplay() C.glutPostRedisplay()
} }
func (ui *GlutUI) Init() { func (ui *GlutUI) Init(screenWidth, screenHeight, screenScale int) {
cargs := []*C.char{} cargs := []*C.char{}
for _, arg := range os.Args { for _, arg := range os.Args {
cargs = append(cargs, C.CString(arg)) cargs = append(cargs, C.CString(arg))
@ -55,15 +52,11 @@ func (ui *GlutUI) Init() {
}() }()
cargc := C.int(len(cargs)) cargc := C.int(len(cargs))
ui.screenWidth = 256
ui.screenHeight = 240
ui.screenScale = 2
C.glutInit(&cargc, &cargs[0]) C.glutInit(&cargc, &cargs[0])
C.glutInitDisplayMode(C.GLUT_RGBA) C.glutInitDisplayMode(C.GLUT_RGBA)
C.glutInitWindowSize( C.glutInitWindowSize(
C.int(ui.screenWidth*ui.screenScale), C.int(screenWidth*screenScale),
C.int(ui.screenHeight*ui.screenScale)) C.int(screenHeight*screenScale))
title := C.CString("Ebiten Demo") title := C.CString("Ebiten Demo")
defer C.free(unsafe.Pointer(title)) defer C.free(unsafe.Pointer(title))
@ -72,18 +65,6 @@ func (ui *GlutUI) Init() {
C.setGlutFuncs() C.setGlutFuncs()
} }
func (ui *GlutUI) ScreenWidth() int {
return ui.screenWidth
}
func (ui *GlutUI) ScreenHeight() int {
return ui.screenHeight
}
func (ui *GlutUI) ScreenScale() int {
return ui.screenScale
}
func (ui *GlutUI) Run(device graphics.Device) { func (ui *GlutUI) Run(device graphics.Device) {
ui.device = device ui.device = device
C.glutMainLoop() C.glutMainLoop()
@ -104,8 +85,10 @@ func main() {
default: default:
gm = game.NewRotatingImage() gm = game.NewRotatingImage()
} }
currentUI = &GlutUI{}
currentUI.Init()
ebiten.OpenGLRun(gm, currentUI) screenScale := 2
currentUI = &GlutUI{}
currentUI.Init(gm.ScreenWidth(), gm.ScreenHeight(), screenScale)
ebiten.OpenGLRun(gm, currentUI, screenScale)
} }