mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
ebiten: Add VibrateGamepad and implement this on browsers
Updates #1452
This commit is contained in:
parent
0d9a165e8f
commit
2aa232878d
@ -33,6 +33,7 @@ const (
|
||||
|
||||
type Game struct {
|
||||
touchIDs []ebiten.TouchID
|
||||
gamepadIDs []ebiten.GamepadID
|
||||
}
|
||||
|
||||
func (g *Game) Update() error {
|
||||
@ -42,11 +43,33 @@ func (g *Game) Update() error {
|
||||
ebiten.Vibrate(200 * time.Millisecond)
|
||||
}
|
||||
|
||||
g.gamepadIDs = g.gamepadIDs[:0]
|
||||
g.gamepadIDs = ebiten.AppendGamepadIDs(g.gamepadIDs)
|
||||
for _, id := range g.gamepadIDs {
|
||||
for b := ebiten.GamepadButton0; b <= ebiten.GamepadButtonMax; b++ {
|
||||
if !inpututil.IsGamepadButtonJustPressed(id, b) {
|
||||
continue
|
||||
}
|
||||
// TODO: Test weak-magnitude.
|
||||
op := &ebiten.VibrateGamepadOptions{
|
||||
Duration: 200 * time.Millisecond,
|
||||
StrongMagnitude: 1,
|
||||
WeakMagnitude: 0,
|
||||
}
|
||||
ebiten.VibrateGamepad(id, op)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
ebitenutil.DebugPrint(screen, "Touch the screen to vibrate the screen.")
|
||||
msg := "Touch the screen to vibrate the screen."
|
||||
if len(g.gamepadIDs) > 0 {
|
||||
msg += "\nPress a gamepad button to vibrate the gamepad."
|
||||
}
|
||||
ebitenutil.DebugPrint(screen, msg)
|
||||
}
|
||||
|
||||
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
package driver
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type GamepadID int
|
||||
|
||||
type TouchID int
|
||||
@ -36,5 +40,6 @@ type Input interface {
|
||||
StandardGamepadAxisValue(id GamepadID, button StandardGamepadAxis) float64
|
||||
StandardGamepadButtonValue(id GamepadID, button StandardGamepadButton) float64
|
||||
TouchPosition(id TouchID) (x, y int)
|
||||
VibrateGamepad(id GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64)
|
||||
Wheel() (xoff, yoff float64)
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ package glfw
|
||||
import (
|
||||
"math"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
||||
@ -409,6 +410,10 @@ func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button drive
|
||||
return gamepaddb.IsButtonPressed(g.guid, button, gamepadState{&g})
|
||||
}
|
||||
|
||||
func (i *Input) VibrateGamepad(id driver.GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||
// TODO: Implement this (#1452)
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Confirm that all the hat state values are the same.
|
||||
if gamepaddb.HatUp != glfw.HatUp {
|
||||
|
@ -17,11 +17,14 @@ package js
|
||||
import (
|
||||
"encoding/hex"
|
||||
"syscall/js"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
||||
)
|
||||
|
||||
var object = js.Global().Get("Object")
|
||||
|
||||
var (
|
||||
stringKeydown = js.ValueOf("keydown")
|
||||
stringKeypress = js.ValueOf("keypress")
|
||||
@ -60,6 +63,8 @@ type pos struct {
|
||||
}
|
||||
|
||||
type gamepad struct {
|
||||
value js.Value
|
||||
|
||||
name string
|
||||
mapping string
|
||||
axisNum int
|
||||
@ -310,7 +315,9 @@ func (i *Input) updateGamepads() {
|
||||
}
|
||||
|
||||
id := driver.GamepadID(gp.Get("index").Int())
|
||||
g := gamepad{}
|
||||
g := gamepad{
|
||||
value: gp,
|
||||
}
|
||||
g.name = gp.Get("id").String()
|
||||
g.mapping = gp.Get("mapping").String()
|
||||
|
||||
@ -506,3 +513,37 @@ func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button drive
|
||||
}
|
||||
return g.standardButtonPressed[button]
|
||||
}
|
||||
|
||||
func (i *Input) VibrateGamepad(id driver.GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// vibrationActuator is avaialble on Chrome.
|
||||
if va := g.value.Get("vibrationActuator"); va.Truthy() {
|
||||
if !va.Get("playEffect").Truthy() {
|
||||
return
|
||||
}
|
||||
|
||||
prop := object.New()
|
||||
prop.Set("startDelay", 0)
|
||||
prop.Set("duration", float64(duration/time.Millisecond))
|
||||
prop.Set("strongMagnitude", strongMagnitude)
|
||||
prop.Set("weakMagnitude", weakMagnitude)
|
||||
va.Call("playEffect", "dual-rumble", prop)
|
||||
return
|
||||
}
|
||||
|
||||
// hapticActuators is available on Firefox.
|
||||
if ha := g.value.Get("hapticActuators"); ha.Truthy() {
|
||||
// TODO: Is this order correct?
|
||||
if ha.Length() > 0 {
|
||||
ha.Index(0).Call("pulse", strongMagnitude, float64(duration/time.Millisecond))
|
||||
}
|
||||
if ha.Length() > 1 {
|
||||
ha.Index(1).Call("pulse", weakMagnitude, float64(duration/time.Millisecond))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -191,6 +191,10 @@ func (i *Input) IsMouseButtonPressed(key driver.MouseButton) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *Input) VibrateGamepad(id driver.GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||
// TODO: Implement this (#1452)
|
||||
}
|
||||
|
||||
func (i *Input) update(keys map[driver.Key]struct{}, runes []rune, touches []Touch) {
|
||||
i.ui.m.Lock()
|
||||
defer i.ui.m.Unlock()
|
||||
|
11
vibrate.go
11
vibrate.go
@ -28,8 +28,8 @@ func Vibrate(duration time.Duration) {
|
||||
uiDriver().Vibrate(duration)
|
||||
}
|
||||
|
||||
// GamepadVibrateOptions represents the options to vibrate a gamepad.
|
||||
type GamepadVibrateOptions struct {
|
||||
// VibrateGamepadOptions represents the options to vibrate a gamepad.
|
||||
type VibrateGamepadOptions struct {
|
||||
// Duration is the time duration of the effect.
|
||||
Duration time.Duration
|
||||
|
||||
@ -42,4 +42,9 @@ type GamepadVibrateOptions struct {
|
||||
WeakMagnitude float64
|
||||
}
|
||||
|
||||
// TODO: Add a function VibrateGamepad.
|
||||
// VibrateGamepad vibrates the specified gamepad with the specified options.
|
||||
//
|
||||
// VibrateGamepad is concurrent-safe.
|
||||
func VibrateGamepad(gamepadID GamepadID, options *VibrateGamepadOptions) {
|
||||
uiDriver().Input().VibrateGamepad(gamepadID, options.Duration, options.StrongMagnitude, options.WeakMagnitude)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user