-
-
Save urothis/ba9eb3930dcc481c84fd10a6fc8d4e86 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! Simple example for illustrating axonometrically projected tilemaps. | |
//! To keep the math simple instead of strictly isometric, we stick to a projection | |
//! where each tile ends up a diamond shape that is twice as wide as high. | |
use bevy::{ | |
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, | |
math::{uvec2, uvec3, vec2}, | |
prelude::*, | |
window::PresentMode, | |
}; | |
use shader_tilemap::{ | |
bundle::MapBundleManaged, FastTileMapPlugin, Map, MapAttributes, AXONOMETRIC, | |
}; | |
use rand::Rng; | |
#[path = "common/mouse_controls_camera.rs"] | |
mod mouse_controls_camera; | |
use mouse_controls_camera::MouseControlsCameraPlugin; | |
fn main() { | |
App::new() | |
.add_plugins(( | |
DefaultPlugins.set(WindowPlugin { | |
primary_window: Some(Window { | |
title: String::from("Fast Tilemap example"), | |
resolution: (1820., 920.).into(), | |
// disable vsync so we can see the raw FPS speed | |
present_mode: PresentMode::Immediate, | |
..default() | |
}), | |
..default() | |
}), | |
LogDiagnosticsPlugin::default(), | |
FrameTimeDiagnosticsPlugin::default(), | |
MouseControlsCameraPlugin::default(), | |
FastTileMapPlugin::default(), | |
)) | |
.add_systems(Startup, startup) | |
.add_systems(Update, show_coordinate) | |
.run(); | |
} | |
fn startup( | |
mut commands: Commands, | |
asset_server: Res<AssetServer>, | |
mut materials: ResMut<Assets<Map>>, | |
) { | |
commands.spawn(Camera2dBundle::default()); | |
let world = Map::builder( | |
// Map size | |
uvec3(5, 5, 5), | |
// Tile atlas | |
asset_server.load("isometric.png"), | |
// Tile size | |
vec2(256.0, 128.0), | |
) | |
.with_padding(vec2(0., 128.), vec2(0., 64.), vec2(0., 64.)) | |
// "Perspective" overhang draws the overlap of tiles depending on their "depth" that is the | |
// y-axis of their world position (tiles higher up are considered further away). | |
.with_projection(AXONOMETRIC) | |
.with_perspective_overhang() | |
.build_and_set(|_| 1); | |
commands.spawn(MapBundleManaged { | |
material: materials.add(world), | |
// Optional: apply a color gradient. | |
// MapAttributes define attributes per vertex so they can be changed without | |
// triggering re-upload of the map data to the GPU which can conserve performance | |
// for large maps | |
attributes: MapAttributes { | |
mix_color: vec![ | |
Vec4::new(1.0, 0.0, 0.0, 1.0), | |
Vec4::new(0.0, 1.0, 0.0, 1.0), | |
Vec4::new(1.0, 1.0, 1.0, 1.0), // color gets multiplied, so this means no change | |
Vec4::new(0.0, 0.0, 1.0, 1.0), | |
], | |
..default() | |
}, | |
..default() | |
}); | |
} | |
/// Highlight the currently hovered tile red, reset all other tiles | |
fn show_coordinate( | |
mut cursor_moved_events: EventReader<CursorMoved>, | |
mut camera_query: Query<(&GlobalTransform, &Camera), With<OrthographicProjection>>, | |
maps: Query<&Handle<Map>>, | |
mut materials: ResMut<Assets<Map>>, | |
) { | |
for event in cursor_moved_events.read() { | |
for map_handle in maps.iter() { | |
let map = materials.get_mut(map_handle).unwrap(); | |
for (global, camera) in camera_query.iter_mut() { | |
// Translate viewport coordinates to world coordinates | |
if let Some(world) = camera | |
.viewport_to_world(global, event.position) | |
.map(|ray| ray.origin.truncate()) | |
{ | |
// The map can convert between world coordinates and map coordinates | |
let coord = map.world_to_map(world); | |
// Convert back to world coordinate to obtain a logical z index ("depth") of | |
// the tile | |
let world2 = map.map_to_world_3d(coord.extend(0.0)); | |
println!("Map coordinate: {:?} World-Z: {:?}", coord, world2.z); | |
} // if Some(world) | |
} // for (global, camera) | |
} // for map | |
} // for event | |
} // highlight_hovered |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment