From ff020e8b1c58ee918fde53f0eeed07b3fdb58426 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 18 Jan 2015 21:11:03 +0900 Subject: [PATCH] example/keyboard: Add a keyboard image --- example/generate.go | 18 +++ example/images/keyboard/keyboard.png | Bin 0 -> 3196 bytes example/internal/font.go | 6 +- example/keyboard/keyboard/gen.go | 169 ++++++++++++++++++++++++++ example/keyboard/keyboard/keyrects.go | 82 +++++++++++++ example/keyboard/main.go | 56 +++++++-- genkeys.go | 13 +- internal/assets/bindata.go | 2 +- internal/license.go | 34 ++++++ 9 files changed, 362 insertions(+), 18 deletions(-) create mode 100644 example/generate.go create mode 100644 example/images/keyboard/keyboard.png create mode 100644 example/keyboard/keyboard/gen.go create mode 100644 example/keyboard/keyboard/keyrects.go create mode 100644 internal/license.go diff --git a/example/generate.go b/example/generate.go new file mode 100644 index 000000000..a392de694 --- /dev/null +++ b/example/generate.go @@ -0,0 +1,18 @@ +// Copyright 2015 Hajime Hoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:generate go run keyboard/keyboard/gen.go +//go:generate gofmt -w . + +package example diff --git a/example/images/keyboard/keyboard.png b/example/images/keyboard/keyboard.png new file mode 100644 index 0000000000000000000000000000000000000000..dc3693760fc736f9649124d63431ca246b5dc7b0 GIT binary patch literal 3196 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 tPB(R0XZ$xt_}?w`e_E-BfX}XE^`> literal 0 HcmV?d00001 diff --git a/example/internal/font.go b/example/internal/font.go index c8a81ebea..3951552d6 100644 --- a/example/internal/font.go +++ b/example/internal/font.go @@ -19,6 +19,8 @@ import ( "github.com/hajimehoshi/ebiten/ebitenutil" "image/color" "math" + "path/filepath" + "runtime" "strings" ) @@ -40,7 +42,9 @@ func (f *Font) TextWidth(str string) int { } func init() { - arcadeFontImage, _, err := ebitenutil.NewImageFromFile("images/arcadefont.png", ebiten.FilterNearest) + _, path, _, _ := runtime.Caller(0) + arcadeFontPath := filepath.Join(filepath.Dir(path), "..", "images", "arcadefont.png") + arcadeFontImage, _, err := ebitenutil.NewImageFromFile(arcadeFontPath, ebiten.FilterNearest) if err != nil { panic(err) } diff --git a/example/keyboard/keyboard/gen.go b/example/keyboard/keyboard/gen.go new file mode 100644 index 000000000..3fb8b4f2e --- /dev/null +++ b/example/keyboard/keyboard/gen.go @@ -0,0 +1,169 @@ +// Copyright 2015 Hajime Hoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build ignore + +package main + +import ( + "github.com/hajimehoshi/ebiten" + "github.com/hajimehoshi/ebiten/example/internal" + einternal "github.com/hajimehoshi/ebiten/internal" + "image" + "image/color" + "image/png" + "log" + "os" + "text/template" +) + +var keyboardKeys = [][]string{ + {"Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", " ", " ", " ", "Del"}, + {"Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", " ", " ", "BS"}, + {"Ctrl", "A", "S", "D", "F", "G", "H", "J", "K", "L", " ", " ", "Enter"}, + {"Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", " ", " "}, + {" ", "Alt", "Space", " ", " "}, + {}, + {"", "Up", ""}, + {"Left", "Down", "Right"}, +} + +func drawKey(t *ebiten.Image, name string, x, y, width int) { + const height = 16 + width-- + c := color.White + t.DrawLine(x, y+3, x, y+height-3, c) + t.DrawLine(x+width-1, y+3, x+width-1, y+height-3, c) + t.DrawLine(x+3, y, x+width-3, y, c) + t.DrawLine(x+3, y+height-1, x+width-3, y+height-1, c) + + t.DrawLine(x, y+3, x+3, y, c) + t.DrawLine(x+width-4, y, x+width-1, y+3, c) + t.DrawLine(x, y+height-4, x+3, y+height-1, c) + t.DrawLine(x+width-1, y+height-4, x+width-4, y+height-1, c) + + internal.ArcadeFont.DrawText(t, name, x+4, y+5, 1, color.White) +} + +func outputKeyboardImage() (map[string]image.Rectangle, error) { + keyMap := map[string]image.Rectangle{} + img, err := ebiten.NewImage(320, 240, ebiten.FilterNearest) + if err != nil { + return nil, err + } + x, y := 0, 0 + for j, line := range keyboardKeys { + x = 0 + const height = 18 + for i, key := range line { + width := 16 + switch j { + default: + switch i { + case 0: + width = 16 + 8*(j+2) + case len(line) - 1: + width = 16 + 8*(j+2) + } + case 4: + switch i { + case 0: + width = 16 + 8*(j+2) + case 1: + width = 16 * 2 + case 2: + width = 16 * 5 + case 3: + width = 16 * 2 + case 4: + width = 16 + 8*(j+2) + } + case 6, 7: + width = 16 * 3 + } + if key != "" { + drawKey(img, key, x, y, width) + if key != " " { + keyMap[key] = image.Rect(x, y, x+width, y+height) + } + } + x += width + } + y += height + } + + f, err := os.Create("images/keyboard/keyboard.png") + if err != nil { + return nil, err + } + defer f.Close() + if err := png.Encode(f, img); err != nil { + return nil, err + } + return keyMap, nil +} + +const keyRectTmpl = `{{.License}} + +// DO NOT EDIT: This file is auto-generated by genkeys.go. + +package keyboard + +import ( + "image" +) + +var keyboardKeyRects = map[string]image.Rectangle{} + +func init() { +{{range $key, $rect := .KeyRectsMap}} keyboardKeyRects["{{$key}}"] = image.Rect({{$rect.Min.X}}, {{$rect.Min.Y}}, {{$rect.Max.X}}, {{$rect.Max.Y}}) +{{end}}} + +func KeyRect(name string) (image.Rectangle, bool) { + r, ok := keyboardKeyRects[name] + return r, ok +}` + +func outputKeyRectsGo(k map[string]image.Rectangle) error { + license, err := einternal.LicenseComment() + if err != nil { + return err + } + path := "keyboard/keyboard/keyrects.go" + + f, err := os.Create(path) + if err != nil { + return err + } + defer f.Close() + + tmpl, err := template.New(path).Parse(keyRectTmpl) + if err != nil { + return err + } + return tmpl.Execute(f, map[string]interface{}{ + "License": license, + "KeyRectsMap": k, + }) +} + +func main() { + m, err := outputKeyboardImage() + if err != nil { + log.Fatal(err) + } + if err := outputKeyRectsGo(m); err != nil { + log.Fatal(err) + } +} diff --git a/example/keyboard/keyboard/keyrects.go b/example/keyboard/keyboard/keyrects.go new file mode 100644 index 000000000..b301e4515 --- /dev/null +++ b/example/keyboard/keyboard/keyrects.go @@ -0,0 +1,82 @@ +// Copyright 2015 Hajime Hoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// DO NOT EDIT: This file is auto-generated by genkeys.go. + +package keyboard + +import ( + "image" +) + +var keyboardKeyRects = map[string]image.Rectangle{} + +func init() { + keyboardKeyRects[","] = image.Rect(168, 54, 184, 72) + keyboardKeyRects["."] = image.Rect(184, 54, 200, 72) + keyboardKeyRects["0"] = image.Rect(176, 0, 192, 18) + keyboardKeyRects["1"] = image.Rect(32, 0, 48, 18) + keyboardKeyRects["2"] = image.Rect(48, 0, 64, 18) + keyboardKeyRects["3"] = image.Rect(64, 0, 80, 18) + keyboardKeyRects["4"] = image.Rect(80, 0, 96, 18) + keyboardKeyRects["5"] = image.Rect(96, 0, 112, 18) + keyboardKeyRects["6"] = image.Rect(112, 0, 128, 18) + keyboardKeyRects["7"] = image.Rect(128, 0, 144, 18) + keyboardKeyRects["8"] = image.Rect(144, 0, 160, 18) + keyboardKeyRects["9"] = image.Rect(160, 0, 176, 18) + keyboardKeyRects["A"] = image.Rect(48, 36, 64, 54) + keyboardKeyRects["Alt"] = image.Rect(64, 72, 96, 90) + keyboardKeyRects["B"] = image.Rect(120, 54, 136, 72) + keyboardKeyRects["BS"] = image.Rect(232, 18, 272, 36) + keyboardKeyRects["C"] = image.Rect(88, 54, 104, 72) + keyboardKeyRects["Ctrl"] = image.Rect(0, 36, 48, 54) + keyboardKeyRects["D"] = image.Rect(80, 36, 96, 54) + keyboardKeyRects["Del"] = image.Rect(240, 0, 272, 18) + keyboardKeyRects["Down"] = image.Rect(48, 126, 96, 144) + keyboardKeyRects["E"] = image.Rect(72, 18, 88, 36) + keyboardKeyRects["Enter"] = image.Rect(224, 36, 272, 54) + keyboardKeyRects["Esc"] = image.Rect(0, 0, 32, 18) + keyboardKeyRects["F"] = image.Rect(96, 36, 112, 54) + keyboardKeyRects["G"] = image.Rect(112, 36, 128, 54) + keyboardKeyRects["H"] = image.Rect(128, 36, 144, 54) + keyboardKeyRects["I"] = image.Rect(152, 18, 168, 36) + keyboardKeyRects["J"] = image.Rect(144, 36, 160, 54) + keyboardKeyRects["K"] = image.Rect(160, 36, 176, 54) + keyboardKeyRects["L"] = image.Rect(176, 36, 192, 54) + keyboardKeyRects["Left"] = image.Rect(0, 126, 48, 144) + keyboardKeyRects["M"] = image.Rect(152, 54, 168, 72) + keyboardKeyRects["N"] = image.Rect(136, 54, 152, 72) + keyboardKeyRects["O"] = image.Rect(168, 18, 184, 36) + keyboardKeyRects["P"] = image.Rect(184, 18, 200, 36) + keyboardKeyRects["Q"] = image.Rect(40, 18, 56, 36) + keyboardKeyRects["R"] = image.Rect(88, 18, 104, 36) + keyboardKeyRects["Right"] = image.Rect(96, 126, 144, 144) + keyboardKeyRects["S"] = image.Rect(64, 36, 80, 54) + keyboardKeyRects["Shift"] = image.Rect(0, 54, 56, 72) + keyboardKeyRects["Space"] = image.Rect(96, 72, 176, 90) + keyboardKeyRects["T"] = image.Rect(104, 18, 120, 36) + keyboardKeyRects["Tab"] = image.Rect(0, 18, 40, 36) + keyboardKeyRects["U"] = image.Rect(136, 18, 152, 36) + keyboardKeyRects["Up"] = image.Rect(48, 108, 96, 126) + keyboardKeyRects["V"] = image.Rect(104, 54, 120, 72) + keyboardKeyRects["W"] = image.Rect(56, 18, 72, 36) + keyboardKeyRects["X"] = image.Rect(72, 54, 88, 72) + keyboardKeyRects["Y"] = image.Rect(120, 18, 136, 36) + keyboardKeyRects["Z"] = image.Rect(56, 54, 72, 72) +} + +func KeyRect(name string) (image.Rectangle, bool) { + r, ok := keyboardKeyRects[name] + return r, ok +} diff --git a/example/keyboard/main.go b/example/keyboard/main.go index 9635ea3b9..72d1221a0 100644 --- a/example/keyboard/main.go +++ b/example/keyboard/main.go @@ -17,10 +17,9 @@ package main import ( "github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten/ebitenutil" + "github.com/hajimehoshi/ebiten/example/keyboard/keyboard" "log" - "sort" "strconv" - "strings" ) const ( @@ -28,13 +27,23 @@ const ( screenHeight = 240 ) +var keyboardImage *ebiten.Image + +func init() { + var err error + keyboardImage, _, err = ebitenutil.NewImageFromFile("images/keyboard/keyboard.png", ebiten.FilterNearest) + if err != nil { + log.Fatal(err) + } +} + var keyNames = map[ebiten.Key]string{ - ebiten.KeyBackspace: "Backspace", - ebiten.KeyComma: "','", - ebiten.KeyDelete: "Delete", + ebiten.KeyBackspace: "BS", + ebiten.KeyComma: ",", + ebiten.KeyDelete: "Del", ebiten.KeyEnter: "Enter", ebiten.KeyEscape: "Esc", - ebiten.KeyPeriod: "'.'", + ebiten.KeyPeriod: ".", ebiten.KeySpace: "Space", ebiten.KeyTab: "Tab", @@ -50,7 +59,32 @@ var keyNames = map[ebiten.Key]string{ ebiten.KeyAlt: "Alt", } +type pressedKeysParts []string + +func (p pressedKeysParts) Len() int { + return len(p) +} + +func (p pressedKeysParts) Dst(i int) (x0, y0, x1, y1 int) { + k := p[i] + r, ok := keyboard.KeyRect(k) + if !ok { + return 0, 0, 0, 0 + } + return r.Min.X, r.Min.Y, r.Max.X, r.Max.Y +} + +func (p pressedKeysParts) Src(i int) (x0, y0, x1, y1 int) { + return p.Dst(i) +} + func update(screen *ebiten.Image) error { + const offsetX, offsetY = 24, 40 + op := &ebiten.DrawImageOptions{} + op.GeoM.Translate(offsetX, offsetY) + op.ColorM.Scale(0.5, 0.5, 0.5, 1) + screen.DrawImage(keyboardImage, op) + pressed := []string{} for i := 0; i <= 9; i++ { if ebiten.IsKeyPressed(ebiten.Key(i) + ebiten.Key0) { @@ -72,9 +106,13 @@ func update(screen *ebiten.Image) error { pressed = append(pressed, name) } } - sort.Strings(pressed) - str := "Pressed Keys: " + strings.Join(pressed, ", ") - ebitenutil.DebugPrint(screen, str) + + op = &ebiten.DrawImageOptions{ + ImageParts: pressedKeysParts(pressed), + } + op.GeoM.Translate(offsetX, offsetY) + screen.DrawImage(keyboardImage, op) + return nil } diff --git a/genkeys.go b/genkeys.go index 8192099f2..8502d8424 100644 --- a/genkeys.go +++ b/genkeys.go @@ -22,12 +22,11 @@ package main import ( - "io/ioutil" + "github.com/hajimehoshi/ebiten/internal" "log" "os" "sort" "strconv" - "strings" "text/template" ) @@ -224,12 +223,10 @@ func (k KeyNames) Swap(i, j int) { } func main() { - l, err := ioutil.ReadFile("license.txt") + license, err := internal.LicenseComment() if err != nil { log.Fatal(err) } - lines := strings.Split(string(l), "\n") - license := "// " + strings.Join(lines[:len(lines)-1], "\n// ") notice := "DO NOT EDIT: This file is auto-generated by genkeys.go." @@ -263,13 +260,15 @@ func main() { log.Fatal(err) } // NOTE: According to godoc, maps are automatically sorted by key. - tmpl.Execute(f, map[string]interface{}{ + if err := tmpl.Execute(f, map[string]interface{}{ "License": license, "Notice": notice, "KeyCodeToName": keyCodeToName, "Codes": codes, "KeyNames": names, "KeyNamesWithoutMods": namesWithoutMods, - }) + }); err != nil { + log.Fatal(err) + } } } diff --git a/internal/assets/bindata.go b/internal/assets/bindata.go index 08c28cc18..6db365d16 100644 --- a/internal/assets/bindata.go +++ b/internal/assets/bindata.go @@ -53,7 +53,7 @@ func text_png() (*asset, error) { return nil, err } - info := bindata_file_info{name: "text.png", size: 2058, mode: os.FileMode(420), modTime: time.Unix(1419689280, 0)} + info := bindata_file_info{name: "text.png", size: 2058, mode: os.FileMode(420), modTime: time.Unix(1420820510, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/internal/license.go b/internal/license.go new file mode 100644 index 000000000..864118f7c --- /dev/null +++ b/internal/license.go @@ -0,0 +1,34 @@ +// Copyright 2015 Hajime Hoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import ( + "io/ioutil" + "path/filepath" + "runtime" + "strings" +) + +func LicenseComment() (string, error) { + _, path, _, _ := runtime.Caller(0) + licensePath := filepath.Join(filepath.Dir(path), "..", "license.txt") + l, err := ioutil.ReadFile(licensePath) + if err != nil { + return "", err + } + lines := strings.Split(string(l), "\n") + license := "// " + strings.Join(lines[:len(lines)-1], "\n// ") + return license, nil +}