-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
187 lines (108 loc) · 4.31 KB
/
main.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package main
import "fmt"
import "github.com/banthar/gl"
import "github.com/jteeuwen/glfw"
import "math/rand"
import "os"
import "time"
func main() {
// Set width and height.
WIDTH := 960
HEIGHT := 720
// Open up a Window (that would potentially be used for OpenGL) with glfw
if err := glfw.Init(); err != nil {
// Error.
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
defer glfw.Terminate()
if err := glfw.OpenWindow(WIDTH, HEIGHT, 0, 0, 0, 0, 0, 0, glfw.Windowed); err != nil {
// Error.
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
glfw.SetWindowTitle("LifePack")
// Initialize.
// Initialize (pseudo) random number generator (used in other files).
rand.Seed( time.Now().Unix() )
// We need a way for the user to exit the program.
// This will be accomplished by making it so, when the user presses
// the [ESC] key, that the program exists.
//
// The keyHandler function makes this happen, and will exit this
// program if [ESC] is pressed.
glfw.SetKeyCallback(keyHandler)
// Set up OpenGL in a way that we can do 2D graphics (as opposed to 3D graphics).
initialize(WIDTH, HEIGHT);
// Run.
run(WIDTH, HEIGHT);
}
func keyHandler(key, state int) {
// Exit this program if [ESC] is pressed.
if glfw.KeyEsc == key {
os.Exit(0)
}
}
func initialize(WIDTH, HEIGHT int) {
gl.MatrixMode(gl.PROJECTION);
gl.LoadIdentity();
gl.Ortho(0, float64(WIDTH), float64(HEIGHT), 0, 0, 1);
gl.MatrixMode(gl.MODELVIEW);
gl.Disable(gl.DEPTH_TEST)
}
func run (WIDTH, HEIGHT int) {
// Initialize world.
f64width := float64(WIDTH)
f64height := float64(HEIGHT)
creatures := []*Creature{
NewCreature( fmt.Sprintf("c%d", 1) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 2) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 3) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 4) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 5) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 6) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 7) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 8) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 9) ).Randomize().RandomlyPlace(f64width, f64height),
NewCreature( fmt.Sprintf("c%d", 10) ).Randomize().RandomlyPlace(f64width, f64height),
}
// Make the world come alive.
for i:=0 ; true ; i++ {
// Logic.
// Update state of each creature that results from the passage of time.
for _,creature := range creatures {
creature.Next(f64width, f64height)
}
// Deal with any potential collisions between creatures.
for i:=0; i<len(creatures); i++ {
for ii:=1+i; ii<len(creatures); ii++ {
if collision(creatures[i], creatures[ii]) {
//@TODO: Make each of the creatures involved in the collision sense the collision.
//@TODO: Collision needs to take into account that the 2D spaces loops back on itself.
// Calculate the new velocities for each creature (that resulted from the collsion).
mi := creatures[i].Mass() // The mass of the 1st creature
mii := creatures[ii].Mass() // The mass of the 2nd creature.
Σm := mi + mii // The total mass of the 2 creatures.
Δm := mi - mii // The difference between the mass of the 2 creatures.
newDx1 := (creatures[i].Dx() * Δm + (2 * mii * creatures[ii].Dx())) / Σm;
newDy1 := (creatures[i].Dy() * Δm + (2 * mii * creatures[ii].Dy())) / Σm;
newDx2 := (creatures[ii].Dx() * -Δm + (2 * mi * creatures[i].Dx())) / Σm;
newDy2 := (creatures[ii].Dy() * -Δm + (2 * mi * creatures[i].Dy())) / Σm;
// Update the new velocity's for each creature (that resulted from the collision).
creatures[i].SetDx(newDx1);
creatures[i].SetDy(newDy1);
creatures[ii].SetDx(newDx2);
creatures[ii].SetDy(newDy2);
}
}
}
// Draw.
gl.Clear(gl.COLOR_BUFFER_BIT)
for _,creature := range creatures {
creature.GlDraw()
}
glfw.SwapBuffers()
// Wait for 0.05 seconds.
time.Sleep(50 * time.Millisecond)
} // for
}