package main import ( "fmt" "math" "math/rand" rl "github.com/gen2brain/raylib-go/raylib" ) type magnet struct { pos rl.Vector2 color rl.Color force float32 radius float32 } type state struct { windowHeight int32 windowWidth int32 magnetsDistance float32 } type ball struct { pos rl.Vector2 originGrid rl.Vector2 radius float32 speed rl.Vector2 } func main() { state := state{ windowWidth: 800, windowHeight: 450, } rl.InitWindow( state.windowWidth, state.windowHeight, "raylib [core] example - basic window", ) defer rl.CloseWindow() // rl.SetTargetFPS(60) const RADIUS = 10 const FORCE = 8 magnets := []magnet{ { color: rl.Red, radius: RADIUS, force: FORCE, }, { color: rl.Green, radius: RADIUS, force: FORCE, }, { color: rl.Blue, radius: RADIUS, force: FORCE, }, } // pocisionar imas no meio da tela xCenter := float32(state.windowWidth / 2) yCenter := float32(state.windowHeight / 2) var magnetsDistance float32 = 80 for i := range magnets { angle := 2.0 * math.Pi * float64(i) / float64(len(magnets)) magnets[i].pos = rl.Vector2{ X: float32(math.Cos(angle)) * magnetsDistance + xCenter, Y: float32(math.Sin(angle)) * magnetsDistance + yCenter, } } verticalGrids := 60 horizontalGrids := 60 grid := make([][]rl.Color, verticalGrids) for i := range grid { grid[i] = make([]rl.Color, horizontalGrids) for j := range grid[i] { grid[i][j] = rl.Black } } // ball := ball{ // pos: rl.Vector2{0, 0}, // originGrid: rl.Vector2{X: 0, Y: 0}, // } // gridSize := rl.Vector2{ X: float32(state.windowWidth / int32(verticalGrids)), Y: float32(state.windowHeight / int32(horizontalGrids)), } var fallingBall *ball fallingBall = nil var fallingBallOrder []rl.Vector2 for y := range grid { for x := range grid[y] { fallingBallOrder = append(fallingBallOrder, rl.Vector2{ X: float32(x), Y: float32(y), }) } } rand.Shuffle(len(fallingBallOrder), func(i, j int) { fallingBallOrder[i], fallingBallOrder[j] = fallingBallOrder[j], fallingBallOrder[i] }) for !rl.WindowShouldClose() { rl.BeginDrawing() rl.ClearBackground(rl.Black) for y := range grid { for x := range grid[y] { pos := rl.Vector2{ X: gridSize.X * float32(x), Y: gridSize.Y * float32(y), } rl.DrawRectangleV(pos, gridSize, grid[y][x]) } } for i := range magnets { rl.DrawCircleV(magnets[i].pos, RADIUS+2, rl.Black) rl.DrawCircleV(magnets[i].pos, RADIUS, magnets[i].color) } if len(fallingBallOrder) == 0 { rl.EndDrawing() continue } if fallingBall == nil { next := fallingBallOrder[0] fallingBallOrder = fallingBallOrder[1:] x := next.X * gridSize.X + gridSize.X/2 y := next.Y * gridSize.Y + gridSize.Y/2 fallingBall = &ball{ pos: rl.Vector2{X: x, Y: y}, originGrid: next, radius: RADIUS/2, } } magnetsPull := rl.Vector2{} var ballMass float32 = 1 var gravConst float32 = 8 for _, magnet := range magnets { direction := rl.Vector2Normalize( rl.Vector2Subtract(fallingBall.pos, magnet.pos), ) distance := rl.Vector2Distance(magnet.pos, fallingBall.pos) force := gravConst * (ballMass * magnet.force) / distance acceleration := rl.Vector2Scale(direction, -force) magnetsPull = rl.Vector2Add(magnetsPull, acceleration) } // fmt.Println(magnetsPull) fallingBall.speed = rl.Vector2Add(fallingBall.speed, magnetsPull) fallingBall.pos = rl.Vector2Add(fallingBall.speed, fallingBall.pos) rl.DrawCircleV( fallingBall.pos, fallingBall.radius+1, rl.Black, ) rl.DrawCircleV( fallingBall.pos, fallingBall.radius, rl.NewColor(100, 100, 100, 255), ) for _, magnet := range magnets { distance := rl.Vector2Distance(fallingBall.pos, magnet.pos) if distance < magnet.radius + fallingBall.radius { x := fallingBall.originGrid.X y := fallingBall.originGrid.Y grid[int(y)][int(x)] = magnet.color fallingBall = nil break } } rl.EndDrawing() } stat := make(map[rl.Color]int) stat[rl.Red] = 0 stat[rl.Green] = 0 stat[rl.Blue] = 0 for y := range grid { for x := range grid[y] { stat[grid[y][x]] += 1 } } fmt.Println(stat) }