mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-24 01:42:05 +01:00
Add game/text
This commit is contained in:
parent
b969c15ecf
commit
1a1bc9f0b3
53
example/game/input/input.go
Normal file
53
example/game/input/input.go
Normal 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) {
|
||||||
|
}
|
@ -55,7 +55,7 @@ func (game *Monochrome) Fps() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (game *Monochrome) Init(tf graphics.TextureFactory) {
|
func (game *Monochrome) Init(tf graphics.TextureFactory) {
|
||||||
file, err := os.Open("ebiten.png")
|
file, err := os.Open("images/ebiten.png")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func (game *Rotating) Fps() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (game *Rotating) Init(tf graphics.TextureFactory) {
|
func (game *Rotating) Init(tf graphics.TextureFactory) {
|
||||||
file, err := os.Open("ebiten.png")
|
file, err := os.Open("images/ebiten.png")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ func (game *Sprites) Fps() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (game *Sprites) Init(tf graphics.TextureFactory) {
|
func (game *Sprites) Init(tf graphics.TextureFactory) {
|
||||||
file, err := os.Open("ebiten.png")
|
file, err := os.Open("images/ebiten.png")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
99
example/game/text/text.go
Normal file
99
example/game/text/text.go
Normal 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)
|
||||||
|
}
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
example/glut/images/text.png
Normal file
BIN
example/glut/images/text.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
@ -26,12 +26,12 @@ package main
|
|||||||
// #include <GLUT/glut.h>
|
// #include <GLUT/glut.h>
|
||||||
//
|
//
|
||||||
// void display(void);
|
// void display(void);
|
||||||
// void mouse(int button, int state, int x, int y);
|
// void motion(int x, int y);
|
||||||
// void idle(void);
|
// void idle(void);
|
||||||
//
|
//
|
||||||
// static void setGlutFuncs(void) {
|
// static void setGlutFuncs(void) {
|
||||||
// glutDisplayFunc(display);
|
// glutDisplayFunc(display);
|
||||||
// glutMouseFunc(mouse);
|
// glutMotionFunc(motion);
|
||||||
// glutIdleFunc(idle);
|
// glutIdleFunc(idle);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
@ -39,10 +39,12 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/go.ebiten"
|
"github.com/hajimehoshi/go.ebiten"
|
||||||
"github.com/hajimehoshi/go.ebiten/example/game/blank"
|
"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/monochrome"
|
||||||
"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"
|
||||||
@ -51,23 +53,14 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GlutInputEventState int
|
|
||||||
|
|
||||||
const (
|
|
||||||
GlutInputEventStateUp GlutInputEventState = iota
|
|
||||||
GlutInputEventStateDown
|
|
||||||
)
|
|
||||||
|
|
||||||
type GlutInputEvent struct {
|
type GlutInputEvent struct {
|
||||||
State GlutInputEventState
|
X int
|
||||||
X int
|
Y int
|
||||||
Y int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GlutUI struct {
|
type GlutUI struct {
|
||||||
screenScale int
|
glutInputting chan GlutInputEvent
|
||||||
glutInputEventCh chan GlutInputEvent
|
updating chan chan func()
|
||||||
updating chan chan func()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentUI *GlutUI
|
var currentUI *GlutUI
|
||||||
@ -81,21 +74,11 @@ func display() {
|
|||||||
C.glutSwapBuffers()
|
C.glutSwapBuffers()
|
||||||
}
|
}
|
||||||
|
|
||||||
//export mouse
|
//export motion
|
||||||
func mouse(button, glutState, x, y C.int) {
|
func motion(x, y C.int) {
|
||||||
var state GlutInputEventState
|
currentUI.glutInputting <- GlutInputEvent{
|
||||||
switch glutState {
|
X: int(x),
|
||||||
case C.GLUT_UP:
|
Y: int(y),
|
||||||
state = GlutInputEventStateUp
|
|
||||||
case C.GLUT_DOWN:
|
|
||||||
state = GlutInputEventStateDown
|
|
||||||
default:
|
|
||||||
panic("invalid glutState")
|
|
||||||
}
|
|
||||||
currentUI.glutInputEventCh <- GlutInputEvent{
|
|
||||||
State: state,
|
|
||||||
X: int(x),
|
|
||||||
Y: int(y),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,9 +89,8 @@ func idle() {
|
|||||||
|
|
||||||
func NewGlutUI(screenWidth, screenHeight, screenScale int) *GlutUI {
|
func NewGlutUI(screenWidth, screenHeight, screenScale int) *GlutUI {
|
||||||
ui := &GlutUI{
|
ui := &GlutUI{
|
||||||
screenScale: screenScale,
|
glutInputting: make(chan GlutInputEvent, 10),
|
||||||
glutInputEventCh: make(chan GlutInputEvent, 10),
|
updating: make(chan chan func()),
|
||||||
updating: make(chan chan func()),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cargs := []*C.char{}
|
cargs := []*C.char{}
|
||||||
@ -153,6 +135,8 @@ func main() {
|
|||||||
switch gameName {
|
switch gameName {
|
||||||
case "blank":
|
case "blank":
|
||||||
game = blank.New()
|
game = blank.New()
|
||||||
|
case "input":
|
||||||
|
game = input.New()
|
||||||
case "monochrome":
|
case "monochrome":
|
||||||
game = monochrome.New()
|
game = monochrome.New()
|
||||||
case "rects":
|
case "rects":
|
||||||
@ -161,16 +145,19 @@ 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()
|
||||||
}
|
}
|
||||||
|
|
||||||
const screenScale = 2
|
const screenScale = 2
|
||||||
currentUI = NewGlutUI(game.ScreenWidth(), game.ScreenHeight(),
|
screenWidth := game.ScreenWidth()
|
||||||
screenScale)
|
screenHeight := game.ScreenHeight()
|
||||||
|
currentUI = NewGlutUI(screenWidth, screenHeight, screenScale)
|
||||||
|
|
||||||
graphicsDevice := opengl.NewDevice(
|
graphicsDevice := opengl.NewDevice(
|
||||||
game.ScreenWidth(), game.ScreenHeight(), screenScale,
|
screenWidth, screenHeight, screenScale,
|
||||||
currentUI.updating)
|
currentUI.updating)
|
||||||
|
|
||||||
game.Init(graphicsDevice.TextureFactory())
|
game.Init(graphicsDevice.TextureFactory())
|
||||||
@ -178,21 +165,25 @@ func main() {
|
|||||||
|
|
||||||
input := make(chan ebiten.InputState)
|
input := make(chan ebiten.InputState)
|
||||||
go func() {
|
go func() {
|
||||||
ch := currentUI.glutInputEventCh
|
ch := currentUI.glutInputting
|
||||||
var inputState ebiten.InputState
|
|
||||||
for {
|
for {
|
||||||
event := <-ch
|
event := <-ch
|
||||||
switch event.State {
|
x := event.X / screenScale
|
||||||
case GlutInputEventStateUp:
|
y := event.Y / screenScale
|
||||||
inputState.IsTapped = false
|
if x < 0 {
|
||||||
inputState.X = 0
|
x = 0
|
||||||
inputState.Y = 0
|
} else if screenWidth <= x {
|
||||||
case GlutInputEventStateDown:
|
x = screenWidth - 1
|
||||||
inputState.IsTapped = true
|
}
|
||||||
inputState.X = event.X
|
if y < 0 {
|
||||||
inputState.Y = event.Y
|
y = 0
|
||||||
|
} else if screenHeight <= y {
|
||||||
|
y = screenHeight - 1
|
||||||
|
}
|
||||||
|
input <- ebiten.InputState{
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
}
|
}
|
||||||
input <- inputState
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ type Context interface {
|
|||||||
geometryMatrix matrix.Geometry,
|
geometryMatrix matrix.Geometry,
|
||||||
colorMatrix matrix.Color)
|
colorMatrix matrix.Color)
|
||||||
DrawTextureParts(textureID TextureID,
|
DrawTextureParts(textureID TextureID,
|
||||||
locations []TexturePart,
|
parts []TexturePart,
|
||||||
geometryMatrix matrix.Geometry,
|
geometryMatrix matrix.Geometry,
|
||||||
colorMatrix matrix.Color)
|
colorMatrix matrix.Color)
|
||||||
SetOffscreen(textureID TextureID)
|
SetOffscreen(textureID TextureID)
|
||||||
|
@ -144,7 +144,7 @@ func (context *Context) DrawTexture(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) DrawTextureParts(
|
func (context *Context) DrawTextureParts(
|
||||||
textureID graphics.TextureID, locations []graphics.TexturePart,
|
textureID graphics.TextureID, parts []graphics.TexturePart,
|
||||||
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
||||||
|
|
||||||
texture := context.textures[textureID]
|
texture := context.textures[textureID]
|
||||||
@ -160,11 +160,11 @@ func (context *Context) DrawTextureParts(
|
|||||||
C.glEnableVertexAttribArray(C.GLuint(vertexAttrLocation))
|
C.glEnableVertexAttribArray(C.GLuint(vertexAttrLocation))
|
||||||
C.glEnableVertexAttribArray(C.GLuint(textureAttrLocation))
|
C.glEnableVertexAttribArray(C.GLuint(textureAttrLocation))
|
||||||
// TODO: Refactoring
|
// TODO: Refactoring
|
||||||
for _, location := range locations {
|
for _, part := range parts {
|
||||||
x1 := float32(location.LocationX)
|
x1 := float32(part.LocationX)
|
||||||
x2 := float32(location.LocationX + location.Source.Width)
|
x2 := float32(part.LocationX + part.Source.Width)
|
||||||
y1 := float32(location.LocationY)
|
y1 := float32(part.LocationY)
|
||||||
y2 := float32(location.LocationY + location.Source.Height)
|
y2 := float32(part.LocationY + part.Source.Height)
|
||||||
vertex := [...]float32{
|
vertex := [...]float32{
|
||||||
x1, y1,
|
x1, y1,
|
||||||
x2, y1,
|
x2, y1,
|
||||||
@ -172,7 +172,7 @@ func (context *Context) DrawTextureParts(
|
|||||||
x2, y2,
|
x2, y2,
|
||||||
}
|
}
|
||||||
|
|
||||||
src := location.Source
|
src := part.Source
|
||||||
tu1 := float32(src.X) / float32(texture.textureWidth)
|
tu1 := float32(src.X) / float32(texture.textureWidth)
|
||||||
tu2 := float32(src.X+src.Width) / float32(texture.textureWidth)
|
tu2 := float32(src.X+src.Width) / float32(texture.textureWidth)
|
||||||
tv1 := float32(src.Y) / float32(texture.textureHeight)
|
tv1 := float32(src.Y) / float32(texture.textureHeight)
|
||||||
|
Loading…
Reference in New Issue
Block a user