-
Notifications
You must be signed in to change notification settings - Fork 0
/
sounds.go
111 lines (96 loc) · 2.67 KB
/
sounds.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
package game
import (
"image/color"
"github.com/kettek/morogue/client/ifs"
"github.com/kettek/morogue/game"
"github.com/tinne26/etxt"
)
// Sounds provides a visual rendering of sounds in the game world.
// It manages their timeout, etc.
type Sounds struct {
sounds []*sound
offsetX, offsetY int
}
// Offset returns the current visual offset of the sounds.
func (sounds *Sounds) Offset() (x, y int) {
return sounds.offsetX, sounds.offsetY
}
// SetOffset sets the current visual offset of the sounds.
func (sounds *Sounds) SetOffset(x, y int) {
sounds.offsetX = x
sounds.offsetY = y
}
// sound is a given sound instance.
type sound struct {
offsetX, offsetY int
x, y int
fromX, fromY int
lifetime int
message string
}
// Add creates and adds a sound to the world.
func (sounds *Sounds) Add(message string, to game.Position, from game.Position) {
// Replace sounds at same position. TODO: Maybe vertical stack sounds in same position?
for _, s := range sounds.sounds {
if s.x == to.X && s.y == to.Y && s.fromX == from.X && s.fromY == from.Y {
s.message = message
s.lifetime = 10 * len(message)
return
}
}
sounds.sounds = append(sounds.sounds, &sound{
x: to.X,
y: to.Y,
fromX: from.X,
fromY: from.Y,
lifetime: 10 * len(message),
message: message,
})
}
// Update manages the lifetime of sounds.
func (sounds *Sounds) Update() {
i := 0
for _, sound := range sounds.sounds {
if sound.lifetime > 0 {
sound.lifetime--
sounds.sounds[i] = sound
i++
}
}
for j := i; j < len(sounds.sounds); j++ {
sounds.sounds[j] = nil
}
sounds.sounds = sounds.sounds[:i]
}
// Draw draws the sounds to the provided context's screen.
func (sounds *Sounds) Draw(ctx ifs.DrawContext) {
cw := int(float64(ctx.Game.CellWidth) * ctx.Game.Zoom)
ch := int(float64(ctx.Game.CellHeight) * ctx.Game.Zoom)
ctx.Txt.Save()
ctx.Txt.SetAlign(etxt.VertCenter | etxt.HorzCenter)
for _, sound := range sounds.sounds {
clr := color.NRGBA{225, 225, 225, 255}
oclr := color.NRGBA{0, 0, 0, 100}
if sound.lifetime < 10 {
clr.A = uint8(float64(sound.lifetime) / 10 * 255)
oclr.A = uint8(float64(sound.lifetime) / 10 * 100)
}
x := sound.x*cw + sounds.offsetX + (cw / 2)
y := sound.y*ch + sounds.offsetY + (ch / 2)
// Adjust the sound in the direction of where it came from, if available.
if sound.fromX > sound.x {
x += cw / 2
} else if sound.fromX < sound.x {
x -= cw / 2
}
if sound.fromY > sound.y {
y += ch / 2
} else if sound.fromY < sound.y {
y -= ch / 2
}
ctx.Txt.SetColor(clr)
ctx.Txt.SetOutlineColor(oclr)
ctx.Txt.DrawWithOutline(ctx.Screen, sound.message, x, y)
}
ctx.Txt.Restore()
}