-
Notifications
You must be signed in to change notification settings - Fork 0
/
callbacks.go
112 lines (88 loc) · 2.68 KB
/
callbacks.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package world
import (
"syscall/js"
"github.com/ByteArena/box2d"
)
func (worldState *WorldState) HandleKeys(this js.Value, args []js.Value) interface{} {
e := args[0]
if e.Get("which").Int() == 27 {
worldState.ResetWorld = true
}
return nil
}
func (worldState *WorldState) HandlePause(this js.Value, args []js.Value) interface{} {
worldState.Paused = true
return nil
}
func (worldState *WorldState) HandleUnpause(this js.Value, args []js.Value) interface{} {
worldState.Paused = false
return nil
}
func (worldState *WorldState) HandleClick(this js.Value, args []js.Value) interface{} {
e := args[0]
if e.Get("target") != worldState.Canvas {
return nil
}
// only allow launch if grounded aka welded to an object
if worldState.PlayerWelded || worldState.AbsorbCount > 0 {
mx := e.Get("clientX").Float() * worldState.WorldScale
my := e.Get("clientY").Float() * worldState.WorldScale
worldState.LaunchPlayer(mx, my)
}
// always clear joints on click to prevent sticking to multiple debris
worldState.ClearJoints(worldState.Player)
return nil
}
func (worldState *WorldState) RenderFrame(this js.Value, args []js.Value) interface{} {
defer func() {
renderFrame := js.FuncOf(worldState.RenderFrame)
js.Global().Call("requestAnimationFrame", renderFrame)
}()
now := args[0].Float()
tdiff := now - worldState.TMark
worldState.TMark = now
if worldState.Paused {
return nil
}
worldState.World.Step(tdiff/1000*worldState.SimSpeed, 60, 120)
resizing := worldState.Resize()
if resizing {
worldState.Resizing = true
worldState.LastResize = now
}
if now-worldState.LastResize > 150 && worldState.Resizing {
worldState.ResetWorld = true
worldState.Resizing = false
}
if worldState.IsPlayerOutOfBounds() {
worldState.ResetWorld = true
}
if worldState.ResetWorld {
worldState.Reset()
}
// check for new weld joint and execute it
worldState.WeldJoint()
worldState.Context.Call("clearRect", 0, 0, worldState.Width*worldState.WorldScale, worldState.Height*worldState.WorldScale)
draw := []*box2d.B2Body{}
drawLast := []*box2d.B2Body{}
// draw absorbing things last, so they can be drawn in front of others
for curBody := worldState.World.GetBodyList(); curBody != nil; curBody = curBody.M_next {
if absorber, ok := curBody.GetUserData().(Absorber); ok {
if absorber.Absorbs() {
drawLast = append(drawLast, curBody)
} else {
draw = append(draw, curBody)
}
}
}
for _, body := range draw {
worldState.Draw(body)
}
for _, body := range drawLast {
worldState.Draw(body)
}
return nil
}
type Absorber interface {
Absorbs() bool
}