feat: add particles

This commit is contained in:
Louis Dalibard 2024-11-03 14:48:53 +01:00
parent 53022419cf
commit 8c852c39ba
5 changed files with 88 additions and 34 deletions

View File

@ -14,39 +14,51 @@ import (
) )
type ConfigS struct { type ConfigS struct {
FPSCounter bool FPSCounter bool
ShowMPRIS bool ShowMPRIS bool
MPRISTextOpacity uint8 MPRISTextOpacity uint8
TargetFPS int32 TargetFPS int32
WindowWidth int32 WindowWidth int32
WindowHeight int32 WindowHeight int32
CaptureDeviceIndex int CaptureDeviceIndex int
SampleRate uint32 SampleRate uint32
RingBufferSize uint32 RingBufferSize uint32
ReadBufferSize uint32 ReadBufferSize uint32
Gain float32 Gain float32
LineOpacity uint8 LineOpacity uint8
LineBrightness float64 LineBrightness float64
LineThickness float32 LineThickness float32
LineInvSqrtOpacityControl bool LineInvSqrtOpacityControl bool
Particles bool
ParticleGenPerFrameEveryXSamples int
ParticleMaxCount int
ParticleMinSize float32
ParticleMaxSize float32
ParticleAcceleration float32
} }
var DefaultConfig = ConfigS{ var DefaultConfig = ConfigS{
FPSCounter: false, FPSCounter: false,
ShowMPRIS: true, ShowMPRIS: true,
MPRISTextOpacity: 255, MPRISTextOpacity: 255,
TargetFPS: 240, TargetFPS: 240,
WindowWidth: 1300, WindowWidth: 1300,
WindowHeight: 1300, WindowHeight: 1300,
CaptureDeviceIndex: 0, CaptureDeviceIndex: 0,
SampleRate: 96000, SampleRate: 96000,
RingBufferSize: 9600, RingBufferSize: 9600,
ReadBufferSize: 9600, ReadBufferSize: 9600,
Gain: 1, Gain: 1,
LineOpacity: 200, LineOpacity: 200,
LineBrightness: 1, LineBrightness: 1,
LineThickness: 3, LineThickness: 3,
LineInvSqrtOpacityControl: false, LineInvSqrtOpacityControl: false,
Particles: true,
ParticleGenPerFrameEveryXSamples: 9600,
ParticleMaxCount: 3000,
ParticleMinSize: 0.2,
ParticleMaxSize: 2.0,
ParticleAcceleration: 0.01,
} }
var Config ConfigS var Config ConfigS

1
go.mod
View File

@ -3,6 +3,7 @@ module xyosc
go 1.23.2 go 1.23.2
require ( require (
github.com/chewxy/math32 v1.11.1
github.com/flopp/go-findfont v0.1.0 github.com/flopp/go-findfont v0.1.0
github.com/fsnotify/fsnotify v1.8.0 github.com/fsnotify/fsnotify v1.8.0
github.com/gen2brain/malgo v0.11.22 github.com/gen2brain/malgo v0.11.22

2
go.sum
View File

@ -1,3 +1,5 @@
github.com/chewxy/math32 v1.11.1 h1:b7PGHlp8KjylDoU8RrcEsRuGZhJuz8haxnKfuMMRqy8=
github.com/chewxy/math32 v1.11.1/go.mod h1:dOB2rcuFrCn6UHrze36WSLVPKtzPMRAQvBvUwkSsLqs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 h1:Gk1XUEttOk0/hb6Tq3WkmutWa0ZLhNn/6fc6XZpM7tM= github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 h1:Gk1XUEttOk0/hb6Tq3WkmutWa0ZLhNn/6fc6XZpM7tM=

36
main.go
View File

@ -5,15 +5,18 @@ import (
"image" "image"
"image/color" "image/color"
"log" "log"
"math/rand/v2"
"xyosc/audio" "xyosc/audio"
"xyosc/config" "xyosc/config"
"xyosc/fastsqrt" "xyosc/fastsqrt"
"xyosc/fonts" "xyosc/fonts"
"xyosc/icons" "xyosc/icons"
"xyosc/media" "xyosc/media"
"xyosc/particles"
"fmt" "fmt"
"github.com/chewxy/math32"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/ebitenutil"
"github.com/hajimehoshi/ebiten/v2/text/v2" "github.com/hajimehoshi/ebiten/v2/text/v2"
@ -35,6 +38,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
var BY float32 var BY float32
binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &AX) binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &AX)
binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &AY) binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &AY)
S := float32(0)
for i := uint32(0); i < config.Config.ReadBufferSize/audio.SampleSizeInBytes/2; i++ { for i := uint32(0); i < config.Config.ReadBufferSize/audio.SampleSizeInBytes/2; i++ {
binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &BX) binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &BX)
binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &BY) binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &BY)
@ -43,17 +47,41 @@ func (g *Game) Draw(screen *ebiten.Image) {
fBX := float32(BX) * config.Config.Gain * float32(scale) fBX := float32(BX) * config.Config.Gain * float32(scale)
fBY := -float32(BY) * config.Config.Gain * float32(scale) fBY := -float32(BY) * config.Config.Gain * float32(scale)
if config.Config.LineInvSqrtOpacityControl { if config.Config.LineInvSqrtOpacityControl {
inv := fastsqrt.FastInvSqrt32((fBX-fAX)*(fBX-fAX) + (fBY-fBY)*(fBY-fBY)) inv := fastsqrt.FastInvSqrt32((fBX-fAX)*(fBX-fAX) + (fBY-fBY)*(fBY-fBY))
colorAdjusted := color.RGBA{config.ThirdColor.R, config.ThirdColor.G, config.ThirdColor.B, uint8(float32(config.Config.LineOpacity) * inv)} colorAdjusted := color.RGBA{config.ThirdColor.R, config.ThirdColor.G, config.ThirdColor.B, uint8(float32(config.Config.LineOpacity) * inv)}
vector.StrokeLine(screen, float32(config.Config.WindowWidth/2)+fAX, float32(config.Config.WindowWidth/2)+fAY, float32(config.Config.WindowWidth/2)+fBX, float32(config.Config.WindowWidth/2)+fBY, config.Config.LineThickness, colorAdjusted, true) vector.StrokeLine(screen, float32(config.Config.WindowWidth/2)+fAX, float32(config.Config.WindowHeight/2)+fAY, float32(config.Config.WindowWidth/2)+fBX, float32(config.Config.WindowHeight/2)+fBY, config.Config.LineThickness, colorAdjusted, true)
} else { } else {
vector.StrokeLine(screen, float32(config.Config.WindowWidth/2)+fAX, float32(config.Config.WindowWidth/2)+fAY, float32(config.Config.WindowWidth/2)+fBX, float32(config.Config.WindowWidth/2)+fBY, config.Config.LineThickness, config.ThirdColorAdj, true) vector.StrokeLine(screen, float32(config.Config.WindowWidth/2)+fAX, float32(config.Config.WindowHeight/2)+fAY, float32(config.Config.WindowWidth/2)+fBX, float32(config.Config.WindowHeight/2)+fBY, config.Config.LineThickness, config.ThirdColorAdj, true)
} }
S += float32(AX)*float32(AX) + float32(AY)*float32(AY)
if config.Config.Particles {
if rand.IntN(config.Config.ParticleGenPerFrameEveryXSamples) == 0 {
if len(particles.Particles) >= config.Config.ParticleMaxCount {
particles.Particles = particles.Particles[1:]
}
particles.Particles = append(particles.Particles, particles.Particle{
X: float32(AX) * config.Config.Gain,
Y: float32(AY) * config.Config.Gain,
VX: 0,
VY: 0,
Size: rand.Float32()*(config.Config.ParticleMaxSize-config.Config.ParticleMinSize) + config.Config.ParticleMinSize,
})
}
}
AX = BX AX = BX
AY = BY AY = BY
} }
for i, particle := range particles.Particles {
vector.DrawFilledCircle(screen, float32(config.Config.WindowWidth/2)+particle.X*float32(scale), float32(config.Config.WindowHeight/2)+particle.Y*float32(scale), particle.Size, config.ThirdColor, true)
norm := math32.Sqrt(particles.Particles[i].X*particles.Particles[i].X + particles.Particles[i].Y*particles.Particles[i].Y)
particles.Particles[i].X += particle.VX / float32(ebiten.ActualTPS())
particles.Particles[i].Y += particle.VY / float32(ebiten.ActualTPS())
particles.Particles[i].VX += config.Config.ParticleAcceleration * particle.X / norm * S / float32(ebiten.ActualTPS())
particles.Particles[i].VY += config.Config.ParticleAcceleration * particle.Y / norm * S / float32(ebiten.ActualTPS())
}
//audio.SampleRingBuffer.Reset() //audio.SampleRingBuffer.Reset()
if config.Config.FPSCounter { if config.Config.FPSCounter {
ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f", ebiten.ActualTPS())) ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f", ebiten.ActualTPS()))

11
particles/particles.go Normal file
View File

@ -0,0 +1,11 @@
package particles
type Particle struct {
X float32
Y float32
VX float32
VY float32
Size float32
}
var Particles = []Particle{}