112 lines
3.3 KiB
Go
112 lines
3.3 KiB
Go
package graphics
|
|
|
|
import (
|
|
"git.openprivacy.ca/sarah/microworlds/core"
|
|
"github.com/faiface/pixel"
|
|
"github.com/faiface/pixel/imdraw"
|
|
"github.com/faiface/pixel/pixelgl"
|
|
"image"
|
|
"image/color"
|
|
"math"
|
|
// "strconv"
|
|
)
|
|
|
|
type Graphics struct {
|
|
window *pixelgl.Window
|
|
width, height, pxsize int32
|
|
imd *imdraw.IMDraw
|
|
t int
|
|
colorMap map[string][4]uint8
|
|
}
|
|
|
|
func NewGraphics(width, height, pxsize int32) *Graphics {
|
|
graphics := new(Graphics)
|
|
graphics.width = width
|
|
graphics.height = height
|
|
graphics.pxsize = pxsize
|
|
cfg := pixelgl.WindowConfig{
|
|
Title: "Microworlds",
|
|
Bounds: pixel.R(0, 0, float64(width*pxsize), float64(height*pxsize)),
|
|
VSync: true,
|
|
Resizable: false,
|
|
}
|
|
|
|
win, err := pixelgl.NewWindow(cfg)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
graphics.imd = imdraw.New(nil)
|
|
graphics.window = win
|
|
graphics.colorMap = make(map[string][4]uint8)
|
|
return graphics
|
|
}
|
|
|
|
func (g *Graphics) DrawTileColor(imd *imdraw.IMDraw, x, y int32, rgba color.RGBA) {
|
|
|
|
imd.Color = rgba
|
|
imd.Push(pixel.V(float64(x*g.pxsize), float64(y*g.pxsize)))
|
|
imd.Push(pixel.V(float64((x*g.pxsize)+g.pxsize), float64(y*g.pxsize)))
|
|
imd.Push(pixel.V(float64(x*g.pxsize), float64((y*g.pxsize)+g.pxsize)))
|
|
imd.Push(pixel.V(float64((x*g.pxsize)+g.pxsize), float64((y*g.pxsize)+g.pxsize)))
|
|
imd.Rectangle(0)
|
|
}
|
|
|
|
func (g *Graphics) ColorPheromone(name string, color [4]uint8) {
|
|
g.colorMap[name] = color
|
|
}
|
|
|
|
func (g *Graphics) Render(env *core.Environment, turtles []*core.Turtle) {
|
|
g.imd.Clear()
|
|
g.window.Clear(color.RGBA{0,0,0,0})
|
|
pheromoneImage := image.NewRGBA(image.Rect(0, 0, int(g.width), int(g.height)))
|
|
for x := 0; x < int(g.width); x++ {
|
|
for y := 0; y < int(g.height); y++ {
|
|
if env.HasValue(x, y) {
|
|
pheromoneImage.SetRGBA(x,y, color.RGBA{255, 0, 128, 0xFF})
|
|
} else {
|
|
scaledamountRedTotal := 0
|
|
scaledamountGreenTotal := 0
|
|
scaledamountBlueTotal := 0
|
|
for name, color := range g.colorMap {
|
|
amount := math.Min(float64(env.Sniff(name, x, y)), 255)
|
|
|
|
if amount > 2 {
|
|
amount = 2
|
|
}
|
|
|
|
if amount > 0 {
|
|
scaledamountRed := uint8(float64(color[0]) * (amount / 2))
|
|
scaledamountGreen := uint8(float64(color[1]) * (amount / 2))
|
|
scaledamountBlue := uint8(float64(color[2]) * (amount / 2))
|
|
scaledamountRedTotal += int(scaledamountRed)
|
|
scaledamountGreenTotal += int(scaledamountGreen)
|
|
scaledamountBlueTotal += int(scaledamountBlue)
|
|
}
|
|
}
|
|
pheromoneImage.SetRGBA(x, y, color.RGBA{uint8(scaledamountRedTotal / len(g.colorMap)), uint8(scaledamountGreenTotal / len(g.colorMap)), uint8(scaledamountBlueTotal / len(g.colorMap)), uint8(0xF0)})
|
|
}
|
|
}
|
|
}
|
|
|
|
pd := pixel.PictureDataFromImage(pheromoneImage)
|
|
sprite := pixel.NewSprite(pd, pd.Bounds())
|
|
mat := pixel.IM
|
|
|
|
mat = mat.Moved(g.window.Bounds().Center())
|
|
mat = mat.ScaledXY(pixel.V(float64(g.width*g.pxsize)/2, float64(g.height*g.pxsize)/2), pixel.V(float64(g.pxsize), float64(-g.pxsize)))
|
|
sprite.Draw(g.window, mat)
|
|
|
|
for _, t := range turtles {
|
|
if t.GetAttribute("status") == "dead" {
|
|
continue
|
|
}
|
|
x, y := t.Pos()
|
|
g.DrawTileColor(g.imd, int32(x), int32(y), t.GetColor())
|
|
}
|
|
g.imd.Draw(g.window)
|
|
g.window.Update()
|
|
// surface, _ := g.window.GetSurface()
|
|
// surface.SaveBMP("./images/" + strconv.Itoa(g.t) + ".bmp")
|
|
g.t++
|
|
}
|