Better tile click detection

This commit is contained in:
bdnugget 2024-10-03 11:53:36 +02:00
parent a9c6298da8
commit 92b0b13add
2 changed files with 55 additions and 21 deletions

76
main.go
View File

@ -108,35 +108,69 @@ func DrawPlayer(player Player, model *rl.Model, mapGrid [][]Tile) {
}
}
// Helper function to test ray-box intersection (slab method)
func RayIntersectsBox(ray rl.Ray, boxMin, boxMax rl.Vector3) bool {
tmin := (boxMin.X - ray.Position.X) / ray.Direction.X
tmax := (boxMax.X - ray.Position.X) / ray.Direction.X
if tmin > tmax {
tmin, tmax = tmax, tmin
}
tymin := (boxMin.Z - ray.Position.Z) / ray.Direction.Z
tymax := (boxMax.Z - ray.Position.Z) / ray.Direction.Z
if tymin > tymax {
tymin, tymax = tymax, tymin
}
if (tmin > tymax) || (tymin > tmax) {
return false
}
if tymin > tmin {
tmin = tymin
}
if tymax < tmax {
tmax = tymax
}
tzmin := (boxMin.Y - ray.Position.Y) / ray.Direction.Y
tzmax := (boxMax.Y - ray.Position.Y) / ray.Direction.Y
if tzmin > tzmax {
tzmin, tzmax = tzmax, tzmin
}
if (tmin > tzmax) || (tzmin > tmax) {
return false
}
return true
}
func GetTileAtMouse(mapGrid [][]Tile, camera *rl.Camera3D) (Tile, bool) {
if !rl.IsMouseButtonPressed(rl.MouseLeftButton) {
return Tile{}, false
}
mouse := rl.GetMousePosition()
// Unproject mouse coordinates to 3D ray
ray := rl.GetMouseRay(mouse, *camera)
// Calculate the distance from the camera to the ray's intersection with the ground plane (Y=0)
if ray.Direction.Y == 0 {
return Tile{}, false
}
dist := -ray.Position.Y / ray.Direction.Y
for x := 0; x < MapWidth; x++ {
for y := 0; y < MapHeight; y++ {
tile := mapGrid[x][y]
// Calculate the intersection point
intersection := rl.NewVector3(
ray.Position.X+ray.Direction.X*dist,
ray.Position.Y+ray.Direction.Y*dist,
ray.Position.Z+ray.Direction.Z*dist,
)
// Define the bounding box for each tile based on its position and height
tilePos := rl.NewVector3(float32(x*TileSize), tile.Height*TileHeight, float32(y*TileSize))
boxMin := rl.Vector3Subtract(tilePos, rl.NewVector3(TileSize/2, TileHeight/2, TileSize/2))
boxMax := rl.Vector3Add(tilePos, rl.NewVector3(TileSize/2, TileHeight/2, TileSize/2))
// Convert the intersection point to tile coordinates
tileX := int(intersection.X / float32(TileSize))
tileY := int(intersection.Z / float32(TileSize))
if tileX >= 0 && tileX < MapWidth && tileY >= 0 && tileY < MapHeight {
fmt.Println("Clicked:", tileX, tileY)
return mapGrid[tileX][tileY], true
// Check if the ray intersects the bounding box
if RayIntersectsBox(ray, boxMin, boxMax) {
fmt.Println("Clicked:", tile.X, tile.Y)
return tile, true
}
}
}
return Tile{}, false
}
@ -228,7 +262,7 @@ func UpdateCamera(camera *rl.Camera3D, player rl.Vector3, deltaTime float32) {
}
func main() {
rl.InitWindow(800, 600, "GoonScape")
rl.InitWindow(1024, 768, "GoonScape")
defer rl.CloseWindow()
rl.InitAudioDevice()
defer rl.CloseAudioDevice()

BIN
output.mp4 Normal file

Binary file not shown.