mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
Add example/server to show examples on GopherJS; Update docs
This commit is contained in:
parent
3f45685136
commit
f631653681
@ -65,6 +65,12 @@ table.examples td.code pre {
|
||||
<pre><code>:; cd $GOHOME/src/github.com/hajimehoshi/ebiten/example
|
||||
:; go run rotate/main.go</code></pre>
|
||||
|
||||
<h2>Execute the example on your browser</h2>
|
||||
<pre><code>:; go get github.com/gopherjs/gopherjs
|
||||
:; go run $GOPATH/src/github.com/hajimehoshi/ebiten/example/server/main.go</code></pre>
|
||||
<p>Then, open <code>localhost:8000</code> on your browser.</p>
|
||||
<p><code>localhost:8000/?EXAMPLE_NAME</code> shows other examples (e.g. <code>localhost:8000/?rotate</code>).</p>
|
||||
|
||||
<h2>License</h2>
|
||||
<h3>Ebiten</h3>
|
||||
<pre>{{.License}}</pre>
|
||||
|
@ -41,6 +41,7 @@ table.examples td.code pre {
|
||||
<li>A simple SNES-like 2D game library in Go</li>
|
||||
<li>Works on
|
||||
<ul>
|
||||
<li>HTML5 (powered by <a href="http://gopherjs.org/">GopherJS</a>)
|
||||
<li>Mac OS X</li>
|
||||
<li>Linux (maybe)</li>
|
||||
<li>Windows (possibly)</li>
|
||||
@ -92,12 +93,10 @@ var (
|
||||
func update(screen *ebiten.Image) error {
|
||||
count++
|
||||
w, h := gophersImage.Size()
|
||||
geo := ebiten.TranslateGeo(float64(screenWidth-w)/2, float64(screenHeight-h)/2)
|
||||
clr := ebiten.RotateHue(float64(count%360) * 2 * math.Pi / 360)
|
||||
if err := screen.DrawImage(gophersImage, &ebiten.DrawImageOptions{
|
||||
GeoM: geo,
|
||||
ColorM: clr,
|
||||
}); err != nil {
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(float64(screenWidth-w)/2, float64(screenHeight-h)/2)
|
||||
op.ColorM.Concat(ebiten.RotateHue(float64(count%360) * 2 * math.Pi / 360))
|
||||
if err := screen.DrawImage(gophersImage, op); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -142,12 +141,12 @@ var (
|
||||
)
|
||||
|
||||
func update(screen *ebiten.Image) error {
|
||||
gophersRenderTarget.DrawImage(gophersImage, &ebiten.DrawImageOptions{
|
||||
GeoM: ebiten.ScaleGeo(1.0/mosaicRatio, 1.0/mosaicRatio),
|
||||
})
|
||||
screen.DrawImage(gophersRenderTarget, &ebiten.DrawImageOptions{
|
||||
GeoM: ebiten.ScaleGeo(mosaicRatio, mosaicRatio),
|
||||
})
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Scale(1.0/mosaicRatio, 1.0/mosaicRatio)
|
||||
gophersRenderTarget.DrawImage(gophersImage, op)
|
||||
op = &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Scale(mosaicRatio, mosaicRatio)
|
||||
screen.DrawImage(gophersRenderTarget, op)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -178,7 +177,6 @@ package main
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||
"image"
|
||||
_ "image/jpeg"
|
||||
"log"
|
||||
)
|
||||
@ -192,24 +190,36 @@ var (
|
||||
gophersImage *ebiten.Image
|
||||
)
|
||||
|
||||
type parts struct {
|
||||
image *ebiten.Image
|
||||
}
|
||||
|
||||
func (p parts) Len() int {
|
||||
_, h := p.image.Size()
|
||||
return h
|
||||
}
|
||||
|
||||
func (p parts) Dst(i int) (x0, y0, x1, y1 int) {
|
||||
w, h := p.image.Size()
|
||||
width := w + i*3/4
|
||||
x := ((h - i) * 3 / 4) / 2
|
||||
return x, i, x + width, i + 1
|
||||
}
|
||||
|
||||
func (p parts) Src(i int) (x0, y0, x1, y1 int) {
|
||||
w, _ := p.image.Size()
|
||||
return 0, i, w, i + 1
|
||||
}
|
||||
|
||||
func update(screen *ebiten.Image) error {
|
||||
parts := []ebiten.ImagePart{}
|
||||
w, h := gophersImage.Size()
|
||||
for i := 0; i < h; i++ {
|
||||
width := w + i*3/4
|
||||
x := ((h - i) * 3 / 4) / 2
|
||||
parts = append(parts, ebiten.ImagePart{
|
||||
Dst: image.Rect(x, i, x+width, i+1),
|
||||
Src: image.Rect(0, i, w, i+1),
|
||||
})
|
||||
op := &ebiten.DrawImageOptions{
|
||||
ImageParts: &parts{gophersImage},
|
||||
}
|
||||
w, h := gophersImage.Size()
|
||||
maxWidth := float64(w) + float64(h)*0.75
|
||||
geo := ebiten.TranslateGeo(-maxWidth/2, -float64(h)/2)
|
||||
geo.Concat(ebiten.TranslateGeo(screenWidth/2, screenHeight/2))
|
||||
screen.DrawImage(gophersImage, &ebiten.DrawImageOptions{
|
||||
Parts: parts,
|
||||
GeoM: geo,
|
||||
})
|
||||
op.GeoM.Translate(-maxWidth/2, -float64(h)/2)
|
||||
op.GeoM.Translate(screenWidth/2, screenHeight/2)
|
||||
screen.DrawImage(gophersImage, op)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -253,12 +263,11 @@ var (
|
||||
func update(screen *ebiten.Image) error {
|
||||
count++
|
||||
w, h := gophersImage.Size()
|
||||
geo := ebiten.TranslateGeo(-float64(w)/2, -float64(h)/2)
|
||||
geo.Concat(ebiten.RotateGeo(float64(count%360) * 2 * math.Pi / 360))
|
||||
geo.Concat(ebiten.TranslateGeo(screenWidth/2, screenHeight/2))
|
||||
if err := screen.DrawImage(gophersImage, &ebiten.DrawImageOptions{
|
||||
GeoM: geo,
|
||||
}); err != nil {
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
|
||||
op.GeoM.Rotate(float64(count%360) * 2 * math.Pi / 360)
|
||||
op.GeoM.Translate(screenWidth/2, screenHeight/2)
|
||||
if err := screen.DrawImage(gophersImage, op); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -284,11 +293,19 @@ func main() {
|
||||
<pre><code>:; brew install glew
|
||||
:; brew install glfw3 # or homebrew/versions/glfw3
|
||||
:; go get -u github.com/hajimehoshi/ebiten</code></pre>
|
||||
<p>If you want to use GopherJS, execute this:</p>
|
||||
<pre><code>:; go get -u -tag=js github.com/hajimehoshi/ebiten</code></pre>
|
||||
|
||||
<h2>Execute the example</h2>
|
||||
<pre><code>:; cd $GOHOME/src/github.com/hajimehoshi/ebiten/example
|
||||
:; go run rotate/main.go</code></pre>
|
||||
|
||||
<h2>Execute the example on your browser</h2>
|
||||
<pre><code>:; go get github.com/gopherjs/gopherjs
|
||||
:; go run $GOPATH/src/github.com/hajimehoshi/ebiten/example/server/main.go</code></pre>
|
||||
<p>Then, open <code>localhost:8000</code> on your browser.</p>
|
||||
<p><code>localhost:8000/?EXAMPLE_NAME</code> shows other examples (e.g. <code>localhost:8000/?rotate</code>).</p>
|
||||
|
||||
<h2>License</h2>
|
||||
<h3>Ebiten</h3>
|
||||
<pre>Copyright 2015 Hajime Hoshi
|
||||
|
17
example/index.html
Normal file
17
example/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<script src="main.js"></script>
|
143
example/server/main.go
Normal file
143
example/server/main.go
Normal file
@ -0,0 +1,143 @@
|
||||
// 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 main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var port = flag.Int("port", 8000, "port number")
|
||||
|
||||
func init() {
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
var rootPath = ""
|
||||
|
||||
func init() {
|
||||
_, path, _, _ := runtime.Caller(0)
|
||||
rootPath = filepath.Join(filepath.Dir(path), "..")
|
||||
}
|
||||
|
||||
var jsDir = ""
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
jsDir, err = ioutil.TempDir("", "ebiten")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func createJSIfNeeded(name string) (string, error) {
|
||||
out := filepath.Join(jsDir, name, "main.js")
|
||||
stat, err := os.Stat(out)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return "", err
|
||||
}
|
||||
if (err != nil && os.IsNotExist(err)) || time.Now().Sub(stat.ModTime()) > 10*time.Second {
|
||||
target := "github.com/hajimehoshi/ebiten/example/" + name
|
||||
if err := exec.Command("gopherjs", "build", "-o", out, target).Run(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func serveFile(w http.ResponseWriter, path, mime string) error {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
w.Header().Set("Content-Type", mime)
|
||||
if _, err := io.Copy(w, f); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func appName(r *http.Request) (string, error) {
|
||||
u, err := url.Parse(r.Referer())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
q := u.RawQuery
|
||||
if q == "" {
|
||||
q = "blocks"
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func serveMainJS(w http.ResponseWriter, r *http.Request) {
|
||||
name, err := appName(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprint(w, err.Error())
|
||||
return
|
||||
}
|
||||
out, err := createJSIfNeeded(name)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprint(w, err.Error())
|
||||
return
|
||||
}
|
||||
if err := serveFile(w, out, "text/javascript"); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprint(w, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func serveMainJSMap(w http.ResponseWriter, r *http.Request) {
|
||||
name, err := appName(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprint(w, err.Error())
|
||||
return
|
||||
}
|
||||
out, err := createJSIfNeeded(name)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprint(w, err.Error())
|
||||
return
|
||||
}
|
||||
out += ".map"
|
||||
if err := serveFile(w, out, "application/octet-stream"); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprint(w, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/main.js", serveMainJS)
|
||||
http.HandleFunc("/main.js.map", serveMainJSMap)
|
||||
http.Handle("/", http.FileServer(http.Dir(rootPath)))
|
||||
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*port), nil))
|
||||
}
|
17
readme.md
17
readme.md
@ -41,14 +41,25 @@ If you want to use GopherJS, execute this:
|
||||
## Execute the example
|
||||
|
||||
```
|
||||
:; cd $GOHOME/src/github.com/hajimehoshi/ebiten/example
|
||||
:; go run rotate/main.go
|
||||
:; cd $GOPATH/src/github.com/hajimehoshi/ebiten/example
|
||||
:; go run blocks/main.go
|
||||
```
|
||||
|
||||
## Execute the example on your browser
|
||||
|
||||
```
|
||||
:; go get github.com/gopherjs/gopherjs
|
||||
:; go run $GOPATH/src/github.com/hajimehoshi/ebiten/example/server/main.go
|
||||
```
|
||||
|
||||
Then, open ``localhost:8000`` on your browser.
|
||||
|
||||
``localhost:8000/?EXAMPLE_NAME`` shows other examples (e.g. ``localhost:8000/?rotate``).
|
||||
|
||||
### Benchmark the example
|
||||
|
||||
```
|
||||
:; cd $GOHOME/src/github.com/hajimehoshi/ebiten/example
|
||||
:; cd $GOPATH/src/github.com/hajimehoshi/ebiten/example
|
||||
:; go build -o=example blocks/main.go
|
||||
:; ./example -cpuprofile=cpu.out
|
||||
:; go tool pprof ./example cpu.out
|
||||
|
Loading…
Reference in New Issue
Block a user