Files
2023-09-05 07:52:41 -04:00

159 lines
4.4 KiB
Go

package splashmenu
import (
"cosmos/diego/groovy"
splashmenu "cosmos/diego/groovy/examples/splashmenu/fonts"
"fmt"
"image"
"image/color"
"math"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/inpututil"
"github.com/hajimehoshi/ebiten/v2/text"
)
var (
// theRand = &randy{12345678, 4185243, 776511, 45411}
)
const (
scaleRatio = 12.0
maxMagWidth = 100
)
//type randy struct {
// x, y, z, w uint32
//}
type Noisy struct {
increment int
Dimensions groovy.Area
magnifier groovy.Area
sX int
sY int
events map[groovy.SceneEvent]func()
pixImage *image.RGBA
pixSubImage *image.RGBA
subTarget *ebiten.Image
renderTarget *ebiten.Image
fader *ebiten.Image
//alpha float32
}
func NewNoisy() Noisy {
return Noisy{
increment: 0,
events: make(map[groovy.SceneEvent]func()),
magnifier: groovy.Area{Width: maxMagWidth, Height: maxMagWidth},
}
}
func (n *Noisy) Update() error {
n.increment++
//n.alpha = float32(n.increment) / (60.0 * 5.0) //60fps * 5 seconds = 300frames
//fmt.Printf("%f, ", n.alpha)
n.UpdateNoise()
return nil
}
func (n *Noisy) Draw(screen *ebiten.Image) {
n.subTarget.WritePixels(n.pixSubImage.Pix)
screen.WritePixels(n.pixImage.Pix)
//screen.WritePixels(n.pixSubImage.Pix)
op := &ebiten.DrawImageOptions{}
op.GeoM.Scale(1/scaleRatio, 1/scaleRatio)
n.renderTarget.DrawImage(n.subTarget, op)
op = &ebiten.DrawImageOptions{}
op.GeoM.Scale(scaleRatio, scaleRatio)
op.GeoM.Translate(float64(n.sX)-maxMagWidth/2, float64(n.sY)-maxMagWidth/2)
screen.DrawImage(n.renderTarget, op)
//screen.DrawImage(n.subTarget, nil)
text.Draw(screen, fmt.Sprintf("%04d, ", n.sX), splashmenu.SplashFont.Menu, n.Dimensions.Width/2-58, n.Dimensions.Height/2+18, color.White)
text.Draw(screen, fmt.Sprintf("%04d ", n.sY), splashmenu.SplashFont.Menu, n.Dimensions.Width/2, n.Dimensions.Height/2+18, color.White)
//op = &ebiten.DrawImageOptions{}
//op.ColorScale.Scale(1, 1, 1, n.alpha)
//screen.DrawImage(n.fader, op)
text.Draw(screen, "Q TO EXIT", splashmenu.SplashFont.Title, n.Dimensions.Width/2-77, n.Dimensions.Height/2, color.RGBA{0xff, 0xff, 0xff, uint8(n.increment / (60 * 2) % 0xff)})
}
// register scenevent handler
func (n *Noisy) SetEventHandler(event groovy.SceneEvent, f func()) {
n.events[event] = f
}
// set the current scene dimensions
func (n *Noisy) SetDimensions(a groovy.Area) {
n.Dimensions = a
n.pixImage = image.NewRGBA(image.Rect(0, 0, a.Width, a.Height))
n.fader = ebiten.NewImage(a.Width, a.Height)
n.fader.Fill(color.RGBA{0x00, 0x00, 0x00, 0xff})
n.pixSubImage = image.NewRGBA(image.Rect(0, 0, n.magnifier.Width, n.magnifier.Height))
n.subTarget = ebiten.NewImage(n.magnifier.Width, n.magnifier.Height)
n.renderTarget = ebiten.NewImage(n.magnifier.Width, n.magnifier.Height)
}
func (n *Noisy) UpdateNoise() {
//update cursor position and lock it into the game region bounds
n.sX, n.sY = ebiten.CursorPosition()
n.sX = int(math.Min(float64(n.sX), float64(n.Dimensions.Width-1)))
n.sX = int(math.Max(float64(n.sX), 0))
n.sY = int(math.Min(float64(n.sY), float64(n.Dimensions.Height-1)))
n.sY = int(math.Max(float64(n.sY), 0))
l := n.Dimensions.Width * n.Dimensions.Height
for i := 0; i < l; i++ {
//x := theRand.next()
//n.pixImage.Pix[4*i] = uint8(x >> 24)
//n.pixImage.Pix[4*i+1] = uint8(x >> 16)
//n.pixImage.Pix[4*i+2] = uint8(x >> 8)
//n.pixImage.Pix[4*i+3] = 0xff
ballsMode := int(float32(i) * (float32(n.increment) / 60.0))
n.pixImage.Pix[4*i] = uint8(n.increment)
n.pixImage.Pix[4*i] = uint8(i % 0xff)
n.pixImage.Pix[4*i+1] = uint8(i >> 16 % 0xff)
n.pixImage.Pix[4*i+2] = uint8(i >> 24 % 0xff)
n.pixImage.Pix[4*i+3] = uint8(ballsMode) % 0xFF
}
startIdx := n.sX * n.sY * 4
endIdx := startIdx + n.magnifier.Width*n.magnifier.Height*4
if endIdx >= l*4 {
delta := endIdx - l*4
startIdx = startIdx - delta
endIdx = endIdx - delta
}
copy(n.pixSubImage.Pix[:], n.pixImage.Pix[startIdx:endIdx])
//check for user input to transition scene
if inpututil.IsKeyJustPressed(ebiten.KeyQ) {
if n.events[groovy.COMPLETED] != nil {
n.events[groovy.COMPLETED]()
}
}
}
//func (r *randy) next() uint32 {
// // math/rand is too slow to keep 60 FPS on web browsers.
// // Use Xorshift instead: http://en.wikipedia.org/wiki/Xorshift
// t := r.x ^ (r.x << 11)
// r.x, r.y, r.z = r.y, r.z, r.w
// r.w = (r.w ^ (r.w >> 19)) ^ (t ^ (t >> 8))
// return r.w
//}