github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/mobile/example/sprite/main.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin linux windows 6 7 // An app that demonstrates the sprite package. 8 // 9 // Note: This demo is an early preview of Go 1.5. In order to build this 10 // program as an Android APK using the gomobile tool. 11 // 12 // See http://godoc.org/golang.org/x/mobile/cmd/gomobile to install gomobile. 13 // 14 // Get the sprite example and use gomobile to build or install it on your device. 15 // 16 // $ go get -d golang.org/x/mobile/example/sprite 17 // $ gomobile build golang.org/x/mobile/example/sprite # will build an APK 18 // 19 // # plug your Android device to your computer or start an Android emulator. 20 // # if you have adb installed on your machine, use gomobile install to 21 // # build and deploy the APK to an Android target. 22 // $ gomobile install golang.org/x/mobile/example/sprite 23 // 24 // Switch to your device or emulator to start the Basic application from 25 // the launcher. 26 // You can also run the application on your desktop by running the command 27 // below. (Note: It currently doesn't work on Windows.) 28 // $ go install golang.org/x/mobile/example/sprite && sprite 29 package main 30 31 import ( 32 "image" 33 "log" 34 "math" 35 "time" 36 37 _ "image/jpeg" 38 39 "golang.org/x/mobile/app" 40 "golang.org/x/mobile/asset" 41 "golang.org/x/mobile/event/lifecycle" 42 "golang.org/x/mobile/event/paint" 43 "golang.org/x/mobile/event/size" 44 "golang.org/x/mobile/exp/app/debug" 45 "golang.org/x/mobile/exp/f32" 46 "golang.org/x/mobile/exp/gl/glutil" 47 "golang.org/x/mobile/exp/sprite" 48 "golang.org/x/mobile/exp/sprite/clock" 49 "golang.org/x/mobile/exp/sprite/glsprite" 50 "golang.org/x/mobile/gl" 51 ) 52 53 var ( 54 startTime = time.Now() 55 images *glutil.Images 56 eng sprite.Engine 57 scene *sprite.Node 58 fps *debug.FPS 59 ) 60 61 func main() { 62 app.Main(func(a app.App) { 63 var glctx gl.Context 64 var sz size.Event 65 for e := range a.Events() { 66 switch e := a.Filter(e).(type) { 67 case lifecycle.Event: 68 switch e.Crosses(lifecycle.StageVisible) { 69 case lifecycle.CrossOn: 70 glctx, _ = e.DrawContext.(gl.Context) 71 onStart(glctx) 72 a.Send(paint.Event{}) 73 case lifecycle.CrossOff: 74 onStop() 75 glctx = nil 76 } 77 case size.Event: 78 sz = e 79 case paint.Event: 80 if glctx == nil || e.External { 81 continue 82 } 83 onPaint(glctx, sz) 84 a.Publish() 85 a.Send(paint.Event{}) // keep animating 86 } 87 } 88 }) 89 } 90 91 func onStart(glctx gl.Context) { 92 images = glutil.NewImages(glctx) 93 fps = debug.NewFPS(images) 94 eng = glsprite.Engine(images) 95 loadScene() 96 } 97 98 func onStop() { 99 eng.Release() 100 fps.Release() 101 images.Release() 102 } 103 104 func onPaint(glctx gl.Context, sz size.Event) { 105 glctx.ClearColor(1, 1, 1, 1) 106 glctx.Clear(gl.COLOR_BUFFER_BIT) 107 now := clock.Time(time.Since(startTime) * 60 / time.Second) 108 eng.Render(scene, now, sz) 109 fps.Draw(sz) 110 } 111 112 func newNode() *sprite.Node { 113 n := &sprite.Node{} 114 eng.Register(n) 115 scene.AppendChild(n) 116 return n 117 } 118 119 func loadScene() { 120 texs := loadTextures() 121 scene = &sprite.Node{} 122 eng.Register(scene) 123 eng.SetTransform(scene, f32.Affine{ 124 {1, 0, 0}, 125 {0, 1, 0}, 126 }) 127 128 var n *sprite.Node 129 130 n = newNode() 131 eng.SetSubTex(n, texs[texBooks]) 132 eng.SetTransform(n, f32.Affine{ 133 {36, 0, 0}, 134 {0, 36, 0}, 135 }) 136 137 n = newNode() 138 eng.SetSubTex(n, texs[texFire]) 139 eng.SetTransform(n, f32.Affine{ 140 {72, 0, 144}, 141 {0, 72, 144}, 142 }) 143 144 n = newNode() 145 n.Arranger = arrangerFunc(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { 146 // TODO: use a tweening library instead of manually arranging. 147 t0 := uint32(t) % 120 148 if t0 < 60 { 149 eng.SetSubTex(n, texs[texGopherR]) 150 } else { 151 eng.SetSubTex(n, texs[texGopherL]) 152 } 153 154 u := float32(t0) / 120 155 u = (1 - f32.Cos(u*2*math.Pi)) / 2 156 157 tx := 18 + u*48 158 ty := 36 + u*108 159 sx := 36 + u*36 160 sy := 36 + u*36 161 eng.SetTransform(n, f32.Affine{ 162 {sx, 0, tx}, 163 {0, sy, ty}, 164 }) 165 }) 166 } 167 168 const ( 169 texBooks = iota 170 texFire 171 texGopherR 172 texGopherL 173 ) 174 175 func loadTextures() []sprite.SubTex { 176 a, err := asset.Open("waza-gophers.jpeg") 177 if err != nil { 178 log.Fatal(err) 179 } 180 defer a.Close() 181 182 img, _, err := image.Decode(a) 183 if err != nil { 184 log.Fatal(err) 185 } 186 t, err := eng.LoadTexture(img) 187 if err != nil { 188 log.Fatal(err) 189 } 190 191 return []sprite.SubTex{ 192 texBooks: sprite.SubTex{t, image.Rect(4, 71, 132, 182)}, 193 texFire: sprite.SubTex{t, image.Rect(330, 56, 440, 155)}, 194 texGopherR: sprite.SubTex{t, image.Rect(152, 10, 152+140, 10+90)}, 195 texGopherL: sprite.SubTex{t, image.Rect(162, 120, 162+140, 120+90)}, 196 } 197 } 198 199 type arrangerFunc func(e sprite.Engine, n *sprite.Node, t clock.Time) 200 201 func (a arrangerFunc) Arrange(e sprite.Engine, n *sprite.Node, t clock.Time) { a(e, n, t) }