examples/audio: Add buttons

This commit is contained in:
Hajime Hoshi 2021-05-04 01:27:57 +09:00
parent 11e76d3fc8
commit e1d0b902e1
9 changed files with 134 additions and 5 deletions

View File

@ -22,7 +22,9 @@ package main
import (
"bytes"
"fmt"
"image"
"image/color"
_ "image/png"
"io"
"io/ioutil"
"log"
@ -35,6 +37,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/audio/wav"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
raudio "github.com/hajimehoshi/ebiten/v2/examples/resources/audio"
riaudio "github.com/hajimehoshi/ebiten/v2/examples/resources/images/audio"
"github.com/hajimehoshi/ebiten/v2/inpututil"
)
@ -50,6 +53,44 @@ var (
playerCurrentColor = color.RGBA{0xff, 0xff, 0xff, 0xff}
)
var (
playButtonPosition image.Point
alertButtonPosition image.Point
playButtonImage *ebiten.Image
pauseButtonImage *ebiten.Image
alertButtonImage *ebiten.Image
)
func init() {
img, _, err := image.Decode(bytes.NewReader(riaudio.Play_png))
if err != nil {
panic(err)
}
playButtonImage = ebiten.NewImageFromImage(img)
img, _, err = image.Decode(bytes.NewReader(riaudio.Pause_png))
if err != nil {
panic(err)
}
pauseButtonImage = ebiten.NewImageFromImage(img)
img, _, err = image.Decode(bytes.NewReader(riaudio.Alert_png))
if err != nil {
panic(err)
}
alertButtonImage = ebiten.NewImageFromImage(img)
const buttonPadding = 16
w, _ := playButtonImage.Size()
playButtonPosition.X = (screenWidth - w*2 + buttonPadding*1) / 2
playButtonPosition.Y = screenHeight - 160
alertButtonPosition.X = playButtonPosition.X + w + buttonPadding
alertButtonPosition.Y = playButtonPosition.Y
}
type musicType int
const (
@ -172,13 +213,34 @@ func (p *Player) update() error {
return nil
}
func (p *Player) playSEIfNeeded() {
func (p *Player) shouldPlaySE() bool {
if p.seBytes == nil {
// Bytes for the SE is not loaded yet.
return
return false
}
if !inpututil.IsKeyJustPressed(ebiten.KeyP) {
if inpututil.IsKeyJustPressed(ebiten.KeyP) {
return true
}
r := image.Rectangle{
Min: alertButtonPosition,
Max: alertButtonPosition.Add(image.Pt(alertButtonImage.Size())),
}
if image.Pt(ebiten.CursorPosition()).In(r) {
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
return true
}
}
for _, id := range inpututil.JustPressedTouchIDs() {
if image.Pt(ebiten.TouchPosition(id)).In(r) {
return true
}
}
return false
}
func (p *Player) playSEIfNeeded() {
if !p.shouldPlaySE() {
return
}
sePlayer := audio.NewPlayerFromBytes(p.audioContext, p.seBytes)
@ -201,8 +263,29 @@ func (p *Player) updateVolumeIfNeeded() {
p.audioPlayer.SetVolume(float64(p.volume128) / 128)
}
func (p *Player) shouldSwitchPlayStateIfNeeded() bool {
if inpututil.IsKeyJustPressed(ebiten.KeyS) {
return true
}
r := image.Rectangle{
Min: playButtonPosition,
Max: playButtonPosition.Add(image.Pt(playButtonImage.Size())),
}
if image.Pt(ebiten.CursorPosition()).In(r) {
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
return true
}
}
for _, id := range inpututil.JustPressedTouchIDs() {
if image.Pt(ebiten.TouchPosition(id)).In(r) {
return true
}
}
return false
}
func (p *Player) switchPlayStateIfNeeded() {
if !inpututil.IsKeyJustPressed(ebiten.KeyS) {
if !p.shouldSwitchPlayStateIfNeeded() {
return
}
if p.audioPlayer.IsPlaying() {
@ -262,6 +345,18 @@ func (p *Player) draw(screen *ebiten.Image) {
s := (c / time.Second) % 60
currentTimeStr := fmt.Sprintf("%02d:%02d", m, s)
// Draw buttons
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(float64(playButtonPosition.X), float64(playButtonPosition.Y))
if p.audioPlayer.IsPlaying() {
screen.DrawImage(pauseButtonImage, op)
} else {
screen.DrawImage(playButtonImage, op)
}
op.GeoM.Reset()
op.GeoM.Translate(float64(alertButtonPosition.X), float64(alertButtonPosition.Y))
screen.DrawImage(alertButtonImage, op)
// Draw the debug message.
msg := fmt.Sprintf(`TPS: %0.2f
Press S to toggle Play/Pause

View File

@ -26,6 +26,9 @@
//go:generate file2byteslice -package=images -input=./images/runner.png -output=./images/runner.go -var=Runner_png
//go:generate file2byteslice -package=images -input=./images/tiles.png -output=./images/tiles.go -var=Tiles_png
//go:generate file2byteslice -package=images -input=./images/ui.png -output=./images/ui.go -var=UI_png
//go:generate file2byteslice -package=audio -input=./images/audio/alert.png -output=./images/audio/alert.go -var=Alert_png
//go:generate file2byteslice -package=audio -input=./images/audio/pause.png -output=./images/audio/pause.go -var=Pause_png
//go:generate file2byteslice -package=audio -input=./images/audio/play.png -output=./images/audio/play.go -var=Play_png
//go:generate file2byteslice -package=blocks -input=./images/blocks/background.png -output=./images/blocks/background.go -var=Background_png
//go:generate file2byteslice -package=blocks -input=./images/blocks/blocks.png -output=./images/blocks/blocks.go -var=Blocks_png
//go:generate file2byteslice -package=flappy -input=./images/flappy/gopher.png -output=./images/flappy/gopher.go -var=Gopher_png

View File

@ -0,0 +1,5 @@
// Code generated by file2byteslice. DO NOT EDIT.
package audio
var Alert_png = []byte("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\b\x04\x00\x00\x00\xfd\v1\f\x00\x00\x017IDATX\xc3c`\x18\x05\xa3`\x14P\x11\xfc\x0f\xfe\xbf\xf9?3\xad\fg\xfb?\xf9?\b\xb4\xd2\xc6x\xa5\xffg\xfeC\xc0\xdf\xff\xee\xb4\b\x9a\x0f\xffa\xe0\xe7\xff$\xca]\xbb\t\x85\xdf\xff\x1f\x01\xee\xfd7\xa1\xccp\x8e\xff\xf5\xff\xbf\xff\xff\x8f\"V\t7~\xed\u007f~ʌ\xf7\xf9\u007f\x17b\x12\x8a(\xe3\xff\xed\xe0\xa0ɥ8`\x10!\x81&'\xfa\xff\xd0\u007fc*\x04\f.\v(\x8dTx\xc0\xa0Z\xf0߂t\xa3\xa4\xff/\xfd\xff\xec?\x11\x00\xac\xfa\xcd\u007f5R\x8d\u007f\xf3\x9fH\x00V\xff\xff\xff\x1e\xd2,X\xfa\xff?\x89\x16\xfc\xff\xefD\x8a\x05Oɰ`&)\x16\xfc'Â\xab\xb8\xf5Sǂ\x8fC\xde\x02\x92\x82\x88\xe6\x91LN2u\xa4mF\xdbMۢ\xe2\xf5\u007fU\xf2\v8d\x83p\x15vf\x94\x94\xa0()\x81\x06\xc55\xa6Ax+\x1c\x91\xff\aI\xacpp\x18\x84\xab\xca\xdc\n\x14\xfa\xf1?\x87b\vpT\xfaep\x8f\xad&\xba\xd2\xc7\x17\xd6\x18͖IH\x91s\x97Ƞ\"-2\xff\x87\"5\xbc~\x10\xd5\xf0\"5\xb5\xfcW\xa6iӑ\x0e\x8d_:4\xdfG\xc1(\x18\xd2\x00\x00-\xdc\xe2\x06\xe3I\x8d\x19\x00\x00\x00\x00IEND\xaeB`\x82")

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

View File

@ -0,0 +1,5 @@
// Code generated by file2byteslice. DO NOT EDIT.
package audio
var Pause_png = []byte("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\x01\x00\x00\x00\x00\u007fy\xc4*\x00\x00\x00\x02tRNS\x00\x00v\x93\xcd8\x00\x00\x00\x13IDATx\x01c\xa0\x12\xe0\xff\xc0\xffahS\xd4\x01\x00\x86\x107\xc9\xdbPϏ\x00\x00\x00\x00IEND\xaeB`\x82")

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

View File

@ -0,0 +1,5 @@
// Code generated by file2byteslice. DO NOT EDIT.
package audio
var Play_png = []byte("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\b\x04\x00\x00\x00\xfd\v1\f\x00\x00\x00\x99IDATX\xc3\xed\xd6A\r\xc2@\x10F\xe1\xf6\u0095;\x0eЀ\n\\\xe0\x02\x17\xc8@\x05\x1aP\x80\x00\xae\x1cȇ\x02J\xd3\xdd?\x810\xcf\xc0K\xba\xaf33\fEQ\xfc\x01\xce6Y\x01w\acR\x00\x17۬\x80\x87\xa3UR\x00W\xbb\xac\x80\xa7\x93uR\x007\xfb\xac\x00\x1d\xe3\xf5\x8e^\xf1\x9a\xa2G\xbc\xa6i\x8f\xd7g\xda\xe25\x87\x96x\xcdei\xbc\xdf!\b\u007f\xa2\xe8#\x873\x8d\xfeh\xe1Q\x11\x1dv\xd1q\x1d^8ѕ\x19^\xfaѳ%|x\xa5OǢ(~\x80\x17,/\x87\x87\x9c\xa0y\xfd\x00\x00\x00\x00IEND\xaeB`\x82")

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

View File

@ -55,6 +55,22 @@ https://opengameart.org/content/orthographic-outdoor-tiles
CC0 1.0
```
## audio/play.png
```
https://fonts.google.com/icons
Apache License 2.0
```
## audio/pause.png
```
https://fonts.google.com/icons
Apache License 2.0
```
## flappy/gopher.png
```
@ -124,7 +140,7 @@ Generated by Magnus Wahlstrand (https://github.com/kyeett)
MIT License
```
## Other image files
## The other image files
```
Copyright 2014 Hajime Hoshi