Bonjour, j'aimerais comprendre et savoir si l'algorithme de Bresenham était une bonne piste pour calculer les lignes de vues de dofus (2/unity)
Pour l'instant j'ai un quelque chose qui est vraiment bugué et je voulais savoir si je partais quand même sur une bonne piste, savoir aussi si il y a des subtilité.
Exemple de prévisu avec mon implem actuelle
Cliquez pour révéler
Cliquez pour masquer
package fight
import (
"math"
"noradj/internal/dofus"
"noradj/internal/dofus/isometry"
)
func lineOfSight(x1, y1, x2, y2 float64) [][2]int {
dx := math.Abs(x2 - x1)
dy := math.Abs(y2 - y1)
sx, sy := 1.0, 1.0
if x1 >= x2 {
sx = -1
}
if y1 >= y2 {
sy = -1
}
err := dx - dy
var line [][2]int
x, y := x1, y1
gridWidth := len(isometry.Grid)
if gridWidth == 0 {
return line // Return empty line if grid is empty
}
gridHeight := len(isometry.Grid[0])
for {
cellX, cellY := int(math.Floor(x)), int(math.Floor(y))
// Check bounds before accessing the grid
if cellX < 0 || cellX >= gridWidth || cellY < 0 || cellY >= gridHeight {
break // Exit the loop if we're out of bounds
}
cellID := isometry.Grid[cellX][cellY]
if cellID == -1 {
break // Exit the loop if we encounter an invalid cell
}
line = append(line, [2]int{cellX, cellY})
if math.Abs(x-x2) < 0.01 && math.Abs(y-y2) < 0.01 {
break
}
e2 := 2 * err
if e2 > -dy {
err -= dy
x += sx * 0.1
}
if e2 < dx {
err += dx
y += sy * 0.1
}
}
return line
}
func NonVisibleCells(playerPos dofus.CellID, cells []dofus.FightCell) []dofus.CellID {
visibleCells := make(map[dofus.CellID]bool)
playerCoord, ok := isometry.CellIdToCoordinates[int(playerPos)]
if !ok {
return []dofus.CellID{} // Return empty slice if player position is invalid
}
playerX, playerY := float64(playerCoord[0]), float64(playerCoord[1])
for _, cell := range cells {
if cell.Kind == dofus.FightCellTypeObstacle {
continue
}
targetCoord, ok := isometry.CellIdToCoordinates[int(cell.Id)]
if !ok {
continue // Skip this cell if its coordinates are invalid
}
targetX, targetY := float64(targetCoord[0]), float64(targetCoord[1])
line := lineOfSight(playerX, playerY, targetX, targetY)
visible := true
for _, point := range line[1:] { // Start from 1 to exclude the player's position
cellX, cellY := point[0], point[1]
// Check bounds before accessing the grid
if cellX < 0 || cellX >= len(isometry.Grid) || cellY < 0 || cellY >= len(isometry.Grid[0]) {
visible = false
break
}
cellID := isometry.Grid[cellX][cellY]
for _, obstacleCell := range cells {
if obstacleCell.Id == dofus.CellID(cellID) && obstacleCell.Kind == dofus.FightCellTypeObstacle {
// Check if the obstacle fully blocks the line
if math.Abs(float64(cellX)-float64(point[0])) < 0.5 &&
math.Abs(float64(cellY)-float64(point[1])) < 0.5 {
visible = false
break
}
}
}
if !visible {
break
}
}
if visible {
visibleCells[cell.Id] = true
}
}
var nonVisibleCells []dofus.CellID
for _, cell := range cells {
if !visibleCells[cell.Id] && cell.Kind != dofus.FightCellTypeObstacle {
nonVisibleCells = append(nonVisibleCells, cell.Id)
}
}
return nonVisibleCells
}