diff --git a/community/starfield/README.md b/community/starfield/README.md new file mode 100644 index 0000000..9afba9f --- /dev/null +++ b/community/starfield/README.md @@ -0,0 +1,20 @@ +# starfield + +Classic starfield… with [supposedly accurate stellar colors](http://www.vendian.org/mncharity/dir3/starcolor/) + +Made by [Peter Hellberg](https://github.com/peterhellberg/) as part of his [pixel-experiments](https://github.com/peterhellberg/pixel-experiments) + +## Controls + +Arrow up and down to change speed. Space bar to almost stop. + +## Screenshots + +![starfield animation](https://user-images.githubusercontent.com/565124/32411599-a5fcba72-c1df-11e7-8730-a570470a4eee.gif) + +![starfield screenshot](screenshot.png) + +## Links + + - https://github.com/peterhellberg/pixel-experiments/tree/master/starfield + - https://gist.github.com/peterhellberg/4018e228cced61a0bb26991e49299c96 diff --git a/community/starfield/screenshot.png b/community/starfield/screenshot.png new file mode 100644 index 0000000..513ca6f Binary files /dev/null and b/community/starfield/screenshot.png differ diff --git a/community/starfield/starfield.go b/community/starfield/starfield.go new file mode 100644 index 0000000..658ecdb --- /dev/null +++ b/community/starfield/starfield.go @@ -0,0 +1,165 @@ +package main + +import ( + "image/color" + "math/rand" + "time" + + "github.com/faiface/pixel" + "github.com/faiface/pixel/imdraw" + "github.com/faiface/pixel/pixelgl" +) + +const w, h = float64(1024), float64(512) + +var speed = float64(200) + +var stars [1024]*star + +func init() { + rand.Seed(4) + + for i := 0; i < len(stars); i++ { + stars[i] = newStar() + } +} + +type star struct { + pixel.Vec + Z float64 + P float64 + C color.RGBA +} + +func newStar() *star { + return &star{ + pixel.V(random(-w, w), random(-h, h)), + random(0, w), 0, Colors[rand.Intn(len(Colors))], + } +} + +func (s *star) update(d float64) { + s.P = s.Z + s.Z -= d * speed + + if s.Z < 0 { + s.X = random(-w, w) + s.Y = random(-h, h) + s.Z = w + s.P = s.Z + } +} + +func (s *star) draw(imd *imdraw.IMDraw) { + p := pixel.V( + scale(s.X/s.Z, 0, 1, 0, w), + scale(s.Y/s.Z, 0, 1, 0, h), + ) + + o := pixel.V( + scale(s.X/s.P, 0, 1, 0, w), + scale(s.Y/s.P, 0, 1, 0, h), + ) + + r := scale(s.Z, 0, w, 11, 0) + + imd.Color = s.C + + if p.Sub(o).Len() > 6 { + imd.Push(p, o) + imd.Line(r) + } + + imd.Push(p) + imd.Circle(r, 0) +} + +func run() { + win, err := pixelgl.NewWindow(pixelgl.WindowConfig{ + Bounds: pixel.R(0, 0, w, h), + VSync: true, + Undecorated: true, + }) + if err != nil { + panic(err) + } + + imd := imdraw.New(nil) + + imd.Precision = 7 + + imd.SetMatrix(pixel.IM.Moved(win.Bounds().Center())) + + last := time.Now() + + for !win.Closed() { + win.SetClosed(win.JustPressed(pixelgl.KeyEscape) || win.JustPressed(pixelgl.KeyQ)) + + if win.Pressed(pixelgl.KeyUp) { + speed += 10 + } + + if win.Pressed(pixelgl.KeyDown) { + if speed > 10 { + speed -= 10 + } + } + + if win.Pressed(pixelgl.KeySpace) { + speed = 100 + } + + d := time.Since(last).Seconds() + + last = time.Now() + + imd.Clear() + + for _, s := range stars { + s.update(d) + s.draw(imd) + } + + win.Clear(color.Black) + imd.Draw(win) + win.Update() + } +} + +func main() { + pixelgl.Run(run) +} + +func random(min, max float64) float64 { + return rand.Float64()*(max-min) + min +} + +func scale(unscaledNum, min, max, minAllowed, maxAllowed float64) float64 { + return (maxAllowed-minAllowed)*(unscaledNum-min)/(max-min) + minAllowed +} + +// Colors based on stellar types listed at +// http://www.vendian.org/mncharity/dir3/starcolor/ +var Colors = []color.RGBA{ + color.RGBA{157, 180, 255, 255}, + color.RGBA{162, 185, 255, 255}, + color.RGBA{167, 188, 255, 255}, + color.RGBA{170, 191, 255, 255}, + color.RGBA{175, 195, 255, 255}, + color.RGBA{186, 204, 255, 255}, + color.RGBA{192, 209, 255, 255}, + color.RGBA{202, 216, 255, 255}, + color.RGBA{228, 232, 255, 255}, + color.RGBA{237, 238, 255, 255}, + color.RGBA{251, 248, 255, 255}, + color.RGBA{255, 249, 249, 255}, + color.RGBA{255, 245, 236, 255}, + color.RGBA{255, 244, 232, 255}, + color.RGBA{255, 241, 223, 255}, + color.RGBA{255, 235, 209, 255}, + color.RGBA{255, 215, 174, 255}, + color.RGBA{255, 198, 144, 255}, + color.RGBA{255, 190, 127, 255}, + color.RGBA{255, 187, 123, 255}, + color.RGBA{255, 187, 123, 255}, +}