-
Notifications
You must be signed in to change notification settings - Fork 84
/
shake.go
71 lines (62 loc) · 1.76 KB
/
shake.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package oak
import (
"image"
"math/rand"
"time"
"github.com/oakmound/oak/alg/floatgeom"
)
// A ScreenShaker knows how to shake a screen by a (or up to a) given magnitude.
// If Random is true, the Shaker will shake up to the (negative or positive)
// magnitude of each the X and Y axes. Otherwise, it will oscillate between
// negative magnitude and positive magnitude.
type ScreenShaker struct {
Random bool
Magnitude floatgeom.Point2
}
var (
// DefShaker is the global default shaker, used when oak.Shake is called.
DefShaker = ScreenShaker{false, floatgeom.Point2{1.0, 1.0}}
)
// ShakeScreen will Shake using the package global DefShaker
func ShakeScreen(dur time.Duration) {
DefShaker.Shake(dur)
}
// Shake shakes the screen based on this shaker's attributes. See ScreenShaker.
func (ss *ScreenShaker) Shake(dur time.Duration) {
doneTime := time.Now().Add(dur)
mag := ss.Magnitude
setViewPos := ViewPos
// If we end up doing this pattern more,
// we need to replace defaultUpdateScreen
// with a local definition of what updateScreen
// was when this was called
updateScreen = func(x, y int) {
setViewPos = image.Point{x, y}
defaultUpdateScreen(x, y)
}
if ss.Random {
randOff := mag
go func() {
for time.Now().Before(doneTime) {
ViewPos = setViewPos
ViewPos.X += int(randOff.X())
ViewPos.Y += int(randOff.Y())
mag = mag.MulConst(-1)
randOff = mag.MulConst(rand.Float64())
}
updateScreen = defaultUpdateScreen
updateScreen(setViewPos.X, setViewPos.Y)
}()
} else {
go func() {
for time.Now().Before(doneTime) {
ViewPos = setViewPos
ViewPos.X += int(mag.X())
ViewPos.Y += int(mag.Y())
mag = mag.MulConst(-1)
}
updateScreen = defaultUpdateScreen
updateScreen(setViewPos.X, setViewPos.Y)
}()
}
}