mirror of
https://github.com/danbulant/cushy
synced 2026-05-19 12:19:02 +00:00
141 lines
4.3 KiB
Rust
141 lines
4.3 KiB
Rust
use std::array;
|
|
use std::cmp::Ordering;
|
|
use std::time::Duration;
|
|
|
|
use cushy::figures::units::Px;
|
|
use cushy::figures::FloatConversion;
|
|
use cushy::figures::{Point, Rect, Size};
|
|
use cushy::kludgine::app::winit::keyboard::Key;
|
|
use cushy::kludgine::app::winit::keyboard::NamedKey;
|
|
use cushy::kludgine::drawing::Renderer;
|
|
use cushy::kludgine::shapes::Shape;
|
|
use cushy::kludgine::sprite::{Sprite, SpriteSource};
|
|
use cushy::kludgine::tilemap::{
|
|
DebugGrid, Object, ObjectLayer, TileArray, TileKind, TileMapFocus, TILE_SIZE,
|
|
};
|
|
use cushy::kludgine::Color;
|
|
use cushy::kludgine::{include_aseprite_sprite, DrawableExt};
|
|
use cushy::value::{Destination, Dynamic};
|
|
use cushy::widgets::TileMap;
|
|
use cushy::{Run, Tick};
|
|
|
|
const PLAYER_SIZE: Px = Px::new(16);
|
|
|
|
fn main() -> cushy::Result {
|
|
let mut characters = ObjectLayer::new();
|
|
|
|
let mut sprite = include_aseprite_sprite!("assets/stickguy").unwrap();
|
|
sprite.set_current_tag(Some("Idle")).unwrap();
|
|
|
|
let myself = characters.push(Player {
|
|
sprite,
|
|
current_frame: None,
|
|
hovered: false,
|
|
position: Point::new(TILE_SIZE.into_float(), TILE_SIZE.into_float()),
|
|
});
|
|
|
|
let sprite = include_aseprite_sprite!("assets/grass").unwrap();
|
|
|
|
let layers = Dynamic::new((
|
|
TileArray::new(
|
|
8,
|
|
array::from_fn::<_, 64, _>(|_| TileKind::Sprite(sprite.clone())),
|
|
),
|
|
characters,
|
|
DebugGrid,
|
|
));
|
|
|
|
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(|mut layers| {
|
|
let player = &mut layers.1[myself];
|
|
|
|
let animation_tag = match direction.x.total_cmp(&0.) {
|
|
Ordering::Less => "WalkLeft",
|
|
Ordering::Equal => "Idle",
|
|
Ordering::Greater => "WalkRight",
|
|
};
|
|
player
|
|
.sprite
|
|
.set_current_tag(Some(animation_tag))
|
|
.expect("valid tag");
|
|
|
|
player.current_frame =
|
|
Some(player.sprite.get_frame(Some(elapsed)).expect("valid tag"));
|
|
|
|
player.position += one_second_movement * elapsed.as_secs_f32();
|
|
|
|
let rect = Rect::new(player.position - Size::squared(8.), Size::squared(16.));
|
|
layers.1[myself].hovered =
|
|
cursor_pos.map_or(false, |cursor_pos| rect.cast().contains(cursor_pos));
|
|
});
|
|
}));
|
|
|
|
tilemap.run()
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct Player {
|
|
sprite: Sprite,
|
|
current_frame: Option<SpriteSource>,
|
|
hovered: bool,
|
|
position: Point<f32>,
|
|
}
|
|
|
|
impl Object for Player {
|
|
fn position(&self) -> Point<Px> {
|
|
self.position.cast()
|
|
}
|
|
|
|
fn render(
|
|
&self,
|
|
center: Point<Px>,
|
|
zoom: f32,
|
|
context: &mut Renderer<'_, '_>,
|
|
) -> Option<Duration> {
|
|
let zoomed_size = PLAYER_SIZE * zoom;
|
|
if self.hovered {
|
|
context.draw_shape(
|
|
Shape::filled_rect(
|
|
Rect::new(Point::squared(-zoomed_size / 2), Size::squared(zoomed_size)),
|
|
Color::new(255, 255, 255, 80),
|
|
)
|
|
.translate_by(center),
|
|
);
|
|
}
|
|
|
|
if let Some(frame) = &self.current_frame {
|
|
context.draw_texture(
|
|
frame,
|
|
Rect::new(center - zoomed_size / 2, Size::squared(zoomed_size)),
|
|
1.,
|
|
);
|
|
}
|
|
|
|
self.sprite.remaining_frame_duration().ok().flatten()
|
|
}
|
|
}
|