mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 03:58:55 +01:00
docs: Update
This commit is contained in:
parent
27e55d6629
commit
f325a70da2
BIN
docs/examples/_resources/fonts/arcade_n.ttf
Executable file
BIN
docs/examples/_resources/fonts/arcade_n.ttf
Executable file
Binary file not shown.
@ -1,5 +1,31 @@
|
|||||||
# License
|
# License
|
||||||
|
|
||||||
|
## arcade_n.ttf
|
||||||
|
|
||||||
|
```
|
||||||
|
=============================================================
|
||||||
|
P.Font Series No. : 1013
|
||||||
|
Type : TrueType
|
||||||
|
Family Name : Arcade
|
||||||
|
Style Name : Arcade Normal
|
||||||
|
Arcade Interlaced
|
||||||
|
Arcade Rounded
|
||||||
|
Author : Yuji Adachi
|
||||||
|
Description : Copyright (C)1997-2003 Yuji Adachi
|
||||||
|
Support URL : http://www.9031.com/
|
||||||
|
=============================================================
|
||||||
|
|
||||||
|
Attention
|
||||||
|
|
||||||
|
印刷物、WEBページ等での御使用は自由ですが、このフォントを、
|
||||||
|
作者の許可なく販売したり、営利目的の製品に添付することは禁じます。
|
||||||
|
また、このフォントのデザインは予告なく変更することがあります。
|
||||||
|
|
||||||
|
|
||||||
|
足立 裕司
|
||||||
|
yuji@9031.com
|
||||||
|
```
|
||||||
|
|
||||||
## mplus-1p-regular.ttf
|
## mplus-1p-regular.ttf
|
||||||
|
|
||||||
```
|
```
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 3.6 KiB |
@ -60,10 +60,14 @@ func update(screen *ebiten.Image) error {
|
|||||||
case 240 < count:
|
case 240 < count:
|
||||||
diff = float64(480-count) * 0.2
|
diff = float64(480-count) * 0.2
|
||||||
}
|
}
|
||||||
|
|
||||||
if ebiten.IsRunningSlowly() {
|
if ebiten.IsRunningSlowly() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.Fill(color.NRGBA{0x00, 0x00, 0x80, 0xff})
|
screen.Fill(color.NRGBA{0x00, 0x00, 0x80, 0xff})
|
||||||
|
|
||||||
|
// Draw 100 Ebitens
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
op.ColorM.Scale(1.0, 1.0, 1.0, 0.5)
|
op.ColorM.Scale(1.0, 1.0, 1.0, 0.5)
|
||||||
for i := 0; i < 10*10; i++ {
|
for i := 0; i < 10*10; i++ {
|
||||||
|
@ -62,6 +62,11 @@ var (
|
|||||||
playerCurrentColor = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
playerCurrentColor = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Input manages the current input state to detect keys 'just pressed'.
|
||||||
|
//
|
||||||
|
// Note: 'just pressed' is a very common idiom.
|
||||||
|
// There is a plan to create a new package for input utility.
|
||||||
|
// See https://github.com/hajimehoshi/ebiten/issues/415.
|
||||||
type Input struct {
|
type Input struct {
|
||||||
mouseButtonStates map[ebiten.MouseButton]int
|
mouseButtonStates map[ebiten.MouseButton]int
|
||||||
keyStates map[ebiten.Key]int
|
keyStates map[ebiten.Key]int
|
||||||
@ -82,7 +87,7 @@ func (i *Input) update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) isKeyTriggered(key ebiten.Key) bool {
|
func (i *Input) isKeyJustPressed(key ebiten.Key) bool {
|
||||||
return i.keyStates[key] == 1
|
return i.keyStates[key] == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,25 +95,22 @@ func (i *Input) isKeyPressed(key ebiten.Key) bool {
|
|||||||
return i.keyStates[key] > 0
|
return i.keyStates[key] > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) isMouseButtonTriggered(mouseButton ebiten.MouseButton) bool {
|
func (i *Input) isMouseButtonJustPressed(mouseButton ebiten.MouseButton) bool {
|
||||||
return i.mouseButtonStates[mouseButton] == 1
|
return i.mouseButtonStates[mouseButton] == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Player represents the current audio state.
|
||||||
type Player struct {
|
type Player struct {
|
||||||
input *Input
|
input *Input
|
||||||
audioContext *audio.Context
|
audioContext *audio.Context
|
||||||
audioPlayer *audio.Player
|
audioPlayer *audio.Player
|
||||||
current time.Duration
|
current time.Duration
|
||||||
total time.Duration
|
total time.Duration
|
||||||
seBytes []uint8
|
seBytes []byte
|
||||||
seCh chan []uint8
|
seCh chan []byte
|
||||||
volume128 int
|
volume128 int
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
musicPlayer *Player
|
|
||||||
)
|
|
||||||
|
|
||||||
func playerBarRect() (x, y, w, h int) {
|
func playerBarRect() (x, y, w, h int) {
|
||||||
w, h = 300, 4
|
w, h = 300, 4
|
||||||
x = (screenWidth - w) / 2
|
x = (screenWidth - w) / 2
|
||||||
@ -141,9 +143,9 @@ func NewPlayer(audioContext *audio.Context) (*Player, error) {
|
|||||||
},
|
},
|
||||||
audioContext: audioContext,
|
audioContext: audioContext,
|
||||||
audioPlayer: p,
|
audioPlayer: p,
|
||||||
total: time.Second * time.Duration(s.Size()) / bytesPerSample / sampleRate,
|
total: time.Second * time.Duration(s.Length()) / bytesPerSample / sampleRate,
|
||||||
volume128: 128,
|
volume128: 128,
|
||||||
seCh: make(chan []uint8),
|
seCh: make(chan []byte),
|
||||||
}
|
}
|
||||||
if player.total == 0 {
|
if player.total == 0 {
|
||||||
player.total = 1
|
player.total = 1
|
||||||
@ -173,32 +175,36 @@ func (p *Player) update() error {
|
|||||||
p.seCh = nil
|
p.seCh = nil
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.audioPlayer.IsPlaying() {
|
if p.audioPlayer.IsPlaying() {
|
||||||
p.current = p.audioPlayer.Current()
|
p.current = p.audioPlayer.Current()
|
||||||
}
|
}
|
||||||
p.updateBar()
|
p.seekBarIfNeeded()
|
||||||
p.updatePlayPause()
|
p.switchPlayStateIfNeeded()
|
||||||
p.updateSE()
|
p.playSEIfNeeded()
|
||||||
p.updateVolume()
|
p.updateVolumeIfNeeded()
|
||||||
if p.input.isKeyTriggered(ebiten.KeyB) {
|
|
||||||
|
if p.input.isKeyJustPressed(ebiten.KeyB) {
|
||||||
b := ebiten.IsRunnableInBackground()
|
b := ebiten.IsRunnableInBackground()
|
||||||
ebiten.SetRunnableInBackground(!b)
|
ebiten.SetRunnableInBackground(!b)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) updateSE() {
|
func (p *Player) playSEIfNeeded() {
|
||||||
if p.seBytes == nil {
|
if p.seBytes == nil {
|
||||||
|
// Bytes for the SE is not loaded yet.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !p.input.isKeyTriggered(ebiten.KeyP) {
|
|
||||||
|
if !p.input.isKeyJustPressed(ebiten.KeyP) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sePlayer, _ := audio.NewPlayerFromBytes(p.audioContext, p.seBytes)
|
sePlayer, _ := audio.NewPlayerFromBytes(p.audioContext, p.seBytes)
|
||||||
sePlayer.Play()
|
sePlayer.Play()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) updateVolume() {
|
func (p *Player) updateVolumeIfNeeded() {
|
||||||
if p.input.isKeyPressed(ebiten.KeyZ) {
|
if p.input.isKeyPressed(ebiten.KeyZ) {
|
||||||
p.volume128--
|
p.volume128--
|
||||||
}
|
}
|
||||||
@ -214,8 +220,8 @@ func (p *Player) updateVolume() {
|
|||||||
p.audioPlayer.SetVolume(float64(p.volume128) / 128)
|
p.audioPlayer.SetVolume(float64(p.volume128) / 128)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) updatePlayPause() {
|
func (p *Player) switchPlayStateIfNeeded() {
|
||||||
if !p.input.isKeyTriggered(ebiten.KeyS) {
|
if !p.input.isKeyJustPressed(ebiten.KeyS) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if p.audioPlayer.IsPlaying() {
|
if p.audioPlayer.IsPlaying() {
|
||||||
@ -225,11 +231,12 @@ func (p *Player) updatePlayPause() {
|
|||||||
p.audioPlayer.Play()
|
p.audioPlayer.Play()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) updateBar() {
|
func (p *Player) seekBarIfNeeded() {
|
||||||
if !p.input.isMouseButtonTriggered(ebiten.MouseButtonLeft) {
|
if !p.input.isMouseButtonJustPressed(ebiten.MouseButtonLeft) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Start seeking.
|
|
||||||
|
// Calculate the next seeking position from the current cursor position.
|
||||||
x, y := ebiten.CursorPosition()
|
x, y := ebiten.CursorPosition()
|
||||||
bx, by, bw, bh := playerBarRect()
|
bx, by, bw, bh := playerBarRect()
|
||||||
const padding = 4
|
const padding = 4
|
||||||
@ -249,40 +256,45 @@ func (p *Player) close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) draw(screen *ebiten.Image) {
|
func (p *Player) draw(screen *ebiten.Image) {
|
||||||
// Bar
|
// Draw the bar.
|
||||||
x, y, w, h := playerBarRect()
|
x, y, w, h := playerBarRect()
|
||||||
ebitenutil.DrawRect(screen, float64(x), float64(y), float64(w), float64(h), playerBarColor)
|
ebitenutil.DrawRect(screen, float64(x), float64(y), float64(w), float64(h), playerBarColor)
|
||||||
|
|
||||||
currentTimeStr := "00:00"
|
// Draw the cursor on the bar.
|
||||||
|
|
||||||
// Current Time
|
|
||||||
c := p.current
|
c := p.current
|
||||||
m := (c / time.Minute) % 100
|
|
||||||
s := (c / time.Second) % 60
|
|
||||||
currentTimeStr = fmt.Sprintf("%02d:%02d", m, s)
|
|
||||||
|
|
||||||
// Cursor
|
|
||||||
cw, ch := 4, 10
|
cw, ch := 4, 10
|
||||||
cx := int(time.Duration(w)*c/p.total) + x - cw/2
|
cx := int(time.Duration(w)*c/p.total) + x - cw/2
|
||||||
cy := y - (ch-h)/2
|
cy := y - (ch-h)/2
|
||||||
ebitenutil.DrawRect(screen, float64(cx), float64(cy), float64(cw), float64(ch), playerCurrentColor)
|
ebitenutil.DrawRect(screen, float64(cx), float64(cy), float64(cw), float64(ch), playerCurrentColor)
|
||||||
|
|
||||||
|
// Compose the curren time text.
|
||||||
|
m := (c / time.Minute) % 100
|
||||||
|
s := (c / time.Second) % 60
|
||||||
|
currentTimeStr := fmt.Sprintf("%02d:%02d", m, s)
|
||||||
|
|
||||||
|
// Draw the debug message.
|
||||||
msg := fmt.Sprintf(`FPS: %0.2f
|
msg := fmt.Sprintf(`FPS: %0.2f
|
||||||
Press S to toggle Play/Pause
|
Press S to toggle Play/Pause
|
||||||
Press P to play SE
|
Press P to play SE
|
||||||
Press Z or X to change volume of the music
|
Press Z or X to change volume of the music
|
||||||
Press B to switch the run-in-background state
|
Press B to switch the run-in-background state
|
||||||
%s`, ebiten.CurrentFPS(), currentTimeStr)
|
Current Time: %s`, ebiten.CurrentFPS(), currentTimeStr)
|
||||||
ebitenutil.DebugPrint(screen, msg)
|
ebitenutil.DebugPrint(screen, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
musicPlayer *Player
|
||||||
|
)
|
||||||
|
|
||||||
func update(screen *ebiten.Image) error {
|
func update(screen *ebiten.Image) error {
|
||||||
if err := musicPlayer.update(); err != nil {
|
if err := musicPlayer.update(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ebiten.IsRunningSlowly() {
|
if ebiten.IsRunningSlowly() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
musicPlayer.draw(screen)
|
musicPlayer.draw(screen)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -300,12 +312,10 @@ func main() {
|
|||||||
if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Audio (Ebiten Demo)"); err != nil {
|
if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Audio (Ebiten Demo)"); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
if musicPlayer != nil {
|
|
||||||
if err := musicPlayer.close(); err != nil {
|
if err := musicPlayer.close(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</code></pre></div>
|
</code></pre></div>
|
||||||
|
|
||||||
</div></main>
|
</div></main>
|
||||||
|
@ -34,15 +34,52 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"github.com/golang/freetype/truetype"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/audio"
|
"github.com/hajimehoshi/ebiten/audio"
|
||||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||||
"github.com/hajimehoshi/ebiten/examples/common"
|
"github.com/hajimehoshi/ebiten/text"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
arcadeFontSize = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
arcadeFont font.Face
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
f, err := ebitenutil.OpenFile(ebitenutil.JoinStringsIntoFilePath("_resources", "fonts", "arcade_n.ttf"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tt, err := truetype.Parse(b)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const dpi = 72
|
||||||
|
arcadeFont = truetype.NewFace(tt, &truetype.Options{
|
||||||
|
Size: arcadeFontSize,
|
||||||
|
DPI: dpi,
|
||||||
|
Hinting: font.HintingFull,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
screenWidth = 320
|
screenWidth = 320
|
||||||
screenHeight = 240
|
screenHeight = 240
|
||||||
@ -64,15 +101,13 @@ var pcm = make([]float64, 4*sampleRate)
|
|||||||
const baseFreq = 220
|
const baseFreq = 220
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
s := float64(sampleRate)
|
|
||||||
amp := []float64{1.0, 0.8, 0.6, 0.4, 0.2}
|
amp := []float64{1.0, 0.8, 0.6, 0.4, 0.2}
|
||||||
x := []float64{4.0, 2.0, 1.0, 0.5, 0.25}
|
x := []float64{4.0, 2.0, 1.0, 0.5, 0.25}
|
||||||
for i := 0; i < len(pcm); i++ {
|
for i := 0; i < len(pcm); i++ {
|
||||||
v := 0.0
|
v := 0.0
|
||||||
twoPiF := 2.0 * math.Pi * baseFreq
|
|
||||||
for j := 0; j < len(amp); j++ {
|
for j := 0; j < len(amp); j++ {
|
||||||
a := amp[j] * math.Exp(-5*float64(i)/(x[j]*s))
|
a := amp[j] * math.Exp(-5*float64(i)/(x[j]*sampleRate))
|
||||||
v += a * math.Sin(float64(i)*twoPiF*float64(j+1)/s)
|
v += a * math.Sin(2.0*math.Pi*float64(i)*baseFreq*float64(j+1)/sampleRate)
|
||||||
}
|
}
|
||||||
pcm[i] = v / 5.0
|
pcm[i] = v / 5.0
|
||||||
}
|
}
|
||||||
@ -175,7 +210,7 @@ func init() {
|
|||||||
x := i*width + 36
|
x := i*width + 36
|
||||||
height := 112
|
height := 112
|
||||||
ebitenutil.DrawRect(imagePiano, float64(x), float64(y), float64(width-1), float64(height), color.White)
|
ebitenutil.DrawRect(imagePiano, float64(x), float64(y), float64(width-1), float64(height), color.White)
|
||||||
common.ArcadeFont.DrawText(imagePiano, k, x+8, y+height-16, 1, color.Black)
|
text.Draw(imagePiano, k, arcadeFont, x+8, y+height-8, color.Black)
|
||||||
}
|
}
|
||||||
|
|
||||||
blackKeys := []string{"Q", "W", "", "R", "T", "", "U", "I", "O"}
|
blackKeys := []string{"Q", "W", "", "R", "T", "", "U", "I", "O"}
|
||||||
@ -186,7 +221,7 @@ func init() {
|
|||||||
x := i*width + 24
|
x := i*width + 24
|
||||||
height := 64
|
height := 64
|
||||||
ebitenutil.DrawRect(imagePiano, float64(x), float64(y), float64(width-1), float64(height), color.Black)
|
ebitenutil.DrawRect(imagePiano, float64(x), float64(y), float64(width-1), float64(height), color.Black)
|
||||||
common.ArcadeFont.DrawText(imagePiano, k, x+8, y+height-16, 1, color.White)
|
text.Draw(imagePiano, k, arcadeFont, x+8, y+height-8, color.White)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user