Skip to content

Instantly share code, notes, and snippets.

@peterhellberg
Created February 13, 2018 19:53
Show Gist options
  • Save peterhellberg/14de62e40e8c29fed2e78cbef87b6aee to your computer and use it in GitHub Desktop.
Save peterhellberg/14de62e40e8c29fed2e78cbef87b6aee to your computer and use it in GitHub Desktop.
Random squares effect rendered by Pixel. Inspiration: https://youtu.be/IGOD2eN21qI?t=3m59s
package main
import (
"image/color"
"math/rand"
"time"
"github.com/faiface/pixel"
"github.com/faiface/pixel/imdraw"
"github.com/faiface/pixel/pixelgl"
)
const (
s, n, b = 32, 16, 6
delay = 96 * time.Millisecond
)
func run() {
win, err := pixelgl.NewWindow(pixelgl.WindowConfig{
Bounds: pixel.R(0, 0, float64(s*n), float64(s*n)),
VSync: true,
Undecorated: true,
})
if err != nil {
panic(err)
}
ticker := time.NewTicker(delay)
for !win.Closed() {
win.SetClosed(win.JustPressed(pixelgl.KeyEscape) || win.JustPressed(pixelgl.KeyQ))
select {
case <-ticker.C:
imd := imdraw.New(nil)
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
x, y := float64(i*s), float64(j*s)
imd.Color = gb.Random()
imd.Push(pixel.V(x, y), pixel.V(x+float64(s), y+float64(s)))
imd.Rectangle(0)
imd.Color = gb.Random()
imd.Push(pixel.V(x+b, y+b), pixel.V(x+float64(s)-b, y+float64(s)-b))
imd.Rectangle(0)
}
}
imd.Draw(win)
default:
}
win.Update()
}
}
func main() {
pixelgl.Run(run)
}
type Palette []color.NRGBA
func (p Palette) Random() color.NRGBA {
return p[rand.Intn(len(p))]
}
// Flat UI Colors 2 - British Palette by Jan Losert
// https://flatuicolors.com/palette/gb
var gb = Palette{
{0, 168, 255, 255},
{0, 151, 230, 255},
{156, 136, 255, 255},
{140, 122, 230, 255},
{251, 197, 49, 255},
{225, 177, 44, 255},
{76, 209, 55, 255},
{68, 189, 50, 255},
{72, 126, 176, 255},
{64, 115, 158, 255},
{232, 65, 24, 255},
{194, 54, 22, 255},
{245, 246, 250, 255},
{220, 221, 225, 255},
{127, 143, 166, 255},
{113, 128, 147, 255},
{39, 60, 117, 255},
{25, 42, 86, 255},
{53, 59, 72, 255},
{47, 54, 64, 255},
}
@peterhellberg
Copy link
Author

pixel-random-squares

@peterhellberg
Copy link
Author

pixel-iterating-squares

select {
case <-ticker.C:
	t++

	imd := imdraw.New(nil)

	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			x, y := float64(i*s), float64(j*s)

			imd.Color = gb[(i+1*j+t)%len(gb)]
			imd.Push(pixel.V(x, y), pixel.V(x+float64(s), y+float64(s)))
			imd.Rectangle(0)

			imd.Color = gb.Random()
			imd.Push(pixel.V(x+b, y+b), pixel.V(x+float64(s)-b, y+float64(s)-b))
			imd.Rectangle(6)
		}
	}
	imd.Draw(win)
default:
}

@peterhellberg
Copy link
Author

peterhellberg commented Feb 14, 2018

pixel-noise-squares

screen shot 2018-02-14 at 02 17 52

screen shot 2018-02-14 at 02 35 42

screen shot 2018-02-14 at 02 42 03

screen shot 2018-02-14 at 02 46 23

screen shot 2018-02-14 at 02 57 44

screen shot 2018-02-14 at 03 13 39

package main

import (
	"image/color"
	"math"
	"time"

	"github.com/faiface/pixel"
	"github.com/faiface/pixel/imdraw"
	"github.com/faiface/pixel/pixelgl"
)

const (
	s, n  = 16, 32
	delay = 256 * time.Millisecond
)

func run() {
	win, err := pixelgl.NewWindow(pixelgl.WindowConfig{
		Bounds:      pixel.R(0, 0, float64(s*n), float64(s*n)),
		VSync:       true,
		Undecorated: true,
	})
	if err != nil {
		panic(err)
	}

	ticker := time.NewTicker(delay)

	var t int

	for !win.Closed() {
		win.SetClosed(win.JustPressed(pixelgl.KeyEscape) || win.JustPressed(pixelgl.KeyQ))

		select {
		case <-ticker.C:
			t++
		default:
		}

		imd := imdraw.New(nil)

		for i := 0; i < n; i++ {
			for j := 0; j < n; j++ {
				x, y := float64(i*s), float64(j*s)

				v := Noise2D(float64(i+t), float64(j+t), 0, 14, 280, 1)

				imd.Color = color.NRGBA{0, uint8((1+v)*256) % 255, 0, 255}
				imd.Push(pixel.V(x, y), pixel.V(x+float64(s), y+float64(s)))
				imd.Rectangle(0)

				imd.Color = color.NRGBA{0, uint8((1+v)*64) % 255, 0, 255}
				imd.Push(pixel.V(x, y), pixel.V(x+float64(s), y+float64(s)))
				imd.Rectangle(1)
			}
		}

		imd.Draw(win)
		win.Update()
	}
}

func main() {
	pixelgl.Run(run)
}

func Noise2D(x, y float64, seed int64, alpha, beta float64, octaves int) (value float64) {
	scale := 1.0

	for i := 0; i < octaves; i++ {
		value += interpolatedNoise(x, y, seed) / scale
		scale *= alpha
		x *= beta
		y *= beta
	}

	return
}

func noise(x, y int64, seed int64) float64 {
	n := x + y*57 + seed*7
	fn := (n << 13) ^ n

	return (1.0 - float64((fn*(fn*fn*15731+789221)+1376312589)&0x7fffffff)/float64(0x40000000))
}

func smoothedNoise(x float64, y float64, seed int64) float64 {
	xint := int64(math.Trunc(x))
	yint := int64(math.Trunc(y))

	corners := (noise(xint-1, yint-1, seed) + noise(xint+1, yint-1, seed) + noise(xint-1, yint+1, seed) + noise(xint+1, yint+1, seed)) / 16
	sides := (noise(xint-1, yint, seed) + noise(xint+1, yint, seed) + noise(xint, yint-1, seed) + noise(xint, yint+1, seed)) / 8
	center := noise(xint, yint, seed) / 4

	return corners + sides + center
}

func interpolate(a, b, x float64) float64 {
	ft := x * math.Pi
	f := (1 - math.Cos(ft)) * 0.5

	return a*(1-f) + b*f
}

func interpolatedNoise(x, y float64, seed int64) float64 {
	xint := math.Trunc(x)
	xfrac := x - xint

	yint := math.Trunc(y)
	yfrac := y - yint

	v1 := smoothedNoise(xint, yint, seed)
	v2 := smoothedNoise(xint+1, yint, seed)
	v3 := smoothedNoise(xint, yint+1, seed)
	v4 := smoothedNoise(xint+1, yint+1, seed)

	i1 := interpolate(v1, v2, xfrac)
	i2 := interpolate(v3, v4, xfrac)

	return interpolate(i1, i2, yfrac)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment