ebiten: Add Vibrate and VibrateOptions, and implement this on browsers

Updates #1452
This commit is contained in:
Hajime Hoshi 2021-10-23 18:27:27 +09:00
parent 96dc80fd08
commit b8a5ea7bd6
6 changed files with 125 additions and 0 deletions

65
examples/vibrate/main.go Normal file
View File

@ -0,0 +1,65 @@
// Copyright 2021 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build example
// +build example
package main
import (
"log"
"time"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
"github.com/hajimehoshi/ebiten/v2/inpututil"
)
const (
screenWidth = 640
screenHeight = 480
)
type Game struct {
touchIDs []ebiten.TouchID
}
func (g *Game) Update() error {
g.touchIDs = g.touchIDs[:0]
g.touchIDs = inpututil.AppendJustPressedTouchIDs(g.touchIDs)
if len(g.touchIDs) > 0 {
op := &ebiten.VibrateOptions{
Duration: 200 * time.Millisecond,
StrongMagnitude: 1,
}
ebiten.Vibrate(op)
}
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
ebitenutil.DebugPrint(screen, "Touch the screen to vibrate the screen.")
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}
func main() {
ebiten.SetWindowTitle("Vibrate (Ebiten Demo)")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}

View File

@ -17,6 +17,7 @@ package driver
import ( import (
"errors" "errors"
"image" "image"
"time"
) )
type UIContext interface { type UIContext interface {
@ -62,6 +63,8 @@ type UI interface {
SetScreenTransparent(transparent bool) SetScreenTransparent(transparent bool)
SetInitFocused(focused bool) SetInitFocused(focused bool)
Vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64)
Input() Input Input() Input
Window() Window Window() Window
Graphics() Graphics Graphics() Graphics

View File

@ -1685,3 +1685,7 @@ func (u *UserInterface) setOrigPos(x, y int) {
u.origPosX = x u.origPosX = x
u.origPosY = y u.origPosY = y
} }
func (u *UserInterface) Vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
// Do nothing.
}

View File

@ -648,6 +648,12 @@ func (u *UserInterface) SetInitFocused(focused bool) {
u.initFocused = focused u.initFocused = focused
} }
func (u *UserInterface) Vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
if js.Global().Get("navigator").Get("vibrate").Truthy() {
js.Global().Get("navigator").Call("vibrate", float64(duration/time.Millisecond))
}
}
func (u *UserInterface) Input() driver.Input { func (u *UserInterface) Input() driver.Input {
return &u.input return &u.input
} }

View File

@ -492,3 +492,7 @@ func (u *UserInterface) ScheduleFrame() {
u.renderRequester.RequestRenderIfNeeded() u.renderRequester.RequestRenderIfNeeded()
} }
} }
func (u *UserInterface) Vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
// TODO: Implement this (#1452)
}

43
vibrate.go Normal file
View File

@ -0,0 +1,43 @@
// Copyright 2021 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ebiten
import (
"time"
)
// VibrateOptions represents the options to vibrate a device.
type VibrateOptions struct {
// Duration is the time duration of the effect.
Duration time.Duration
// StrongMagnitude is the rumble intensity of a low-frequency rumble motor.
// The value is in between 0 and 1.
StrongMagnitude float64
// StrongMagnitude is the rumble intensity of a high-frequency rumble motor.
// The value is in between 0 and 1.
WeakMagnitude float64
}
// Vibrate vibrates the device.
//
// Vibrate works on mobiles and browsers.
// On browsers, StrongManitude and WeakMagnitude might be ignored.
//
// Vibrate is concurrent-safe.
func Vibrate(options *VibrateOptions) {
uiDriver().Vibrate(options.Duration, options.StrongMagnitude, options.WeakMagnitude)
}