forked from maxfish/gojira2d
/
player.go
155 lines (138 loc) · 3.7 KB
/
player.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"github.com/go-gl/mathgl/mgl32"
g "github.com/markov/gojira2d/pkg/graphics"
"fmt"
"github.com/go-gl/glfw/v3.2/glfw"
"math"
)
const (
playersStopAtX = float32(550)
maxSpeed = 9
FragmentShaderPlayerDead = `
#version 410 core
in vec2 uv_out;
out vec4 color;
uniform sampler2D tex;
void main() {
if(texture(tex, uv_out).a != 1.0f)
{
discard;
}
float grayScale = dot(texture(tex, uv_out).rgb, vec3(0.299, 0.587, 0.114));
color = vec4(grayScale, grayScale, grayScale, 1.0);
}
` + "\x00"
)
type Player struct {
quad *g.Primitive2D
shadowQuad *g.Primitive2D
speed float32
key0 glfw.Key
key1 glfw.Key
lastKeyInteraction float64
position mgl32.Vec3
runningSprites []*g.Texture
numberOfFrames int
currentFrameIndex int
animationSpeed float32
canStart bool
isDead bool
isWinner bool
offsetXStartLine float32
playerName string
mugshotTexturePath string
deathShader *g.ShaderProgram
}
func NewPlayer(
position mgl32.Vec3,
scale mgl32.Vec2,
playerName string,
numberOfFrames int,
key0 glfw.Key,
offsetXStartLine float32) *Player {
p := &Player{}
p.canStart = false
p.isDead = false
p.offsetXStartLine = offsetXStartLine
p.runningSprites = make([]*g.Texture, 0, numberOfFrames+1)
for i := 0; i < numberOfFrames; i++ {
p.runningSprites = append(
p.runningSprites,
g.NewTextureFromFile(fmt.Sprintf("bojack/sprites/%s/%s_%02d.png", playerName, playerName, i)))
}
p.playerName = playerName
p.mugshotTexturePath = fmt.Sprintf("bojack/sprites/mugshots/%s.png", playerName)
p.speed = 1.9
p.key0 = key0
p.position = position
p.numberOfFrames = numberOfFrames
p.currentFrameIndex = 0
p.quad = g.NewQuadPrimitive(position, mgl32.Vec2{0, 0})
p.quad.SetTexture(p.runningSprites[p.currentFrameIndex])
p.quad.SetSizeFromTexture()
p.quad.SetScale(scale)
p.quad.SetAnchorToBottomCenter()
p.shadowQuad = g.NewQuadPrimitive(position, mgl32.Vec2{0, 0})
p.shadowQuad.SetTexture(g.NewTextureFromFile("bojack/sprites/shadow.png"))
p.shadowQuad.SetSizeFromTexture()
p.shadowQuad.SetScale(mgl32.Vec2{0.8, 0.6})
p.shadowQuad.SetAnchorToCenter()
p.deathShader = g.NewShaderProgram(g.VertexShaderPrimitive2D, "", FragmentShaderPlayerDead)
return p
}
func (p *Player) Update(scene *Scene) {
time := glfw.GetTime()
if !p.canStart {
if p.position.X() >= playersStopAtX {
p.canStart = true
p.speed = 0
}
} else if p.lastKeyInteraction+1 < time {
p.slowDown()
p.lastKeyInteraction = time
}
p.updateSprite(scene)
}
func (p *Player) updateSprite(scene *Scene) {
if p.position.X() < scene.X()+100 && p.canStart == true && !p.isDead {
p.position = mgl32.Vec3{scene.X() + 100, p.position.Y(), p.position.Z()}
if p.speed < 1 {
p.speed = 1
}
} else if p.isWinner {
p.speed = -1.5
}
p.animationSpeed += float32(math.Min(float64(p.speed), 3))
p.currentFrameIndex = int(p.animationSpeed/10) % p.numberOfFrames
absPos := p.position
absPos = absPos.Add(mgl32.Vec3{p.speed, 0, 0})
p.position = absPos
p.quad.SetPosition(p.position.Sub(mgl32.Vec3{scene.X(), 0, 0}))
p.shadowQuad.SetPosition(p.position.Sub(mgl32.Vec3{scene.X(), 0, -0.05}))
scene.UpdatePlayerPos(p)
if p.isDead {
p.quad.SetShader(p.deathShader)
return
}
p.quad.SetTexture(p.runningSprites[p.currentFrameIndex])
}
func (p *Player) speedUp() {
if !p.canStart || p.isDead {
return
}
p.speed += 1.5
if p.speed > maxSpeed {
p.speed = maxSpeed
}
}
func (p *Player) slowDown() {
if !p.canStart {
return
}
p.speed *= 0.75
}
func (p *Player) Draw(ctx *g.Context) {
p.quad.Draw(ctx)
p.shadowQuad.Draw(ctx)
}