138 lines
4.4 KiB
Go
138 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"math/rand"
|
|
|
|
"github.com/fogleman/gg"
|
|
)
|
|
|
|
type bubbles map[string](*bubble)
|
|
|
|
func (b bubbles) draw(x int, y int) *gg.Context {
|
|
dc := gg.NewContext(x, y)
|
|
for key, i := range b {
|
|
px, py := 0, 0
|
|
noCollision := false
|
|
for !noCollision {
|
|
fmt.Printf("=== key: %v\n", key)
|
|
// the nature of pinging for points is that you can always end up with something
|
|
// in between points if one is sufficently large and the other is sufficently small.
|
|
px, py = rand.Intn(x-i.SizeX)+i.SizeX/2, rand.Intn(y-i.SizeY)+i.SizeY/2
|
|
switch { // ping 15 points to verify if an different bubble is beneath this one.
|
|
case !isTransparent(dc.Image(), px-i.SizeX/2, py-i.SizeY/2): //top left
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px-i.SizeX/4, py-i.SizeY/4): //top 2/5th
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px, py-i.SizeY/2): // top
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px+i.SizeX/4, py-i.SizeY/2): //top 4/5th
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px+i.SizeX/2, py-i.SizeY/2): //top right
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px-i.SizeX/2, py): //center left
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px-i.SizeX/4, py): //center 2/5th
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px, py): //center
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px+i.SizeX/4, py): //center 4/5th
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px+i.SizeX/2, py): //center right
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px-i.SizeX/2, py+i.SizeY/2): //bottom left
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px-i.SizeX/4, py+i.SizeY/2): //bottom 2/5th
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px, py+i.SizeY/2): //bottom
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px+i.SizeX/4, py+i.SizeY/2): //bottom 4/5th
|
|
noCollision = false
|
|
case !isTransparent(dc.Image(), px+i.SizeX/2, py+i.SizeY/2): //bottom right
|
|
noCollision = false
|
|
default:
|
|
noCollision = true
|
|
}
|
|
}
|
|
dc.DrawImageAnchored(i.DC.Image(), px, py, 0.5, 0.5)
|
|
}
|
|
|
|
return dc
|
|
}
|
|
|
|
type bubble struct {
|
|
DC *gg.Context
|
|
SizeX int
|
|
SizeY int
|
|
CoordX, CoordX2 int
|
|
CoordY, CoordY2 int
|
|
}
|
|
|
|
// newBubble creates a bubble object.
|
|
// content must be greater than 0.
|
|
func newBubble(s string, pt float64) *bubble {
|
|
var b bubble
|
|
inch := 72.272 //1 inch is 72.272 (font) points. or 72 points. im getting conflicting information here.
|
|
px := inch / 96 //1 px is 1/96th of an inch. According to some random website.
|
|
padX, padY := 0.0, 0.0 // left in case I change my mind on absolute padding vs relative padding
|
|
to := 25 // round up to the nearest 25th.
|
|
size := float64(len(s)) * (px * pt) /* this was incorrect but it does make for a nice amount of padding per text.
|
|
It gets wider as you add more text. This is because the program should be cursed. */
|
|
bx, by := size+padX, (pt*2)+padY // box x and box y
|
|
x, y := roundTo(bx, to), roundTo(by, to) //dc x and dc y
|
|
|
|
b.DC = drawBubble(s, pt, x, y, bx, by)
|
|
b.SizeX = int(x)
|
|
b.SizeY = int(y)
|
|
b.CoordX = 0
|
|
b.CoordY = 0
|
|
b.CoordX2 = b.SizeX
|
|
b.CoordY2 = b.SizeY
|
|
|
|
return &b
|
|
}
|
|
|
|
// drawBubble creates a gg.Context for a bubble. the size is moved to the nearest 25th pixel and the bubble rests in the center.
|
|
func drawBubble(s string, pt, x, y, bx, by float64) *gg.Context {
|
|
dc := gg.NewContext(int(x), int(y))
|
|
err := dc.LoadFontFace("./Hack-Regular.ttf", pt)
|
|
if err != nil {
|
|
print("lol")
|
|
}
|
|
|
|
dc.DrawRoundedRectangle((x-bx)/2, (y-by)/2, bx, by, 10)
|
|
dc.SetRGB(1, 1, 1)
|
|
dc.Fill()
|
|
dc.DrawRoundedRectangle((x-bx)/2, (y-by)/2, bx, by, 10)
|
|
dc.SetRGB(256, 256, 256)
|
|
dc.SetLineWidth(3)
|
|
dc.Stroke()
|
|
dc.DrawStringAnchored(s, x/2, y/2, 0.5, 0.5)
|
|
return dc
|
|
}
|
|
|
|
// Move moves a bubble to a new coordinate value.
|
|
func (b *bubble) Move(x, y int) {
|
|
b.CoordX, b.CoordX2 = b.CoordX+x, b.CoordX2+x
|
|
b.CoordY, b.CoordY2 = b.CoordY+y, b.CoordY2+y
|
|
}
|
|
|
|
// roundTo rounds base up to the next multiple of To.
|
|
func roundTo(base float64, To int) float64 {
|
|
i := int(base)
|
|
for i%To != 0 {
|
|
i++
|
|
}
|
|
return float64(i)
|
|
}
|
|
|
|
func isTransparent(im image.Image, x, y int) bool {
|
|
r, g, b, a := im.At(x, y).RGBA()
|
|
fmt.Printf("X: %v, Y: %v\nred: %v, green: %v, blue: %v, alpha: %v\n", x, y, r, g, b, a)
|
|
if r != 0 || g != 0 || b != 0 || a != 0 {
|
|
return false
|
|
}
|
|
return true
|
|
}
|