Code Monkey home page Code Monkey logo

hexx's Introduction

Hexx

workflow License unsafe forbidden Crates.io Docs.rs dependency status

Hexagonal tools lib in rust.

Inspired by this RedBlobGames article and Sander Evers work

This lib allows you to:

  • Manipulate hexagon coordinates
  • Generate hexagonal maps with custom layouts and orientation
  • Generate hexagon meshes (planes or columns)

I made the choice to use Axial Coordinates for performance and utility reasons, but the [Hex] type has conversion utilities with cubic, doubled and offset coordinates.

See the hexagonal coordinate systems

Installation

Minimum supported rust version (MSRV) is 1.72.1

Run cargo add hexx in your project or add the following line to your Cargo.toml:

  • hexx = "0.14"

Cargo features

hexx supports serialization and deserialization of most types using serde, through the serde feature gate. To enable it add the following line to your Cargo.toml:

  • hexx = { version = "0.14", features = ["serde"] }

By default Hex uses rust classic memory layout, if you want to use hexx through the FFI or have Hex be stored without any memory padding, the packed feature will make Hex repr(C). To enable this behaviour add the following line to your Cargo.toml:

  • hexx = { version = "0.14", features = ["packed"] }

hexx supports Bevy Reflection through the bevy_reflect feature. To enable it add the following line to your Cargo.toml:

  • hexx = { version = "0.14", features = ["bevy_reflect"] }

Features

hexx provides the [Hex] coordinates with:

  • Distances
  • Neighbors and directions
  • Lines
  • Ranges
  • Rings
  • Edges
  • Wedges
  • Spirals
  • Rotation
  • Symmetry
  • Vector operations
  • Conversions to other coordinate systems:
    • Cubic coordinates
    • Offset coordinates
    • Doubled coordinates
    • Hexmod coordinates
  • Multiple hex resolution

Basic usage

 use hexx::*;

 // Declare points in hexagonal spaces
 let point_a = hex(10, -5); // Equivalent of `Hex::new(10, -5)`
 let point_b = hex(-8, 15);
 // Find distance between them
 let dist = point_a.unsigned_distance_to(point_b);
 // Compute a line between points
 let line: Vec<Hex> = point_a.line_to(point_b).collect();
 // Compute a ring from `point_a` containing `point_b`
 let ring: Vec<Hex> = point_a.ring(dist).collect();
 // Rotate `point_b` around `point_a` by 2 times 60 degrees clockwise
 let rotated = point_b.rotate_cw_around(point_a, 2);
 // Find the direction between the two points
 let dir_a = point_a.main_direction_to(point_b);
 let dir_b = point_b.main_direction_to(point_a);
 assert!(dir_a == -dir_b);
 // Compute a wedge from `point_a` to `point_b`
 let wedge = point_a.wedge_to(point_b);
 // Get the average value of the wedge
 let avg = wedge.average();

Layout usage

[HexLayout] is the bridge between your world/screen/pixel coordinate system and the hexagonal coordinates system.

 use hexx::*;

 // Define your layout
 let layout = HexLayout {
     hex_size: Vec2::new(1.0, 1.0),
     orientation: HexOrientation::Flat,
     ..Default::default()
 };
 // Get the hex coordinate at the world position `world_pos`.
 let world_pos = Vec2::new(53.52, 189.28);
 let point = layout.world_pos_to_hex(world_pos);
 // Get the world position of `point`
 let point = hex(123, 45);
 let world_pos = layout.hex_to_world_pos(point);

Wrapping

[HexBounds] defines a bounding hexagon around a center coordinate. It can be used for boundary and interesection checks but also for wrapping coordinates. Coordinate wrapping transform a point outside of the bounds to a point inside. This allows for seamless or repeating wraparound maps.

use hexx::*;

let center = hex(23, -45);
let radius = 5;
let bounds = HexBounds::new(center, radius);
let outside_coord = hex(12345, 98765);
assert!(!bounds.is_in_bounds(outside_coord));
let wrapped_coord = bounds.wrap(outside_coord);
assert!(bounds.is_in_bounds(wrapped_coord));

Resolutions and chunks

[Hex] support multi-resolution coordinates. In practice this means that you may convert a coordinate to a different resolution:

  • To a lower resolution, meaning retrieving a parent coordinate
  • to a higher resolution, meaning retrieving the center child coordinate

Resolutions are abstract, the only useful information is the resolution radius.

For example, if you use a big grid, with a radius of a 100, you might want to split that grid evenly in larger hexagons containing a 10 radius of coordinates and maybe do operations locally inside of these chunks.

So instead of using a big range directly:

use hexx::*;

const MAP_RADIUS: u32 = 100;

// Our big grid with hundreds of hexagons
let big_grid = Hex::ZERO.range(MAP_RADIUS);

You may define a smaller grid you will then divide to a higher resolution

use hexx::*;

const CHUNK_RADIUS: u32 = 10;
const MAP_RADIUS: u32 = 20;

let chunks = Hex::ZERO.range(MAP_RADIUS);
for chunk in chunks {
    // We can retrieve the center of that chunk by increasing the resolution
    let center = chunk.to_higher_res(CHUNK_RADIUS);
    // And retrieve the other coordinates in the chunk
    let children = center.range(CHUNK_RADIUS);
    // We can retrieve the chunk coordinates from any coordinate..
    for coord in children {
        // .. by reducing the resolution
        assert_eq!(coord.to_lower_res(CHUNK_RADIUS), chunk);
    }
}

An other usage could be to draw an infinite hex grid, with different resolutions displayed, dynamically changing according to user zoom level.

Usage in Bevy

If you want to generate 3D hexagonal mesh and use it in bevy you may do it this way:

 use bevy::{
     prelude::Mesh,
     render::{mesh::Indices, render_resource::PrimitiveTopology},
 };
 use hexx::MeshInfo;

 pub fn hexagonal_plane(mesh_info: MeshInfo) -> Mesh {
     Mesh::new(PrimitiveTopology::TriangleList)
         .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, mesh_info.vertices)
         .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, mesh_info.normals)
         .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, mesh_info.uvs)
         .with_indices(Some(Indices::U16(mesh_info.indices)))
 }

The [MeshInfo] can be produced from [PlaneMeshBuilder] or [ColumnMeshBuilder]

See the examples for bevy usage

Examples

hexx provides interactive examples showcasing various features:

Hex grid

hex_grid

cargo run --example hex_grid

This example showcases hex ranges, rings, wedges, rotation, and lines

Scroll Map

scroll_map

cargo run --example scroll_map

This example showcases the HexMap struct for scrolling maps

Wrap Map

wrap_map

cargo run --example wrap_map

This example showcases the HexMap struct for looping/wrapping map

A Star pathfinding

a_star

cargo run --example a_star

This example showcases the A star algorithm, with an interactive pathfinding between the origin and your cursor. Clicking on tile toggles their availability

Field of view

fov

cargo run --example field_of_view

This example showcases the FOV algorithm, with an interactive range fov around your cursor. Clicking on tile toggles their visibility.

Field of movement

fov

cargo run --example field_of_movement

This example showcases the field of movement algorithm, interactively displaying the accessible range of movement around the cursor.

3d columns

columns

cargo run --example 3d_columns

This example showcases the 3d hexagon columns procedural generation

Mesh builder

mesh

cargo run --example mesh_builder --features bevy_reflect

This example showcases the hexagon columns procedural generation customization options

Chunks

chunks

cargo run --example chunks

This example showcases the hexagon resolution system, allowing to tile coordinates in evenly sized chunks

Merged Chunks

merged_chunks

cargo run --example merged_columns --features bevy_reflect

This example showcases how to build a simple hex chunk system with each chunk being a single mesh

Sprite Sheet

sprite_sheet

cargo run --example sprite_sheet

This example showcases how to use hexx with 2D sprite sheet.

hexx's People

Contributors

alice-i-cecile avatar asibahi avatar guimilxd avatar haselkern avatar manevillef avatar orph3uslyre avatar specificprotagonist avatar uvizhe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

hexx's Issues

Add 3D example

Trying to piece together how exactly to use this crate with Bevy in 3D is non-trivial. A 3D version of the existing example would help quite a bit.

Missing documentation for from/to vector methods

The conversion methods from/to Vec2 and IVec2 implemented for Hex don't make it clear these methods shouldn't be used for converting from/to world coordinates.

Solution

Give pointers to the HexLayout struct and it's uses in the documentation for these methods

Hex operations can overflow

With very high Hex coordinates, various methods can overflow like:

  • substraction
  • addition
  • multiplication
  • length / distance

Maybe we should add wrapping and saturating variants ?

`hexx v0.10.1` introduces breaking change for pre-rust `v1.71.0`

A change introduced by PR #114 will prevent hexx from compiling with rust versions prior to v1.71.0

This is because the implementation for impl<T> From <(T, T)> for [T; 2] was only stabilized in rust v1.71.0

This is the code block that causes this issue (src/hex/convert.rs):

impl From<(f32, f32)> for Hex {
    #[inline]
    fn from(v: (f32, f32)) -> Self {
        Self::round(v.into())
    }
}

Perhaps update/mention the MSRV for the crate or rollback the change for backwards compatibility?

Implement bevy reflect traits

Is your feature request related to a problem? Please describe.
I wanted to see/edit hexx components using bevy-inspector-egui and saw that they don't implement bevy::Reflect.

Describe the solution you'd like
Add a feature flag to add the trait derives.

Additional context
I made this super tiny commit a while ago for the previous version but never turned it into a PR. You're welcome to take this diff and use it as you see fit, consider it public domain. Maybe I have time to look at it again in a couple weeks :)

Hex division is unstable

There are two major problems with the current Hex division implementations:

  1. Only the axial coordinates are divided.
    Not considering the third axis gives unstable results (e.g. Hex(2, -1, -1) / 2 == Hex(1, 0, -1) while Hex(1, 1, -2) / 2 == Hex(0, 0, 0)).
  2. Hexes shouldnโ€™t be divisible by another hex (or at least I donโ€™t see a way).
    Often when dividing hexes the resulting hex is in a location that doesnโ€™t fully make sense (e.g. Hex(1, -1, 0) / Hex(-1, 1, 0) == Hex(-1, -1, 2) which is further from the center than the initial two).

One possible solution for dividing by integers would be to use floating point numbers and round those, but this might result in similar issues due to rounding errors.

It might have to be considered removing hex division altogether until a solid solution is found.

This is a first issue, feedback is appreciated.

Implement PartialEq for HexDirection

Is your feature request related to a problem? Please describe.
I'd like to create an egui slider that controls the HexOrientation of a hex map.

Describe the solution you'd like
I'd like to HexOrientation to implement PartialEq and possibly other common traits.

Describe alternatives you've considered
I've created an enum that implemented Into<HexOrientation>, but found the bodge to be just ugly.

Additional context
image

Deprecation warnings for `Hex::left` and `Hex::right` are incorrect

Describe the bug

use of deprecated associated function hexx::Direction::left: Use Direction::ccw

To Reproduce

Direction::top().left()

Expected behavior

Direction::ccw (and Direction::cw) do not exist. Instead, these are Direction::clockwise and Direction::counter_clockwise.

Mesh can be simplified

Is your feature request related to a problem? Please describe.
Plane and column mesh generation compute one extra vertex and two extra triangles per hexagon.

Describe the solution you'd like
We could compute 6 vertices instead or 7 and 4 triangles instead of 6 per hexagon.

Add Direction::from_angle

Is your feature request related to a problem? Please describe.

I want to convert from an angle in radians to the nearest Direction.

Describe the solution you'd like

Direction::from_angle(radians: f32, orientation: HexOrientation) -> Direction

Support irregular hexagons

Is your feature request related to a problem? Please describe.
I'm not able to configure for irregular shaped hexagons in HexLayout. Perhaps there is a way, in which case please excuse my ignorance and point me in the right direction :)

Describe the solution you'd like
A way to support irregular shaped hexagons.


EDIT:

I see the hex_size field in HexLayout, but since it's a Vec2, I'm guessing it would only support irregular hexagons that, in the "flat top" orientation, have the flat size exactly 1/2 of the over all width?

i.e. how would one support something like this?
Screenshot 2023-12-09 at 10 13 40โ€ฏAM

Example showing how to use sprite sheet for animated tiles

Is your feature request related to a problem? Please describe.
I'm relatively new to Bevy and I'd love to use hexx for my hex grid tilemap. I'd looking to animate the tiles with sprite sheets but don't have any examples to go off of. It seems like the library is tightly integrated with using meshes from what I can tell from the examples.

Describe the solution you'd like
Pointers or code examples to how one could use hexx along with sprite sheets.

Describe alternatives you've considered
Considered using bevy_ecs_tilemap but not sure if the hex grid management there is right for me.

Center pointy_rectangle to the window and field_of_movement input

Hi,

I have two issues;

The first one is that I am struggling to center a 15 by 11 sized pointy_rectangle.

The only way I manage to do so at the moment is by doing something like shapes::pointy_rectangle([-7, 7, -5, 5]).
It does center it, however, the x, y coordinates I receive are not desirable in that solution. I don't want any negative x, y, but 0-14 and 0-10 instead.

Is there an easy way to solve this? I assume it would involve not using hex_to_world_pos.

Edit;

I 'solved' the first problem by continuing to use [-7, 7, -5, 5]

with

hex.x = (hex.x - 7).abs();
hex.y = (hex.y - 5).abs();

and inverting x, y on the layout so I can present 0,0 in the top left corner of the rectangle and 14, 10 in the bottom right.

Of course, this is purely to visualize the tile's x, y with text, and I continue to use the [-7, 7, -5, 5] coordinates for the position.

Not ideal but it works for my purposes.


The other issue is that the visual placement is for some reason not the same as the coords that handle_input picks up (taken from "field_of_movement" example). It's off by 1 tile, as if there's another outer layer of hexagons. Maybe that's by design from the example and I just don't see where?


Thank you so much for this amazing crate! Let me know if I need to clarify anything.

pointy_rectangle generates confusing results

When I generate rectangle with pointY I see confused results.

To Reproduce
Try to generate pointY rectangle with 2 columns and 3 rows:

for hex in shapes::pointy_rectangle([0, 1, 0, 2]) {
    println!("hex ({}, {})", hex.x, hex.y);
}

Actual result:

hex (0, 0)
hex (1, 0)
hex (0, 1)
hex (1, 1)
hex (-1, 2)
hex (0, 2)

As you can see, 3rd row begins with confused numbers -1, 2

Expected behavior
According to this link I should see following 3rd row:

hex (0, 2)
hex (1, 2)

Screenshots Or Code snippet
Picture from above link:
bug

Is this an issue or am I doing something wrong?

Implement Serialize, Deserialize, Reflect and FromReflect for Hex

Is your feature request related to a problem? Please describe.

I want to implement serde and reflection on my new-typed Hex component.

I can't derive this, because Hex doesn't impl these traits.

Describe the solution you'd like

Implement these traits, guarded by two distinct feature flags that are off by default.

Describe alternatives you've considered

I can probably get around this with a remote derive or a manual implementation?

Direction issues when using Pointy Orientation

Summary
The angle values listed in the Direction documentation for pointy orientation are off by one (South should be pointy angle 0), as the documented angle values for pointy orientation do not match the coordinate change described for each Direction.

On top of this, there's a larger issue of lacking Pointy orientation Direction as directions such as NorthWest have different coordinate changes for each orientation.

Details

The Direction enum uses flat orientation for its naming, but the documentation for each direction states what equivalent direction it is for pointy orientation. For example Direction::TopRight notes that in pointy orientation, it's equivalent of 0 radians, which would be East (assuming mathematical east-counterclockwise orientation).

The problem is, the coordinate change of TopRight in flat orientation is (1, -1), but the change for East in pointy orientation is (1, 0) (which is Bottom in flat orientation).

This becomes a problem when you start using Hex::all_neighbors() using pointy orientation, which actually starts at NorthEast instead of East.

This matters when storing data by Direction index (Direction as usize), as Direction::NorthEast acting as PointyDirection::East has index 0, but the actual transform (1, -1) leads to the cell to the north-east in pointy orientation.

To Reproduce
According to the documents Direction::TopRight is supposed to be equivalent to East when using pointy orientation, so this should pass:

pub type East = Direction::TopRight;
assert_eq!(Hex::new(0, 0) + East, Hex::new(0, 1));

Expected behavior
Honestly, I don't know. Updating the documentation to change the angles to match the
direction coordinate changes in NEIGHBORS_COORDS would be a start. Effectively Direction::South should be pointy angle 0.

However, this doesn't really resolve the overarching problem of having to mentally convert the pointy direction East into flat direction South. It gets even worse when you realize NorthWest in flat (-1, 1) is different from NorthWest in pointy (0, -1).

Perhaps specialization of Direction into PointyDirection and FlatDirection is the approach?

Screenshots Or Code snippet
Pointy orientation coordinate change:
Screen Shot 2023-09-10 at 12 51 12 PM

Flat orientation coordinate change:
Screen Shot 2023-09-10 at 12 51 24 PM

Improve documentation

The lib has a lot of features lacking doc examples and doctests, which should be added for 0.4.0 release

Also the lib.rs file should have Usage section describing most common features, such as the ones shocased in the hex_grid example

Parallel computations

hexx should provide, through a feature gate, parallel operation support for big operations using rayon

Add UV wrapping options for hexagon meshes

Is your feature request related to a problem? Please describe.

Since #80 we have improved plane and column mesh generations, but UV mapping is still very naive.

Describe the solution you'd like

The mesh builder should provide some basic UV options, inspired by 3D software mesh texturing

Hex rotation is invertex

Describe the bug

Hex rotation is inverted:

  • Hex::right rotates counter-clockwise instead of clockwise
  • Hex::left rotates clock wise instead of counter-clockwise

To Reproduce
Steps to reproduce the behavior:

#[test]
fn rotation() {
    let neighbors = Hex::ZERO.all_neighbors();
    for elems in neighbors.windows(2) {
        let [prev, next] = [elems[0], elems[1]];
        assert_eq!(prev.right(), next);
        assert_eq!(next.left(), prev);
    }
}

Expected behavior

The logic in both Hex::left and Hex::right should be inverted

Better mesh generation

Is your feature request related to a problem? Please describe.

The current hexagonal planes and columns API is straightforward but lacks customization and the code is hard to maintain

Describe the solution you'd like

  • Implement a MeshBuilder with various options like rotation , offset, height, subdivisions, etc.
  • Add a mesh builder example to showcase the customization

Additional context

@alice-i-cecile identified some rendering issues with the partial columns and this refactoring should attempt to fix it

Add more iterator tools

  • rotated_by
  • rotated_left_by
  • rotated_right_by
  • rotated_left
  • rotated_left
  • inverted: to apply Neg to all elements
  • bounds: to find the centroid and range containing the entire iterator

Add benchmarks

In addition of the existing unit tests, basic operations should have benchmarks using criterion.

Some features like length computation or iterators (range, spirales, wedges) have alternative algorithms which should be benchmarked as well

Bevy Camera2dBundle Support

I'm trying to integrate this library into a current project that's working with a Camera2d Bundle with Bevy. After some fumbling, I tried changing the Camera3dBundle in the hex_grid example to a Camera2dBundle and discovered that this broke the example. Is this expected behavior? Is Bevy's Camera2dBundle supported?

Describe the solution you'd like
Support the Camera2dBundle for Bevy.

Describe alternatives you've considered
Using Camera3dBundle instead of Camera2dBundle for Bevy.

Return `ExactSizeIterator` from shapes where possible

hexx/src/lib.rs

Line 156 in 9e7dc16

pub fn hexagon(center: Hex, radius: u32) -> impl Iterator<Item = Hex> {

This avoids needing to slowly count the iterator. This was particularly silly because iterators are consumed by doing so.

See this code that I wrote:

    /// Returns the average height of tiles around `tile_pos` within `radius`
    pub(crate) fn average_height(&self, tile_pos: TilePos, radius: u32) -> f32 {
        let hex_iter = hexagon(tile_pos.hex, radius);
        let n = hex_iter.count();
        let hex_iter = hexagon(tile_pos.hex, radius);
        let heights = hex_iter.map(|hex| *self.height_index.get(&TilePos { hex }).unwrap_or(&0.));
        heights.sum::<f32>() / n as f32
    }

Implement Component for Hex

This should be hidden behind a feature flag to avoid pulling in bevy_ecs as a dependency. Storing the position of an effect, unit or tile directly on the entity is a common and clear pattern.

Add mesh scale option

Is your feature request related to a problem? Please describe.
Mesh generation, through plane and column builder are missing a scaling option

Describe the solution you'd like
Both builder should have an optional Vec2/Vec3 scale factor

Column mesh normals aren't normalized

Describe the bug
The normals generated by ColumnMeshBuilder are not unit vectors.

To Reproduce

use hexx::{ColumnMeshBuilder, HexLayout};

fn main() {
    let mesh_info = ColumnMeshBuilder::new(&HexLayout::default(), 1.0).build();

    for normal in mesh_info.normals {
        println!("{}", normal.length());
    }
}

Expected behavior
All normals should be of length 1.

Screenshots Or Code snippet

Actual output
1.7320508
1.7320508
1.7320508
1.7320508
1.7320509
1.7320509
1.7320509
1.7320509
1.7320508
1.7320508
1.7320508
1.7320508
1.7320508
1.7320508
1.7320508
1.7320508
1.7320509
1.7320509
1.7320509
1.7320509
1.7320508
1.7320508
1.7320508
1.7320508
1
1
1
1
1
1
1
1
1
1
1
1
1
1

SIMD support

hexx should provide optional SIMD operations like glam.

SIMD: Single instruction, multiple data (SIMD) instructions can be used to perform the same operation on multiple data elements simultaneously. Rust's packed_simd crate provides support for SIMD instructions and could be used to accelerate certain operations in hexx.

I don't know what would be better, wait for stabilization of std::simd (issue) or use packed_simd.

In terms of API I don't know what is better:

  • A HexA type with simd support
  • Add a simd module with explicit simd methods like that:
use super::Hex;
use std::simd::i32x2;
// src/hex/simd.rs

impl Hex {
    pub fn simd_add(self, rhs: Self) -> Self {
        let x = i32x2::from_array([self.x, rhs.x]);
        let y = i32x2::from_array([self.y, rhs.y]);
        let [x, y] = (x + y).to_array();
        Self::new(x, y)
    }
}

Unclear rotation names

Is your feature request related to a problem? Please describe.
Rotation functions are named left/right and similar. This is confusing โ€“ what do left/right have to do with rotations, which direction is which? In fact, the documentation for these functions does not use these terms, it instead uses clockwise/counterclockwise, which are clear.

Describe the solution you'd like
Deprecate these functions and replace them with clockwise/counterclockwise and similar.
Alternatively this could be abbreviated as cw and ccw (as e.g. rotate_counter_clockwise is rather long).

Additional context
example of confusion

How to use ColorMesh2dBundle with textures

Is your feature request related to a problem? Please describe.
How do I go about using textures for the hexes in the ColorMesh2dBundle?

Describe the solution you'd like
I'd like to use textures instead of plain colors for the hexes.

Describe alternatives you've considered
I've tried the following:

let texture_handle = asset_server.load("Ocean1.png");
let foo = materials.add(ColorMaterial::from(texture_handle));

let entity = commands
                .spawn(ColorMesh2dBundle {
                    mesh: mesh.clone().into(),
                    foo.clone(),
                    transform: Transform::from_xyz(pos.x, pos.y, 0.0).with_scale(Vec3::splat(1.)),
                    ..default()
                })
                .id();

Add `Direction::angle` method

This method should return the standard angle in radians (counterclockwise from +x) associated with the center of each direction.

This is helpful in concert with #13 to support discretized object and camera rotation.

`Direction` not consistent with bevy screen-space coordinates

Bevy 0.11 has changed a coordinate system (inverted Y) for cursor position.

This leads to Direction::Top appears at the bottom.

Here is a patch for hex_grid example to showcase the issue: patch.txt.

diff --git a/examples/hex_grid.rs b/examples/hex_grid.rs
index 5177783..1a57efb 100644
--- a/examples/hex_grid.rs
+++ b/examples/hex_grid.rs
@@ -175,6 +175,14 @@ fn handle_input(
                 .entity(entity)
                 .insert(map.selected_material.clone());
             highlighted_hexes.selected = coord;
+
+            let top = coord.neighbor(hexx::direction::Direction::Top);
+            if let Some(entity) = map.entities.get(&top).copied() {
+                commands
+                    .entity(entity)
+                    .insert(map.half_ring_material.clone());
+                highlighted_hexes.selected = top;
+            }
         }
     }
 }

Hexagon wedges

Implement :

  • wedge iterators
  • corner wedge iterators
  • wedge check
  • corner wedge check

following this article

field_of_movement algorithm is broken

Describe the bug
In this particular video below, you'll see me moving between two white tiles that have the exact same cost to reach another white tile further below. However, one of the white tiles I hover is showing that it's within my field of movement, while the other one does not. The budget in this case was 5.

To Reproduce
https://github.com/ManevilleF/hexx/blob/main/examples/field_of_movement.rs

Use the above example, put budget to a lower amount and look around your map to find that things don't add up

Expected behavior
To be able see a field of movement that corresponds to the set budget

Screenshots Or Code snippet

543a537a26c3ff5a317ad71cffb95137.mp4

Not sure what's wrong with it or what algorithm it is based on. I'll try to come up with a fix but I don't understand how it works yet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.