-
Notifications
You must be signed in to change notification settings - Fork 0
/
game.go
141 lines (131 loc) · 2.85 KB
/
game.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
// Responds to input, draws the scene, handles quit event
package main
import (
"fmt"
"github.com/veandco/go-sdl2/sdl"
"github.com/veandco/go-sdl2/ttf"
"time"
)
// control input modes
const (
MODE_PLACING_START = iota
MODE_PLACING_END = iota
)
type Game struct {
grid *Grid
mode int
apc *AStarPathComputer
fpsTicker *time.Ticker
r *sdl.Renderer
f *ttf.Font
}
func NewGame(r *sdl.Renderer, f *ttf.Font) *Game {
grid := NewGrid(r)
return &Game{
grid: grid,
apc: NewAStarPathComputer(grid),
fpsTicker: time.NewTicker(time.Millisecond * (1000 / FPS)),
r: r,
f: f,
}
}
func (g *Game) gameloop() int {
gameloop:
for {
// draw if fps ticket ticked
select {
case _ = <-g.fpsTicker.C:
sdl.Do(func() {
g.r.Clear()
g.r.Copy(g.grid.st, nil, nil)
g.r.Present()
})
default:
}
// handle input
if !g.HandleEvents() {
break gameloop
}
// sleep
sdl.Delay(1000 / (2 * FPS))
}
return 0
}
// handle quit, key, and mouse events
func (g *Game) HandleEvents() bool {
for e := sdl.PollEvent(); e != nil; e = sdl.PollEvent() {
if g.HandleQuit(e) {
return false
}
switch e.(type) {
case *sdl.KeyboardEvent:
g.HandleKeyEvents(e)
case *sdl.MouseButtonEvent:
g.HandleMouseButtonEvents(e.(*sdl.MouseButtonEvent))
}
}
return true
}
// check for a quit event or key escape/q
func (g *Game) HandleQuit(e sdl.Event) bool {
switch e.(type) {
case *sdl.QuitEvent:
return false
case *sdl.KeyboardEvent:
ke := e.(*sdl.KeyboardEvent)
if ke.Keysym.Sym == sdl.K_ESCAPE ||
ke.Keysym.Sym == sdl.K_q {
return true
}
}
return false
}
// handle keyboard input
func (g *Game) HandleKeyEvents(e sdl.Event) {
switch e.(type) {
case *sdl.KeyboardEvent:
ke := e.(*sdl.KeyboardEvent)
if ke.Type == sdl.KEYDOWN {
if ke.Keysym.Sym == sdl.K_g {
fmt.Println("pressed G")
}
}
}
}
// handle mouse input
func (g *Game) HandleMouseButtonEvents(me *sdl.MouseButtonEvent) {
p := MouseButtonEventToGridCellPosition(me)
if me.Type != sdl.MOUSEBUTTONDOWN {
return
}
// place either start or end
if g.mode == MODE_PLACING_START {
// if placing start, clear any prior grid data
g.grid.Clear()
g.grid.SetStart(p)
} else {
g.grid.SetEnd(p)
}
// mode is toggled between start/end whenever a click event is processed
g.mode = (g.mode + 1) % 2
// if g.grid.start and g.grid.end are defined, compute the path
if g.grid.start != nil && g.grid.end != nil {
g.grid.path = g.grid.path[:0]
path := g.apc.AStarPath(*g.grid.start, *g.grid.end)
if len(path) != 0 {
path := make([]Position, 0)
cur := g.apc.endNode
for cur != nil {
path = append(path, cur.Pos)
cur = cur.From
}
for i, _ := range path {
if i != len(path)-1 {
g.grid.path = append(g.grid.path,
PositionPair{path[i], path[i+1]})
}
}
}
}
g.grid.UpdateTexture()
}