mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 19:28:57 +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 {
|
type Game struct {
|
||||||
touchIDs []ebiten.TouchID
|
touchIDs []ebiten.TouchID
|
||||||
|
gamepadIDs []ebiten.GamepadID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update() error {
|
func (g *Game) Update() error {
|
||||||
@ -42,11 +43,33 @@ func (g *Game) Update() error {
|
|||||||
ebiten.Vibrate(200 * time.Millisecond)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Draw(screen *ebiten.Image) {
|
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) {
|
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
package driver
|
package driver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type GamepadID int
|
type GamepadID int
|
||||||
|
|
||||||
type TouchID int
|
type TouchID int
|
||||||
@ -36,5 +40,6 @@ type Input interface {
|
|||||||
StandardGamepadAxisValue(id GamepadID, button StandardGamepadAxis) float64
|
StandardGamepadAxisValue(id GamepadID, button StandardGamepadAxis) float64
|
||||||
StandardGamepadButtonValue(id GamepadID, button StandardGamepadButton) float64
|
StandardGamepadButtonValue(id GamepadID, button StandardGamepadButton) float64
|
||||||
TouchPosition(id TouchID) (x, y int)
|
TouchPosition(id TouchID) (x, y int)
|
||||||
|
VibrateGamepad(id GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64)
|
||||||
Wheel() (xoff, yoff float64)
|
Wheel() (xoff, yoff float64)
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ package glfw
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
"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})
|
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() {
|
func init() {
|
||||||
// Confirm that all the hat state values are the same.
|
// Confirm that all the hat state values are the same.
|
||||||
if gamepaddb.HatUp != glfw.HatUp {
|
if gamepaddb.HatUp != glfw.HatUp {
|
||||||
|
@ -17,11 +17,14 @@ package js
|
|||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var object = js.Global().Get("Object")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
stringKeydown = js.ValueOf("keydown")
|
stringKeydown = js.ValueOf("keydown")
|
||||||
stringKeypress = js.ValueOf("keypress")
|
stringKeypress = js.ValueOf("keypress")
|
||||||
@ -60,6 +63,8 @@ type pos struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type gamepad struct {
|
type gamepad struct {
|
||||||
|
value js.Value
|
||||||
|
|
||||||
name string
|
name string
|
||||||
mapping string
|
mapping string
|
||||||
axisNum int
|
axisNum int
|
||||||
@ -310,7 +315,9 @@ func (i *Input) updateGamepads() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := driver.GamepadID(gp.Get("index").Int())
|
id := driver.GamepadID(gp.Get("index").Int())
|
||||||
g := gamepad{}
|
g := gamepad{
|
||||||
|
value: gp,
|
||||||
|
}
|
||||||
g.name = gp.Get("id").String()
|
g.name = gp.Get("id").String()
|
||||||
g.mapping = gp.Get("mapping").String()
|
g.mapping = gp.Get("mapping").String()
|
||||||
|
|
||||||
@ -506,3 +513,37 @@ func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button drive
|
|||||||
}
|
}
|
||||||
return g.standardButtonPressed[button]
|
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
|
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) {
|
func (i *Input) update(keys map[driver.Key]struct{}, runes []rune, touches []Touch) {
|
||||||
i.ui.m.Lock()
|
i.ui.m.Lock()
|
||||||
defer i.ui.m.Unlock()
|
defer i.ui.m.Unlock()
|
||||||
|
11
vibrate.go
11
vibrate.go
@ -28,8 +28,8 @@ func Vibrate(duration time.Duration) {
|
|||||||
uiDriver().Vibrate(duration)
|
uiDriver().Vibrate(duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GamepadVibrateOptions represents the options to vibrate a gamepad.
|
// VibrateGamepadOptions represents the options to vibrate a gamepad.
|
||||||
type GamepadVibrateOptions struct {
|
type VibrateGamepadOptions struct {
|
||||||
// Duration is the time duration of the effect.
|
// Duration is the time duration of the effect.
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
|
|
||||||
@ -42,4 +42,9 @@ type GamepadVibrateOptions struct {
|
|||||||
WeakMagnitude float64
|
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