use gooey::kludgine::app::winit::keyboard::Key; use gooey::kludgine::figures::units::Px; use gooey::kludgine::figures::{Point, Rect, Size}; use gooey::kludgine::render::Renderer; use gooey::kludgine::shapes::Shape; use gooey::kludgine::tilemap::{Object, ObjectLayer, TileKind, TileMapFocus, Tiles, TILE_SIZE}; use gooey::kludgine::Color; use gooey::value::Dynamic; use gooey::widget::MakeWidget; use gooey::widgets::{Label, Stack, TileMap}; use gooey::{Run, Tick}; use kludgine::app::winit::keyboard::NamedKey; use kludgine::figures::FloatConversion; use kludgine::DrawableExt; const PLAYER_SIZE: Px = Px::new(16); #[rustfmt::skip] const TILES: [TileKind; 64] = { const O: TileKind = TileKind::Color(Color::PURPLE); const X: TileKind = TileKind::Color(Color::WHITE); [ X, X, X, X, X, X, X, X, X, O, O, O, O, O, O, X, X, O, X, O, O, X, O, X, X, O, O, O, O, O, O, X, X, O, X, O, O, X, O, X, X, O, O, X, X, O, O, X, X, O, O, O, O, O, O, X, X, X, X, X, X, X, X, X, ] }; fn main() -> gooey::Result { let mut characters = ObjectLayer::new(); let myself = characters.push(Player { color: Color::RED, position: Point::new(TILE_SIZE.into_float(), TILE_SIZE.into_float()), }); let layers = Dynamic::new((Tiles::new(8, 8, TILES), characters)); let debug_message = Dynamic::new(String::new()); let tilemap = TileMap::dynamic(layers.clone()) .focus_on(TileMapFocus::Object { layer: 1, id: myself, }) .tick(Tick::times_per_second(60, move |elapsed, input| { // get mouse cursor position and subsequently get the object under the cursor let mut direction = Point::new(0., 0.); if input.keys.contains(&Key::Named(NamedKey::ArrowDown)) { direction.y += 1.0; } if input.keys.contains(&Key::Named(NamedKey::ArrowUp)) { direction.y -= 1.0; } if input.keys.contains(&Key::Named(NamedKey::ArrowRight)) { direction.x += 1.0; } if input.keys.contains(&Key::Named(NamedKey::ArrowLeft)) { direction.x -= 1.0; } let one_second_movement = direction * TILE_SIZE.into_float(); let cursor_pos = input.mouse.as_ref().map(|mouse| mouse.position); layers.map_mut(|layers| { let pos = &mut layers.1[myself].position; *pos += Point::new( one_second_movement.x * elapsed.as_secs_f32(), one_second_movement.y * elapsed.as_secs_f32(), ); let rect = Rect::new(*pos - Size::squared(8.), Size::squared(16.)); layers.1[myself].color = match cursor_pos.map_or(false, |cursor_pos| rect.cast().contains(cursor_pos)) { true => Color::RED, false => Color::BLUE, }; }); })); Stack::rows(tilemap.expand().and(Label::new(debug_message))).run() } #[derive(Debug)] struct Player { color: Color, position: Point, } impl Object for Player { fn position(&self) -> Point { self.position.cast() } fn render(&self, center: Point, zoom: f32, context: &mut Renderer<'_, '_>) { let zoomed_size = PLAYER_SIZE * zoom; context.draw_shape( Shape::filled_rect( Rect::new(Point::squared(-zoomed_size / 2), Size::squared(zoomed_size)), self.color, ) .translate_by(center), ) } }