speed control

This commit is contained in:
2026-05-14 13:08:58 -05:00
parent fc3631c6a0
commit cfe855944b
2 changed files with 91 additions and 32 deletions
+5 -1
View File
@@ -289,7 +289,7 @@ func (a *AStar) CalculatePath(startX int, startY int, endX int, endY int) [][]in
return make([][]int, 0) return make([][]int, 0)
} }
func (a *AStar) CalculatePathLive(startX int, startY int, endX int, endY int, updateChan chan int) [][]int { func (a *AStar) CalculatePathLive(startX int, startY int, endX int, endY int, updateChan chan int, speed *int) [][]int {
timer := time.Now() timer := time.Now()
defer func() { defer func() {
a.timeTaken = time.Since(timer) a.timeTaken = time.Since(timer)
@@ -342,6 +342,10 @@ func (a *AStar) CalculatePathLive(startX int, startY int, endX int, endY int, up
heap.Push(&a.openSet, &Item{index: neighborIndex, priority: priority, gScore: tentativeGScore}) heap.Push(&a.openSet, &Item{index: neighborIndex, priority: priority, gScore: tentativeGScore})
} }
} }
if *speed != 1000 {
time.Sleep(time.Duration(1000-*speed) * time.Millisecond)
}
} }
return make([][]int, 0) return make([][]int, 0)
} }
+69 -14
View File
@@ -318,6 +318,9 @@ func main() {
updateChan := make(chan int, 100000) updateChan := make(chan int, 100000)
autoCompute := false autoCompute := false
speed := 1000
speedInputValue := "100"
editModeSpeed := false
astar := AStar{} astar := AStar{}
astar.Init(width, height) astar.Init(width, height)
@@ -553,6 +556,7 @@ func main() {
editModeWidth = !editModeWidth editModeWidth = !editModeWidth
if editModeWidth { if editModeWidth {
editModeHeight = false editModeHeight = false
editModeSpeed = false
} }
} }
rg.Label(rl.NewRectangle(sidebarX+(95*scale), (10*scale), (10*scale), (20*scale)), "x") rg.Label(rl.NewRectangle(sidebarX+(95*scale), (10*scale), (10*scale), (20*scale)), "x")
@@ -562,6 +566,7 @@ func main() {
editModeHeight = !editModeHeight editModeHeight = !editModeHeight
if editModeHeight { if editModeHeight {
editModeWidth = false editModeWidth = false
editModeSpeed = false
} }
} }
@@ -597,22 +602,14 @@ func main() {
} }
} }
// Tool Selector (text must be "opt1;opt2;..." — raygui splits on ';' and needs 2+ items) // While a dropdown list is open it overlaps controls below; those widgets are handled
rg.Label(rl.NewRectangle(sidebarX+(10*scale), (75*scale), (180*scale), (30*scale)), "Tool:") // earlier in the frame and would otherwise steal the release-click. GuiLock skips input
if rg.DropdownBox(rl.NewRectangle(sidebarX+(10*scale), (100*scale), (180*scale), (30*scale)), toolOptionsText, &activeTool, toolDropdownOpen) { // for other controls; DropdownBox still handles input when its editMode is true.
toolDropdownOpen = !toolDropdownOpen if toolDropdownOpen || heuristicDropdownOpen {
} rg.Lock()
// Heuristic Selector
if !toolDropdownOpen {
rg.Label(rl.NewRectangle(sidebarX+(10*scale), (135*scale), (180*scale), (30*scale)), "Heuristic:")
if rg.DropdownBox(rl.NewRectangle(sidebarX+(10*scale), (160*scale), (180*scale), (30*scale)), heuristicOptionsText, &activeHeuristic, heuristicDropdownOpen) {
heuristicDropdownOpen = !heuristicDropdownOpen
}
} }
// Reset Visualization Button // Reset Visualization Button
if !toolDropdownOpen && !heuristicDropdownOpen {
if rg.Button(rl.NewRectangle(sidebarX+(10*scale), (200*scale), (180*scale), (30*scale)), "Reset Visualization") { if rg.Button(rl.NewRectangle(sidebarX+(10*scale), (200*scale), (180*scale), (30*scale)), "Reset Visualization") {
astar.ResetGrid(false) // keep grid types, otherwise it will delete the board before simulating astar.ResetGrid(false) // keep grid types, otherwise it will delete the board before simulating
lastEvaluatedNode = -1 lastEvaluatedNode = -1
@@ -632,8 +629,50 @@ func main() {
} }
tex.markFull() tex.markFull()
} }
// Speed Slider
speedText := ""
if speed == 1000 {
speedText = "Uncapped"
} else {
speedText = strconv.Itoa(speed/10) + "%"
}
speedLabel := "Speed: " + speedText
rg.Label(rl.NewRectangle(sidebarX+(10*scale), (screenHeight-(145*scale)), (180*scale), (30*scale)), speedLabel)
newSpeed := int(rg.SliderBar(rl.NewRectangle(sidebarX+(10*scale), (screenHeight-(120*scale)), (140*scale), (30*scale)), "", "", float32(speed), 0, 1000))
if editModeSpeed {
if newSpeed != speed {
speed = newSpeed
speedInputValue = strconv.Itoa(speed)
editModeSpeed = false
}
} else {
speed = newSpeed
speedInputValue = strconv.Itoa(speed)
}
if rg.TextBox(rl.NewRectangle(sidebarX+(160*scale), (screenHeight-(120*scale)), (30*scale), (30*scale)), &speedInputValue, 20, editModeSpeed) {
editModeSpeed = !editModeSpeed
if editModeSpeed {
speedInputValue = strconv.Itoa(speed)
editModeWidth = false
editModeHeight = false
} else {
v, err := strconv.Atoi(strings.TrimSpace(speedInputValue))
if err != nil {
speedInputValue = strconv.Itoa(speed)
} else {
if v < 0 {
v = 0
} else if v > 1000 {
v = 1000
}
speed = v
speedInputValue = strconv.Itoa(speed)
}
}
} }
// Calculate Path (Live) Button
if rg.Button(rl.NewRectangle(sidebarX+(10*scale), (screenHeight-(80*scale)), (180*scale), (30*scale)), "Calculate Path (Live)") { if rg.Button(rl.NewRectangle(sidebarX+(10*scale), (screenHeight-(80*scale)), (180*scale), (30*scale)), "Calculate Path (Live)") {
if int(startPos.X) < 0 || int(startPos.X) >= width || int(startPos.Y) < 0 || int(startPos.Y) >= height || int(endPos.X) < 0 || int(endPos.X) >= width || int(endPos.Y) < 0 || int(endPos.Y) >= height { if int(startPos.X) < 0 || int(startPos.X) >= width || int(startPos.Y) < 0 || int(startPos.Y) >= height || int(endPos.X) < 0 || int(endPos.X) >= width || int(endPos.Y) < 0 || int(endPos.Y) >= height {
posError = true posError = true
@@ -657,7 +696,7 @@ func main() {
} }
tex.markFull() tex.markFull()
go func() { go func() {
astar.CalculatePathLive(int(startPos.X), int(startPos.Y), int(endPos.X), int(endPos.Y), updateChan) astar.CalculatePathLive(int(startPos.X), int(startPos.Y), int(endPos.X), int(endPos.Y), updateChan, &speed)
}() }()
} }
} }
@@ -710,6 +749,22 @@ func main() {
// Status Label // Status Label
rg.Label(rl.NewRectangle((10*scale), (screenHeight-(30*scale)), (canvasWidth-(20*scale)), (30*scale)), "Evaluated "+strconv.Itoa(astar.GetEvaluatedCells())+" cells in "+astar.GetTimeTaken().String()) rg.Label(rl.NewRectangle((10*scale), (screenHeight-(30*scale)), (canvasWidth-(20*scale)), (30*scale)), "Evaluated "+strconv.Itoa(astar.GetEvaluatedCells())+" cells in "+astar.GetTimeTaken().String())
rg.Unlock()
// Tool Selector (text must be "opt1;opt2;..." — raygui splits on ';' and needs 2+ items)
rg.Label(rl.NewRectangle(sidebarX+(10*scale), (75*scale), (180*scale), (30*scale)), "Tool:")
if rg.DropdownBox(rl.NewRectangle(sidebarX+(10*scale), (100*scale), (180*scale), (30*scale)), toolOptionsText, &activeTool, toolDropdownOpen) {
toolDropdownOpen = !toolDropdownOpen
}
// Heuristic Selector
if !toolDropdownOpen {
rg.Label(rl.NewRectangle(sidebarX+(10*scale), (135*scale), (180*scale), (30*scale)), "Heuristic:")
if rg.DropdownBox(rl.NewRectangle(sidebarX+(10*scale), (160*scale), (180*scale), (30*scale)), heuristicOptionsText, &activeHeuristic, heuristicDropdownOpen) {
heuristicDropdownOpen = !heuristicDropdownOpen
}
}
rl.EndDrawing() rl.EndDrawing()
} }
} }