use bevy::{prelude::*, utils::HashMap, window::PrimaryWindow}; use glam::uvec2; use hexx::{shapes, *}; const HEX_SIZE: Vec2 = Vec2::splat(20.0); pub fn main() { App::new() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { resolution: (1_000.0, 1_000.0).into(), ..default() }), ..default() })) .add_systems(Startup, (setup_camera, setup_grid)) .add_systems(Update, handle_input) .run(); } /// 3D Orthogrpahic camera setup fn setup_camera(mut commands: Commands) { commands.spawn(Camera2dBundle::default()); } #[derive(Debug, Resource)] struct HexGrid { pub entities: HashMap, pub layout: HexLayout, } fn setup_grid( mut commands: Commands, mut atlas_layouts: ResMut>, asset_server: Res, ) { let texture = asset_server.load("kenney/hexagonTerrain_sheet.png"); let atlas_layout = TextureAtlasLayout::from_grid(uvec2(120, 140), 7, 6, Some(uvec2(2, 2)), None); let atlas_layout = atlas_layouts.add(atlas_layout); let layout = HexLayout { orientation: HexOrientation::Pointy, hex_size: HEX_SIZE, ..default() }; let sprite_size = layout.rect_size(); let entities = shapes::pointy_rectangle([-14, 14, -16, 16]) .enumerate() .map(|(i, coord)| { let pos = layout.hex_to_world_pos(coord); let index = i % (7 * 6); let entity = commands .spawn(( SpriteBundle { sprite: Sprite { custom_size: Some(sprite_size), ..default() }, texture: texture.clone(), transform: Transform::from_xyz(pos.x, pos.y, 0.0), ..default() }, TextureAtlas { index, layout: atlas_layout.clone(), }, )) .id(); (coord, entity) }) .collect(); commands.insert_resource(HexGrid { entities, layout }); } /// Input interaction fn handle_input( buttons: Res>, windows: Query<&Window, With>, cameras: Query<(&Camera, &GlobalTransform)>, grid: Res, mut tiles: Query<&mut TextureAtlas>, ) { let window = windows.single(); let (camera, cam_transform) = cameras.single(); if let Some(pos) = window .cursor_position() .and_then(|p| camera.viewport_to_world_2d(cam_transform, p)) { let hex_pos = grid.layout.world_pos_to_hex(pos); let Some(entity) = grid.entities.get(&hex_pos).copied() else { return; }; if !buttons.just_pressed(MouseButton::Left) { return; } let Ok(mut atlas) = tiles.get_mut(entity) else { return; }; atlas.index = (atlas.index + 1) % (7 * 6); } }