Add game/text

This commit is contained in:
Hajime Hoshi 2013-07-03 01:27:04 +09:00
parent b969c15ecf
commit 1a1bc9f0b3
10 changed files with 202 additions and 59 deletions

View File

@ -0,0 +1,53 @@
// 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 input
import (
"github.com/hajimehoshi/go.ebiten/graphics"
)
type Input struct {
}
func New() *Input {
return &Input{}
}
func (game *Input) ScreenWidth() int {
return 256
}
func (game *Input) ScreenHeight() int {
return 240
}
func (game *Input) Fps() int {
return 60
}
func (game *Input) Init(tf graphics.TextureFactory) {
}
func (game *Input) Update() {
}
func (game *Input) Draw(g graphics.Context, offscreen graphics.Texture) {
}

View File

@ -55,7 +55,7 @@ func (game *Monochrome) Fps() int {
}
func (game *Monochrome) Init(tf graphics.TextureFactory) {
file, err := os.Open("ebiten.png")
file, err := os.Open("images/ebiten.png")
if err != nil {
panic(err)
}

View File

@ -52,7 +52,7 @@ func (game *Rotating) Fps() int {
}
func (game *Rotating) Init(tf graphics.TextureFactory) {
file, err := os.Open("ebiten.png")
file, err := os.Open("images/ebiten.png")
if err != nil {
panic(err)
}

View File

@ -100,7 +100,7 @@ func (game *Sprites) Fps() int {
}
func (game *Sprites) Init(tf graphics.TextureFactory) {
file, err := os.Open("ebiten.png")
file, err := os.Open("images/ebiten.png")
if err != nil {
panic(err)
}

99
example/game/text/text.go Normal file
View File

@ -0,0 +1,99 @@
// 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

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -26,12 +26,12 @@ package main
// #include <GLUT/glut.h>
//
// void display(void);
// void mouse(int button, int state, int x, int y);
// void motion(int x, int y);
// void idle(void);
//
// static void setGlutFuncs(void) {
// glutDisplayFunc(display);
// glutMouseFunc(mouse);
// glutMotionFunc(motion);
// glutIdleFunc(idle);
// }
//
@ -39,10 +39,12 @@ import "C"
import (
"github.com/hajimehoshi/go.ebiten"
"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/text"
"github.com/hajimehoshi/go.ebiten/graphics"
"github.com/hajimehoshi/go.ebiten/graphics/opengl"
"os"
@ -51,23 +53,14 @@ import (
"unsafe"
)
type GlutInputEventState int
const (
GlutInputEventStateUp GlutInputEventState = iota
GlutInputEventStateDown
)
type GlutInputEvent struct {
State GlutInputEventState
X int
Y int
X int
Y int
}
type GlutUI struct {
screenScale int
glutInputEventCh chan GlutInputEvent
updating chan chan func()
glutInputting chan GlutInputEvent
updating chan chan func()
}
var currentUI *GlutUI
@ -81,21 +74,11 @@ func display() {
C.glutSwapBuffers()
}
//export mouse
func mouse(button, glutState, x, y C.int) {
var state GlutInputEventState
switch glutState {
case C.GLUT_UP:
state = GlutInputEventStateUp
case C.GLUT_DOWN:
state = GlutInputEventStateDown
default:
panic("invalid glutState")
}
currentUI.glutInputEventCh <- GlutInputEvent{
State: state,
X: int(x),
Y: int(y),
//export motion
func motion(x, y C.int) {
currentUI.glutInputting <- GlutInputEvent{
X: int(x),
Y: int(y),
}
}
@ -106,9 +89,8 @@ func idle() {
func NewGlutUI(screenWidth, screenHeight, screenScale int) *GlutUI {
ui := &GlutUI{
screenScale: screenScale,
glutInputEventCh: make(chan GlutInputEvent, 10),
updating: make(chan chan func()),
glutInputting: make(chan GlutInputEvent, 10),
updating: make(chan chan func()),
}
cargs := []*C.char{}
@ -153,6 +135,8 @@ func main() {
switch gameName {
case "blank":
game = blank.New()
case "input":
game = input.New()
case "monochrome":
game = monochrome.New()
case "rects":
@ -161,16 +145,19 @@ func main() {
game = rotating.New()
case "sprites":
game = sprites.New()
case "text":
game = text.New()
default:
game = rotating.New()
}
const screenScale = 2
currentUI = NewGlutUI(game.ScreenWidth(), game.ScreenHeight(),
screenScale)
screenWidth := game.ScreenWidth()
screenHeight := game.ScreenHeight()
currentUI = NewGlutUI(screenWidth, screenHeight, screenScale)
graphicsDevice := opengl.NewDevice(
game.ScreenWidth(), game.ScreenHeight(), screenScale,
screenWidth, screenHeight, screenScale,
currentUI.updating)
game.Init(graphicsDevice.TextureFactory())
@ -178,21 +165,25 @@ func main() {
input := make(chan ebiten.InputState)
go func() {
ch := currentUI.glutInputEventCh
var inputState ebiten.InputState
ch := currentUI.glutInputting
for {
event := <-ch
switch event.State {
case GlutInputEventStateUp:
inputState.IsTapped = false
inputState.X = 0
inputState.Y = 0
case GlutInputEventStateDown:
inputState.IsTapped = true
inputState.X = event.X
inputState.Y = event.Y
x := event.X / screenScale
y := event.Y / screenScale
if x < 0 {
x = 0
} else if screenWidth <= x {
x = screenWidth - 1
}
if y < 0 {
y = 0
} else if screenHeight <= y {
y = screenHeight - 1
}
input <- ebiten.InputState{
X: x,
Y: y,
}
input <- inputState
}
}()

View File

@ -53,7 +53,7 @@ type Context interface {
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
DrawTextureParts(textureID TextureID,
locations []TexturePart,
parts []TexturePart,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
SetOffscreen(textureID TextureID)

View File

@ -144,7 +144,7 @@ func (context *Context) DrawTexture(
}
func (context *Context) DrawTextureParts(
textureID graphics.TextureID, locations []graphics.TexturePart,
textureID graphics.TextureID, parts []graphics.TexturePart,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
texture := context.textures[textureID]
@ -160,11 +160,11 @@ func (context *Context) DrawTextureParts(
C.glEnableVertexAttribArray(C.GLuint(vertexAttrLocation))
C.glEnableVertexAttribArray(C.GLuint(textureAttrLocation))
// TODO: Refactoring
for _, location := range locations {
x1 := float32(location.LocationX)
x2 := float32(location.LocationX + location.Source.Width)
y1 := float32(location.LocationY)
y2 := float32(location.LocationY + location.Source.Height)
for _, part := range parts {
x1 := float32(part.LocationX)
x2 := float32(part.LocationX + part.Source.Width)
y1 := float32(part.LocationY)
y2 := float32(part.LocationY + part.Source.Height)
vertex := [...]float32{
x1, y1,
x2, y1,
@ -172,7 +172,7 @@ func (context *Context) DrawTextureParts(
x2, y2,
}
src := location.Source
src := part.Source
tu1 := float32(src.X) / float32(texture.textureWidth)
tu2 := float32(src.X+src.Width) / float32(texture.textureWidth)
tv1 := float32(src.Y) / float32(texture.textureHeight)