Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hexagon generation seems to not working correctly #414

Open
JohnTheCoolingFan opened this issue Apr 5, 2023 · 6 comments · May be fixed by #416
Open

Hexagon generation seems to not working correctly #414

JohnTheCoolingFan opened this issue Apr 5, 2023 · 6 comments · May be fixed by #416

Comments

@JohnTheCoolingFan
Copy link
Contributor

I'm using generate_hexagon to select tiles that are in range for player to see. But this is what I get:
image

It's supposed to be just a hexagon, but every other row below the center is shifted!

Here are code snippets of the project:

fn chart_map(
    player: Query<(&MapPos, &ChartRange), With<PlayerVehicle>>,
    mut tiles: Query<(&mut TileVisibility, &TilePos, &TilemapId)>,
    chunks: Query<&Chunk>,
) {
    let (player_pos, chart_range) = player.single();
    let tiles_in_chart_range: Vec<RowEvenPos> =
        generate_hexagon(player_pos.pos.into(), chart_range.0)
            .into_iter()
            .map(Into::into)
            .collect();
    for (mut tile_vis, tile_pos, tilemap_id) in tiles.iter_mut() {
        let chunk = chunks.get(tilemap_id.0).unwrap();
        let global_tile_pos = global_from_chunk_and_local(chunk.pos, *tile_pos);
        if tiles_in_chart_range.contains(&global_tile_pos) {
            *tile_vis = TileVisibility::Visible
        } else if matches!(*tile_vis, TileVisibility::Visible) {
            *tile_vis = TileVisibility::Charted
        }
    }
}

pub fn global_from_chunk_and_local(chunk: IVec2, local: TilePos) -> RowEvenPos {
    RowEvenPos {
        q: chunk.x * TILEMAP_CHUNK_SIZE.x as i32 + local.x as i32,
        r: chunk.y * TILEMAP_CHUNK_SIZE.y as i32 + local.y as i32,
    }
}

And also the project is on github: https://github.com/JohnTheCoolingFan/sands_of_merkhyl/tree/b69881fde365a79716ed8cb02999443350f8a832

@rparrett
Copy link
Collaborator

rparrett commented Apr 5, 2023

I think this is a bug with:

impl From<AxialPos> for RowEvenPos {

And possibly other coordinate conversions. (Needs further investigation)

If I replace that conversion with

impl From<AxialPos> for RowEvenPos {
    fn from(axial_pos: AxialPos) -> Self {
        let AxialPos { q, r } = axial_pos;

        RowEvenPos {
            q: q + (r + (r & 1)) / 2,
            r,
        }
    }
}

(see https://www.redblobgames.com/grids/hexagons/#conversions-offset)

then your map seems to render correctly.

@JohnTheCoolingFan
Copy link
Contributor Author

Then this makes me think, maybe there's also problems with other AxialPos related conversions? This would probably need further testing, currently thinking on how to set it up.

@rparrett
Copy link
Collaborator

rparrett commented Apr 5, 2023

Yeah, I think they are all suspect. Especially anything using ceiled_division_by_2, which seems obviously wrong to me.

I think maybe we aren't seeing this in the hex_neighbors example because there are aren't any negative q coordinates there?

It would be great if we could rework that example so that we can repro there.

@JohnTheCoolingFan
Copy link
Contributor Author

JohnTheCoolingFan commented Apr 8, 2023

hex_neighbors example doesn't use this at all, it just HexNeighbors struct, which doesn't output AxialPos, but TilePos instead and can't handle tiles that are not on the map. So maybe this case requires additional example?

@rparrett
Copy link
Collaborator

rparrett commented Apr 8, 2023

Just adding some actual rust tests for those conversion functions would probably be better.

I'm personally more inclined to remove/simplify existing hex examples actually.

@JohnTheCoolingFan
Copy link
Contributor Author

IMO some of these examples show some important details of hex tilemap. Besides, I think it's easier to verify the system visually than figuring out valid coordinates, especially with hex. Although it is more robust and cheaper in developer time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants