github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/mobile/example/audio/main.go (about) 1 // Copyright 2015 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 6 7 // An app that makes a sound as the gopher hits the walls of the screen. 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 audio example and use gomobile to build or install it on your device. 15 // 16 // $ go get -d golang.org/x/mobile/example/audio 17 // $ gomobile build golang.org/x/mobile/example/audio # 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/audio 23 // 24 // Additionally, you can run the sample on your desktop environment 25 // by using the go tool. 26 // 27 // $ go install golang.org/x/mobile/example/audio && audio 28 // 29 // On Linux, you need to install OpenAL developer library by 30 // running the command below. 31 // 32 // $ apt-get install libopenal-dev 33 package main 34 35 import ( 36 "image" 37 "log" 38 "time" 39 40 _ "image/jpeg" 41 42 "golang.org/x/mobile/app" 43 "golang.org/x/mobile/asset" 44 "golang.org/x/mobile/event/lifecycle" 45 "golang.org/x/mobile/event/paint" 46 "golang.org/x/mobile/event/size" 47 "golang.org/x/mobile/exp/audio" 48 "golang.org/x/mobile/exp/f32" 49 "golang.org/x/mobile/exp/gl/glutil" 50 "golang.org/x/mobile/exp/sprite" 51 "golang.org/x/mobile/exp/sprite/clock" 52 "golang.org/x/mobile/exp/sprite/glsprite" 53 "golang.org/x/mobile/gl" 54 ) 55 56 const ( 57 width = 72 58 height = 60 59 ) 60 61 var ( 62 startTime = time.Now() 63 64 images *glutil.Images 65 eng sprite.Engine 66 scene *sprite.Node 67 68 player *audio.Player 69 70 sz size.Event 71 ) 72 73 func main() { 74 app.Main(func(a app.App) { 75 var glctx gl.Context 76 for e := range a.Events() { 77 switch e := a.Filter(e).(type) { 78 case lifecycle.Event: 79 switch e.Crosses(lifecycle.StageVisible) { 80 case lifecycle.CrossOn: 81 glctx, _ = e.DrawContext.(gl.Context) 82 onStart(glctx) 83 a.Send(paint.Event{}) 84 case lifecycle.CrossOff: 85 onStop() 86 glctx = nil 87 } 88 case size.Event: 89 sz = e 90 case paint.Event: 91 if glctx == nil || e.External { 92 continue 93 } 94 onPaint(glctx) 95 a.Publish() 96 a.Send(paint.Event{}) // keep animating 97 } 98 } 99 }) 100 } 101 102 func onStart(glctx gl.Context) { 103 images = glutil.NewImages(glctx) 104 eng = glsprite.Engine(images) 105 loadScene() 106 107 rc, err := asset.Open("boing.wav") 108 if err != nil { 109 log.Fatal(err) 110 } 111 player, err = audio.NewPlayer(rc, 0, 0) 112 if err != nil { 113 log.Fatal(err) 114 } 115 } 116 117 func onStop() { 118 eng.Release() 119 images.Release() 120 player.Close() 121 } 122 123 func onPaint(glctx gl.Context) { 124 glctx.ClearColor(1, 1, 1, 1) 125 glctx.Clear(gl.COLOR_BUFFER_BIT) 126 now := clock.Time(time.Since(startTime) * 60 / time.Second) 127 eng.Render(scene, now, sz) 128 } 129 130 func newNode() *sprite.Node { 131 n := &sprite.Node{} 132 eng.Register(n) 133 scene.AppendChild(n) 134 return n 135 } 136 137 func loadScene() { 138 gopher := loadGopher() 139 scene = &sprite.Node{} 140 eng.Register(scene) 141 eng.SetTransform(scene, f32.Affine{ 142 {1, 0, 0}, 143 {0, 1, 0}, 144 }) 145 146 var x, y float32 147 dx, dy := float32(1), float32(1) 148 149 n := newNode() 150 // TODO: Shouldn't arranger pass the size.Event? 151 n.Arranger = arrangerFunc(func(eng sprite.Engine, n *sprite.Node, t clock.Time) { 152 eng.SetSubTex(n, gopher) 153 154 if x < 0 { 155 dx = 1 156 boing() 157 } 158 if y < 0 { 159 dy = 1 160 boing() 161 } 162 if x+width > float32(sz.WidthPt) { 163 dx = -1 164 boing() 165 } 166 if y+height > float32(sz.HeightPt) { 167 dy = -1 168 boing() 169 } 170 171 x += dx 172 y += dy 173 174 eng.SetTransform(n, f32.Affine{ 175 {width, 0, x}, 176 {0, height, y}, 177 }) 178 }) 179 } 180 181 func boing() { 182 player.Seek(0) 183 player.Play() 184 } 185 186 func loadGopher() sprite.SubTex { 187 a, err := asset.Open("gopher.jpeg") 188 if err != nil { 189 log.Fatal(err) 190 } 191 defer a.Close() 192 193 img, _, err := image.Decode(a) 194 if err != nil { 195 log.Fatal(err) 196 } 197 t, err := eng.LoadTexture(img) 198 if err != nil { 199 log.Fatal(err) 200 } 201 return sprite.SubTex{t, image.Rect(0, 0, 360, 300)} 202 } 203 204 type arrangerFunc func(e sprite.Engine, n *sprite.Node, t clock.Time) 205 206 func (a arrangerFunc) Arrange(e sprite.Engine, n *sprite.Node, t clock.Time) { a(e, n, t) }