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 //}