Random cards
This commit is contained in:
parent
b931079a71
commit
c9438aa49d
4 changed files with 133 additions and 28 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -95,6 +95,7 @@ name = "ants"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"nannou",
|
||||
"rand_derive2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1580,6 +1581,16 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc_macro2_helper"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79528bef70da112116feb5ecb6b64f1394e5360660d6474a760789ea07885501"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profiling"
|
||||
version = "1.0.15"
|
||||
|
@ -1657,6 +1668,18 @@ dependencies = [
|
|||
"getrandom 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_derive2"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e07d80c051ce2007c5cbb87ae0a6be7c5e5345cb03e06717b64ed5c426cbfb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"proc_macro2_helper",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
|
|
|
@ -27,3 +27,6 @@ codegen-units = 1
|
|||
|
||||
[dependencies.nannou]
|
||||
version = "0.19"
|
||||
|
||||
[dependencies.rand_derive2]
|
||||
version = "0.1"
|
||||
|
|
112
src/main.rs
112
src/main.rs
|
@ -1,12 +1,17 @@
|
|||
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
|
||||
|
||||
mod card;
|
||||
pub(crate) mod rect_helper;
|
||||
|
||||
use std::sync::RwLock;
|
||||
|
||||
use crate::rect_helper::RectHelper;
|
||||
use card::Card;
|
||||
use nannou::{
|
||||
image::{self, ImageFormat},
|
||||
prelude::*,
|
||||
text::Font,
|
||||
winit::window::CursorIcon,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
@ -22,7 +27,8 @@ struct Model {
|
|||
font: Font,
|
||||
texture: wgpu::Texture,
|
||||
ups: f64,
|
||||
ant_count: u8,
|
||||
just_clicked: RwLock<bool>,
|
||||
hand: [Card; HAND_CARD_COUNT],
|
||||
}
|
||||
|
||||
impl Model {
|
||||
|
@ -56,53 +62,101 @@ impl Model {
|
|||
)))
|
||||
.expect("Failed to load font"),
|
||||
ups: 0f64,
|
||||
ant_count: 1,
|
||||
just_clicked: RwLock::new(false),
|
||||
hand: random(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update(_app: &App, model: &mut Model, update: Update) {
|
||||
model.ups = (1f64 / update.since_last.as_secs_f64()).round();
|
||||
let new_ant_count = ((update.since_start.as_secs() + 1) % 12)
|
||||
.try_into()
|
||||
.expect("Failed to convert number to u8");
|
||||
if model.ant_count != new_ant_count {
|
||||
model.ant_count = new_ant_count;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle events related to the window and update the model if necessary
|
||||
fn event(_app: &App, _model: &mut Model, event: WindowEvent) {
|
||||
fn event(_app: &App, model: &mut Model, event: WindowEvent) {
|
||||
match event {
|
||||
MousePressed(MouseButton::Left) => {
|
||||
let mut just_clicked = model.just_clicked.write().expect("click handler poisoned");
|
||||
if !*just_clicked {
|
||||
*just_clicked = true;
|
||||
}
|
||||
}
|
||||
MouseReleased(MouseButton::Left) => {
|
||||
let mut just_clicked = model.just_clicked.write().expect("click handler poisoned");
|
||||
if *just_clicked {
|
||||
*just_clicked = false;
|
||||
}
|
||||
}
|
||||
KeyPressed(Key::R) => {
|
||||
model.hand = random();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
drop(event);
|
||||
}
|
||||
|
||||
const HAND_COUNT: usize = 8;
|
||||
const HAND_CARD_COUNT: usize = 8;
|
||||
const HAND_ASPECT_WIDTH: f32 = 1f32;
|
||||
const HAND_ASPECT_HEIGHT: f32 = 2f32;
|
||||
// Draw the state of your `Model` into the given `Frame` here.
|
||||
fn view(app: &App, model: &Model, frame: Frame) {
|
||||
let window = app.window(model.window).unwrap();
|
||||
window.set_cursor_icon(CursorIcon::Default);
|
||||
frame.clear(BLACK);
|
||||
|
||||
let mut can_click = *model.just_clicked.read().expect("click handler poisoned");
|
||||
|
||||
let mouse = &app.mouse;
|
||||
|
||||
let mouse_position = if mouse.window == Some(model.window) {
|
||||
Some(mouse.position())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let draw = app.draw();
|
||||
|
||||
let rect = window.rect().bottom_part(0.2);
|
||||
draw.rect().wh(rect.wh()).xy(rect.xy()).color(RED).finish();
|
||||
let rect = window.rect().left_part(0.2);
|
||||
draw.rect().wh(rect.wh()).xy(rect.xy()).color(BLUE).finish();
|
||||
let rect = window.rect().right_part(0.2);
|
||||
draw.rect()
|
||||
.wh(rect.wh())
|
||||
.xy(rect.xy())
|
||||
.color(YELLOW)
|
||||
.finish();
|
||||
let rect = window.rect().top_part(0.2);
|
||||
draw.rect()
|
||||
.wh(rect.wh())
|
||||
.xy(rect.xy())
|
||||
.color(GREEN)
|
||||
.finish();
|
||||
let window_rect = window.rect();
|
||||
let hand_bounds = window_rect.bottom_part(0.3);
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let hand_rect = Rect::from_x_y_w_h(
|
||||
hand_bounds.x(),
|
||||
hand_bounds.y(),
|
||||
HAND_CARD_COUNT as f32 * HAND_ASPECT_WIDTH,
|
||||
HAND_ASPECT_HEIGHT,
|
||||
)
|
||||
.fit_into(&hand_bounds)
|
||||
.align_bottom_of(hand_bounds);
|
||||
|
||||
for rect in rect.split_horizontal::<HAND_COUNT>() {
|
||||
draw.texture(&model.texture).xy(rect.xy()).wh(rect.wh());
|
||||
for (idx, rect) in hand_rect
|
||||
.split_horizontal::<HAND_CARD_COUNT>()
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
draw.rect()
|
||||
.xy(rect.xy())
|
||||
.wh(rect.wh())
|
||||
.color(model.hand[idx].color());
|
||||
let image_rect = Rect::from_x_y_w_h(rect.x(), rect.y(), 1401f32, 1061f32)
|
||||
.fit_into(rect)
|
||||
.align_bottom_of(*rect);
|
||||
draw.texture(&model.texture)
|
||||
.xy(image_rect.xy())
|
||||
.wh(image_rect.wh());
|
||||
|
||||
if matches!(mouse_position, Some(mouse_position) if rect.contains(mouse_position)) {
|
||||
window.set_cursor_icon(CursorIcon::Hand);
|
||||
|
||||
if can_click {
|
||||
println!(
|
||||
"Click! {idx} {:?} {:?}",
|
||||
model.hand[idx],
|
||||
model.hand[idx].color()
|
||||
);
|
||||
can_click = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
|
@ -113,6 +167,8 @@ fn view(app: &App, model: &Model, frame: Frame) {
|
|||
.left_justify();
|
||||
}
|
||||
|
||||
*model.just_clicked.write().expect("click handler poisoned") = false;
|
||||
|
||||
draw.to_frame(app, &frame).unwrap();
|
||||
drop(frame);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use nannou::geom::Rect;
|
||||
|
||||
pub trait RectHelper {
|
||||
fn fit_into(&self, bounds: &Rect<f32>) -> Rect<f32>;
|
||||
|
||||
fn bottom_half(&self) -> Rect<f32>;
|
||||
fn bottom_part(&self, part: f32) -> Rect<f32>;
|
||||
|
||||
|
@ -20,6 +22,27 @@ pub trait RectHelper {
|
|||
}
|
||||
|
||||
impl RectHelper for Rect<f32> {
|
||||
fn fit_into(&self, bounds: &Rect<f32>) -> Self {
|
||||
let content_aspect_ratio = self.w() / self.h();
|
||||
let bounds_aspect_ratio = bounds.w() / bounds.h();
|
||||
|
||||
if bounds_aspect_ratio > content_aspect_ratio {
|
||||
Self::from_x_y_w_h(
|
||||
self.x(),
|
||||
self.y(),
|
||||
self.w() * bounds.h() / self.h(),
|
||||
bounds.h(),
|
||||
)
|
||||
} else {
|
||||
Self::from_x_y_w_h(
|
||||
self.x(),
|
||||
self.y(),
|
||||
bounds.w(),
|
||||
self.h() * bounds.w() / self.w(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn bottom_half(&self) -> Self {
|
||||
Self::from_corners(self.mid_left(), self.bottom_right())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue