mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +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
|
||||
|
||||
## 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
|
||||
|
||||
```
|
||||
|
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:
|
||||
diff = float64(480-count) * 0.2
|
||||
}
|
||||
|
||||
if ebiten.IsRunningSlowly() {
|
||||
return nil
|
||||
}
|
||||
|
||||
screen.Fill(color.NRGBA{0x00, 0x00, 0x80, 0xff})
|
||||
|
||||
// Draw 100 Ebitens
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.ColorM.Scale(1.0, 1.0, 1.0, 0.5)
|
||||
for i := 0; i < 10*10; i++ {
|
||||
|
@ -62,6 +62,11 @@ var (
|
||||
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 {
|
||||
mouseButtonStates map[ebiten.MouseButton]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
|
||||
}
|
||||
|
||||
@ -90,25 +95,22 @@ func (i *Input) isKeyPressed(key ebiten.Key) bool {
|
||||
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
|
||||
}
|
||||
|
||||
// Player represents the current audio state.
|
||||
type Player struct {
|
||||
input *Input
|
||||
audioContext *audio.Context
|
||||
audioPlayer *audio.Player
|
||||
current time.Duration
|
||||
total time.Duration
|
||||
seBytes []uint8
|
||||
seCh chan []uint8
|
||||
seBytes []byte
|
||||
seCh chan []byte
|
||||
volume128 int
|
||||
}
|
||||
|
||||
var (
|
||||
musicPlayer *Player
|
||||
)
|
||||
|
||||
func playerBarRect() (x, y, w, h int) {
|
||||
w, h = 300, 4
|
||||
x = (screenWidth - w) / 2
|
||||
@ -141,9 +143,9 @@ func NewPlayer(audioContext *audio.Context) (*Player, error) {
|
||||
},
|
||||
audioContext: audioContext,
|
||||
audioPlayer: p,
|
||||
total: time.Second * time.Duration(s.Size()) / bytesPerSample / sampleRate,
|
||||
total: time.Second * time.Duration(s.Length()) / bytesPerSample / sampleRate,
|
||||
volume128: 128,
|
||||
seCh: make(chan []uint8),
|
||||
seCh: make(chan []byte),
|
||||
}
|
||||
if player.total == 0 {
|
||||
player.total = 1
|
||||
@ -173,32 +175,36 @@ func (p *Player) update() error {
|
||||
p.seCh = nil
|
||||
default:
|
||||
}
|
||||
|
||||
if p.audioPlayer.IsPlaying() {
|
||||
p.current = p.audioPlayer.Current()
|
||||
}
|
||||
p.updateBar()
|
||||
p.updatePlayPause()
|
||||
p.updateSE()
|
||||
p.updateVolume()
|
||||
if p.input.isKeyTriggered(ebiten.KeyB) {
|
||||
p.seekBarIfNeeded()
|
||||
p.switchPlayStateIfNeeded()
|
||||
p.playSEIfNeeded()
|
||||
p.updateVolumeIfNeeded()
|
||||
|
||||
if p.input.isKeyJustPressed(ebiten.KeyB) {
|
||||
b := ebiten.IsRunnableInBackground()
|
||||
ebiten.SetRunnableInBackground(!b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Player) updateSE() {
|
||||
func (p *Player) playSEIfNeeded() {
|
||||
if p.seBytes == nil {
|
||||
// Bytes for the SE is not loaded yet.
|
||||
return
|
||||
}
|
||||
if !p.input.isKeyTriggered(ebiten.KeyP) {
|
||||
|
||||
if !p.input.isKeyJustPressed(ebiten.KeyP) {
|
||||
return
|
||||
}
|
||||
sePlayer, _ := audio.NewPlayerFromBytes(p.audioContext, p.seBytes)
|
||||
sePlayer.Play()
|
||||
}
|
||||
|
||||
func (p *Player) updateVolume() {
|
||||
func (p *Player) updateVolumeIfNeeded() {
|
||||
if p.input.isKeyPressed(ebiten.KeyZ) {
|
||||
p.volume128--
|
||||
}
|
||||
@ -214,8 +220,8 @@ func (p *Player) updateVolume() {
|
||||
p.audioPlayer.SetVolume(float64(p.volume128) / 128)
|
||||
}
|
||||
|
||||
func (p *Player) updatePlayPause() {
|
||||
if !p.input.isKeyTriggered(ebiten.KeyS) {
|
||||
func (p *Player) switchPlayStateIfNeeded() {
|
||||
if !p.input.isKeyJustPressed(ebiten.KeyS) {
|
||||
return
|
||||
}
|
||||
if p.audioPlayer.IsPlaying() {
|
||||
@ -225,11 +231,12 @@ func (p *Player) updatePlayPause() {
|
||||
p.audioPlayer.Play()
|
||||
}
|
||||
|
||||
func (p *Player) updateBar() {
|
||||
if !p.input.isMouseButtonTriggered(ebiten.MouseButtonLeft) {
|
||||
func (p *Player) seekBarIfNeeded() {
|
||||
if !p.input.isMouseButtonJustPressed(ebiten.MouseButtonLeft) {
|
||||
return
|
||||
}
|
||||
// Start seeking.
|
||||
|
||||
// Calculate the next seeking position from the current cursor position.
|
||||
x, y := ebiten.CursorPosition()
|
||||
bx, by, bw, bh := playerBarRect()
|
||||
const padding = 4
|
||||
@ -249,40 +256,45 @@ func (p *Player) close() error {
|
||||
}
|
||||
|
||||
func (p *Player) draw(screen *ebiten.Image) {
|
||||
// Bar
|
||||
// Draw the bar.
|
||||
x, y, w, h := playerBarRect()
|
||||
ebitenutil.DrawRect(screen, float64(x), float64(y), float64(w), float64(h), playerBarColor)
|
||||
|
||||
currentTimeStr := "00:00"
|
||||
|
||||
// Current Time
|
||||
// Draw the cursor on the bar.
|
||||
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
|
||||
cx := int(time.Duration(w)*c/p.total) + x - cw/2
|
||||
cy := y - (ch-h)/2
|
||||
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
|
||||
Press S to toggle Play/Pause
|
||||
Press P to play SE
|
||||
Press Z or X to change volume of the music
|
||||
Press B to switch the run-in-background state
|
||||
%s`, ebiten.CurrentFPS(), currentTimeStr)
|
||||
Current Time: %s`, ebiten.CurrentFPS(), currentTimeStr)
|
||||
ebitenutil.DebugPrint(screen, msg)
|
||||
}
|
||||
|
||||
var (
|
||||
musicPlayer *Player
|
||||
)
|
||||
|
||||
func update(screen *ebiten.Image) error {
|
||||
if err := musicPlayer.update(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ebiten.IsRunningSlowly() {
|
||||
return nil
|
||||
}
|
||||
|
||||
musicPlayer.draw(screen)
|
||||
return nil
|
||||
}
|
||||
@ -300,10 +312,8 @@ func main() {
|
||||
if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Audio (Ebiten Demo)"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if musicPlayer != nil {
|
||||
if err := musicPlayer.close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := musicPlayer.close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
</code></pre></div>
|
||||
|
@ -34,15 +34,52 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"github.com/golang/freetype/truetype"
|
||||
"golang.org/x/image/font"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/audio"
|
||||
"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 (
|
||||
screenWidth = 320
|
||||
screenHeight = 240
|
||||
@ -64,15 +101,13 @@ var pcm = make([]float64, 4*sampleRate)
|
||||
const baseFreq = 220
|
||||
|
||||
func init() {
|
||||
s := float64(sampleRate)
|
||||
amp := []float64{1.0, 0.8, 0.6, 0.4, 0.2}
|
||||
x := []float64{4.0, 2.0, 1.0, 0.5, 0.25}
|
||||
for i := 0; i < len(pcm); i++ {
|
||||
v := 0.0
|
||||
twoPiF := 2.0 * math.Pi * baseFreq
|
||||
for j := 0; j < len(amp); j++ {
|
||||
a := amp[j] * math.Exp(-5*float64(i)/(x[j]*s))
|
||||
v += a * math.Sin(float64(i)*twoPiF*float64(j+1)/s)
|
||||
a := amp[j] * math.Exp(-5*float64(i)/(x[j]*sampleRate))
|
||||
v += a * math.Sin(2.0*math.Pi*float64(i)*baseFreq*float64(j+1)/sampleRate)
|
||||
}
|
||||
pcm[i] = v / 5.0
|
||||
}
|
||||
@ -175,7 +210,7 @@ func init() {
|
||||
x := i*width + 36
|
||||
height := 112
|
||||
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"}
|
||||
@ -186,7 +221,7 @@ func init() {
|
||||
x := i*width + 24
|
||||
height := 64
|
||||
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