https://github.com/selimanac/defold-tile-raycast
Ray Casting in tiled worlds using DDA algorithm.
https://github.com/selimanac/defold-tile-raycast
defold defold-engine defold-game-engine defold-library defold-native-extension game-development gamedev
Last synced: 8 months ago
JSON representation
Ray Casting in tiled worlds using DDA algorithm.
- Host: GitHub
- URL: https://github.com/selimanac/defold-tile-raycast
- Owner: selimanac
- License: mit
- Created: 2022-10-19T14:49:39.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2022-10-24T16:02:59.000Z (over 3 years ago)
- Last Synced: 2025-04-20T23:32:29.649Z (about 1 year ago)
- Topics: defold, defold-engine, defold-game-engine, defold-library, defold-native-extension, game-development, gamedev
- Language: Lua
- Homepage:
- Size: 842 KB
- Stars: 16
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
- awesome-defold - Tile Raycast
README

# Tile Raycast
Raycasting in tiled worlds using the DDA algorithm. It is a very effective solution for tile-based worlds such as platformers or top-down games.
This implementation is inspired by:
https://lodev.org/cgtutor/raycasting.html
https://www.youtube.com/watch?v=NbSee-XM7WA
# Installation
You can use Tiled Raycast in your own project by adding this project as a [Defold library dependency](http://www.defold.com/manuals/libraries/). Open your `game.project` file and in the `dependencies` field under `project`, add:
https://github.com/selimanac/defold-tile-raycast/archive/refs/heads/master.zip
# Examples
You can find vision cone and line of sight examples in this project.
Test it here: https://selimanac.github.io/defold-tile-raycast/
For v1: https://github.com/selimanac/defold-tile-raycast-platformer
# Release Notes
### v2
- **BREAKING:** Module name has been changed to `tile_raycast`
- Complete code refactoring
- Performance improvements
- New vision cone and line of sight examples
# Use Cases(AI Generated)
### Ray Casting in Games
2D Top-Down Roguelikes: Games like "The Binding of Isaac" and "Enter the Gungeon" use ray casting for line-of-sight calculations, bullet trajectory.
Wolfenstein 3D and similar pseudo-3D engines: The original Wolfenstein 3D used DDA-based ray casting to create a 3D-like environment from a 2D map.
Minecraft uses a variation for block targeting and lighting calculations.
### Line-of-Sight Systems
Tactical games like "XCOM" and "Into the Breach" use DDA for determining visibility between units.
Stealth games for guard vision cones and detection systems.
### Procedural Generation
Dungeon crawlers like "Rogue Legacy" use it for connecting rooms and ensuring paths are traversable.
Spelunky and similar games for procedural level interconnections.
### Other Applications
Tower defense games for targeting and projectile calculations.
Strategy games for unit visibility and pathing calculations.
Battle royale games for circle/zone damage calculations across grid terrain.
# API
### tile_raycast.setup(`tile_width`, `tile_heigh`,`tilemap_width`,`tilemap_height`,`tiles`,`target_tiles`)
Initial setup for raycasting.
**PARAMETERS**
* `tile_width` (uint16_t) – Width of a single tile.
* `tile_height` (uint16_t) – Height of a single tile.
* `tilemap_width` (uint16_t) – Number of tiles horizontally in the tilemap.
* `tilemap_height` (uint16_t) – Number of tiles vertically in the tilemap.
* `tiles` (table - uint16_t ) – One-dimensional tile table generated from your tilemap or source data.
* `target_tiles` (table - uint16_t) – IDs of impassable tiles from your tilesource (e.g., walls, ground, etc.).
**EXAMPLE**
```lua
local tiles = {
4,2,2,2,0,2,2,2,2,2,
2,2,2,2,0,2,2,2,2,2,
2,2,2,2,0,2,2,2,2,2,
2,2,1,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,
1,2,1,2,2,2,1,1,1,1,
1,1,1,2,2,2,1,1,1,1,
1,1,1,2,1,2,1,3,1,1,
1,1,1,1,2,1,1,1,4,1,
1,1,1,2,2,2,2,1,1,3,
1,1,1,1,1,1,1,1,1,1
}
local tile_width = 32
local tile_height = 32
local target_tiles = {2, 3, 4}
local tilemap_width = 10
local tilemap_height = 11
tile_raycast.setup(tile_width, tile_height, tilemap_width, tilemap_height, tiles, target_tiles)
```
---
### tile_raycast.cast(`ray_from_x`,`ray_from_y`,`ray_to_x`, `ray_to_y`)
Performs a raycast on the tilemap. Returns **only the first** successful hit.
**PARAMETERS**
* `ray_from_x` (float) – Start position of the ray (X).
* `ray_from_y` (float) – Start position of the ray (Y).
* `ray_to_x` (float) – End position of the ray (X).
* `ray_to_y` (float) – End position of the ray (Y).
**RETURN**
* `hit` (boolean) – Whether a tile was hit.
* `tile_x` (uint16_t) – X position of the tile.
* `tile_y` (uint16_t) – Y position of the tile.
* `array_id` (uint16_t) – Index in the tilemap array.
* `tile_id` (uint16_t) – ID of the tile from the tilesource.
* `intersection_x` (float) – X coordinate of the ray intersection point.
* `intersection_y` (float) – Y coordinate of the ray intersection point.
* `side` (enum) – The side of the tile that was hit.
**tile_raycast.LEFT**
**tile_raycast.RIGHT**
**tile_raycast.TOP**
**tile_raycast.BOTTOM**
**EXAMPLE**
```lua
local ray_from = go.get_position(ray_start_url)
local ray_to = go.get_position(ray_end_url)
local hit, tile_x, tile_y, array_id, tile_id, intersection_x, intersection_y, side = tile_raycast.cast(ray_from.x,ray_from.y, ray_to.x,ray_to.y)
if hit then
print("tile_x: " .. tile_x)
print("tile_y: " .. tile_y)
print("array_id " .. array_id)
print("tile_id " .. tile_id)
print("intersection_x " .. intersection_x)
print("intersection_y " .. intersection_y)
print("Side " .. side)
else
print("No result found")
end
```
---
### tile_raycast.set_at(`tile_x`, `tile_y`, `tile_id`)
Sets a tile value in the map array at the specified coordinates.
**PARAMETERS**
* `tile_x` (uint16_t) – Tile X coordinate.
* `tile_y` (uint16_t) – Tile Y coordinate.
* `tile_id` (uint16_t) – Tile ID to set.
---
### tile_raycast.get_at(`tile_x`, `tile_y`)
Returns the tile ID from the map array at the specified coordinates.
**PARAMETERS**
* `tile_x` (uint16_t) – Tile X coordinate.
* `tile_y` (uint16_t) – Tile Y coordinate.
**RETURN**
* `tile_id` (uint16_t) – Tile ID at the given coordinates.
---
### tile_raycast.reset()
Clears all tile and tilemap data.