/
hero.go
112 lines (98 loc) · 2.5 KB
/
hero.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 main
import (
"bytes"
"image/color"
"io"
"os"
"github.com/faiface/pixel"
"github.com/faiface/pixel/imdraw"
"github.com/faiface/pixel/pixelgl"
"github.com/svera/quarter/animation"
"github.com/svera/quarter/bound"
"github.com/svera/quarter/physic"
)
const (
impulse = 64
)
type Hero struct {
*physic.Physics
*animation.Animation
heroBounds map[string][]bound.Shaper
}
func NewHero(dataFile string) (*Hero, error) {
r, err := os.Open(dataFile)
if err != nil {
return nil, err
}
var buf bytes.Buffer
tee := io.TeeReader(r, &buf)
anim, err := animation.Deserialize(tee, pixel.V(64, 32))
if err != nil {
panic(err)
}
anim.SetCurrentAnim("idle")
bounds, err := bound.Deserialize(&buf)
if err != nil {
return nil, err
}
return &Hero{
physic.NewPhysics(
physic.Params{
MaxVelocity: [2]float64{50, 100},
Acceleration: [2]float64{75, 0},
Gravity: 112,
},
),
anim,
bounds,
}, nil
}
func (h *Hero) Jump(dt float64) {
if h.CurrentAnim() != "jumping" && h.CurrentAnim() != "falling" {
h.SetVelocity(physic.AxisY, impulse)
}
}
func (h *Hero) Left(dt float64) {
h.Dir = physic.DirectionLeft
h.Accelerate(physic.AxisX, h.Dir, dt)
}
func (h *Hero) Right(dt float64) {
h.Dir = physic.DirectionRight
h.Accelerate(physic.AxisX, h.Dir, dt)
}
func (h *Hero) Draw(target *pixelgl.Canvas, debug *color.RGBA, imd *imdraw.IMDraw, dt float64) {
h.Animation.Draw(target, dt)
h.boundingShape().Draw(debug, imd, target)
}
func (h *Hero) updatePosition(sol bound.Solution, delta pixel.Vec) {
if sol.CollisionAxis == bound.AxisX {
h.SetVelocity(physic.AxisX, 0)
h.Position = h.Position.Add(pixel.V(sol.Distance.X, delta.Y))
} else if sol.CollisionAxis == bound.AxisY {
h.SetVelocity(physic.AxisY, 0)
h.Position = h.Position.Add(pixel.V(delta.X, sol.Distance.Y))
} else if sol.CollisionAxis == bound.AxisBoth {
h.SetVelocity(physic.AxisY, 0)
h.SetVelocity(physic.AxisX, 0)
h.Position = h.Position.Add(sol.Distance)
} else {
h.Position = h.Position.Add(delta)
}
h.updateAnim(sol)
}
func (h *Hero) boundingShape() bound.Shape {
bb := h.heroBounds[h.CurrentAnim()][h.CurrentFrameNumber()]
bb.Shape().Align(h.Position)
return bb.Shape()
}
func (h *Hero) updateAnim(sol bound.Solution) {
if h.Velocity(physic.AxisY) > 0 {
h.SetCurrentAnim("jumping")
} else if h.Velocity(physic.AxisY) < 0 && sol.CollisionAxis != bound.AxisY {
h.SetCurrentAnim("falling")
} else if h.Velocity(physic.AxisX) != 0 {
h.SetCurrentAnim("running")
} else {
h.SetCurrentAnim("idle")
}
}