Placeholder castle
This commit is contained in:
parent
78e4dedf21
commit
e64742a159
4 changed files with 165 additions and 110 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1599,9 +1599,9 @@ checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
|
BIN
assets/images/castle.png
Normal file
BIN
assets/images/castle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
200
src/main.rs
200
src/main.rs
|
@ -2,7 +2,8 @@
|
|||
#![allow(
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::too_many_lines
|
||||
clippy::too_many_lines,
|
||||
clippy::module_name_repetitions
|
||||
)]
|
||||
|
||||
mod card;
|
||||
|
@ -24,15 +25,48 @@ use player::{Player, Stats};
|
|||
fn main() {
|
||||
nannou::app(Model::init)
|
||||
.update(update)
|
||||
.loop_mode(LoopMode::RefreshSync)
|
||||
.loop_mode(LoopMode::Wait)
|
||||
.run();
|
||||
}
|
||||
|
||||
struct Textures {
|
||||
ant: wgpu::Texture,
|
||||
castle: wgpu::Texture,
|
||||
}
|
||||
|
||||
impl Textures {
|
||||
fn load(app: &App) -> Self {
|
||||
let ant = wgpu::Texture::from_image(
|
||||
app,
|
||||
&image::load_from_memory_with_format(
|
||||
include_bytes!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/assets/images/ant.png"
|
||||
)),
|
||||
ImageFormat::Png,
|
||||
)
|
||||
.expect("Failed to load image"),
|
||||
);
|
||||
let castle = wgpu::Texture::from_image(
|
||||
app,
|
||||
&image::load_from_memory_with_format(
|
||||
include_bytes!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/assets/images/castle.png"
|
||||
)),
|
||||
ImageFormat::Png,
|
||||
)
|
||||
.expect("Failed to load image"),
|
||||
);
|
||||
Self { ant, castle }
|
||||
}
|
||||
}
|
||||
|
||||
struct Model {
|
||||
// Store the window ID so we can refer to this specific window later if needed.
|
||||
window: WindowId,
|
||||
font: Font,
|
||||
texture: wgpu::Texture,
|
||||
textures: Textures,
|
||||
ups: f64,
|
||||
just_clicked: RwLock<bool>,
|
||||
red_hand: RwLock<[Card; HAND_CARD_COUNT]>,
|
||||
|
@ -53,20 +87,9 @@ impl Model {
|
|||
.build()
|
||||
.unwrap();
|
||||
|
||||
let texture = wgpu::Texture::from_image(
|
||||
app,
|
||||
&image::load_from_memory_with_format(
|
||||
include_bytes!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/assets/images/ant.png"
|
||||
)),
|
||||
ImageFormat::Png,
|
||||
)
|
||||
.expect("Failed to load image"),
|
||||
);
|
||||
Self {
|
||||
window,
|
||||
texture,
|
||||
textures: Textures::load(app),
|
||||
font: Font::from_bytes(include_bytes!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/assets/fonts/Monocraft/Monocraft-NF.ttf"
|
||||
|
@ -136,56 +159,88 @@ 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 player_panel(
|
||||
draw: &Draw,
|
||||
bounds: Rect,
|
||||
player_stats: &RwLock<Stats>,
|
||||
player: Player,
|
||||
font: Font,
|
||||
) {
|
||||
let rect = Rect::from_x_y_w_h(bounds.x(), bounds.y(), 1f32, 5f32).fit_into(&bounds);
|
||||
let rect = match player {
|
||||
Player::Red => rect.align_right_of(bounds),
|
||||
Player::Black => rect.align_left_of(bounds),
|
||||
fn player_panel(model: &Model, draw: &Draw, bounds: Rect, player: Player) {
|
||||
let part_bounds = bounds.part_horizontal(match player {
|
||||
Player::Red => 0.8,
|
||||
Player::Black => 0.2,
|
||||
});
|
||||
let [castle_bounds, status_bounds] = match player {
|
||||
Player::Red => part_bounds,
|
||||
Player::Black => [part_bounds[1], part_bounds[0]],
|
||||
};
|
||||
|
||||
let player_stats = player_stats.read().expect("player stats poisoned");
|
||||
let castle_bounds = castle_bounds.top_part(0.7);
|
||||
let castle_rect = Rect::from_x_y_w_h(
|
||||
castle_bounds.x(),
|
||||
castle_bounds.y(),
|
||||
model.textures.castle.width() as f32,
|
||||
model.textures.castle.height() as f32,
|
||||
)
|
||||
.fit_into(castle_bounds);
|
||||
draw.texture(&model.textures.castle)
|
||||
.xy(castle_rect.xy())
|
||||
.wh(castle_rect.wh())
|
||||
.finish();
|
||||
|
||||
let status_rect = status_bounds
|
||||
.align_left_of(status_bounds)
|
||||
.align_middle_y_of(status_bounds);
|
||||
|
||||
let player_stats = *model
|
||||
.stats_of(player)
|
||||
.read()
|
||||
.expect("player stats poisoned");
|
||||
let status = match player {
|
||||
Player::Red => format!(
|
||||
"{:<3} Builders\n{:<5} Bricks\n{:<3} Soldiers\n{:<4} Weapons\n{:<7} Magi\n{:<3} Crystals\n{:<5} Castle\n{:<6} Fence",
|
||||
player_stats.builders,
|
||||
player_stats.bricks,
|
||||
player_stats.soldiers,
|
||||
player_stats.weapons,
|
||||
player_stats.magi,
|
||||
player_stats.crystals,
|
||||
player_stats.castle,
|
||||
player_stats.fence,
|
||||
),
|
||||
Player::Black => format!(
|
||||
"Builders {:>3}\nBricks {:>5}\nSoldiers {:>3}\nWeapons {:>4}\nMagi {:>7}\nCrystals {:>3}\nCastle {:>5}\nFence {:>6}",
|
||||
player_stats.builders,
|
||||
player_stats.bricks,
|
||||
player_stats.soldiers,
|
||||
player_stats.weapons,
|
||||
player_stats.magi,
|
||||
player_stats.crystals,
|
||||
player_stats.castle,
|
||||
player_stats.fence,
|
||||
)
|
||||
};
|
||||
drop(player_stats);
|
||||
Player::Red => format!(
|
||||
"{:<3} Builders\n{:<5} Bricks\n{:<3} Soldiers\n{:<4} Weapons\n{:<7} Magi\n{:<3} Crystals\n{:<5} Castle\n{:<6} Fence",
|
||||
player_stats.builders,
|
||||
player_stats.bricks,
|
||||
player_stats.soldiers,
|
||||
player_stats.weapons,
|
||||
player_stats.magi,
|
||||
player_stats.crystals,
|
||||
player_stats.castle,
|
||||
player_stats.fence,
|
||||
),
|
||||
Player::Black => format!(
|
||||
"Builders {:>3}\nBricks {:>5}\nSoldiers {:>3}\nWeapons {:>4}\nMagi {:>7}\nCrystals {:>3}\nCastle {:>5}\nFence {:>6}",
|
||||
player_stats.builders,
|
||||
player_stats.bricks,
|
||||
player_stats.soldiers,
|
||||
player_stats.weapons,
|
||||
player_stats.magi,
|
||||
player_stats.crystals,
|
||||
player_stats.castle,
|
||||
player_stats.fence,
|
||||
)
|
||||
};
|
||||
let character_size = model
|
||||
.font
|
||||
.glyph('A')
|
||||
.standalone()
|
||||
.get_data()
|
||||
.expect("No glyph found")
|
||||
.extents
|
||||
.unwrap();
|
||||
let character_width = character_size.width();
|
||||
let character_height = character_size.height();
|
||||
|
||||
let character_aspect_ratio = character_width as f32 / character_height as f32;
|
||||
|
||||
let font_size = f32::min(
|
||||
status_bounds.w() / 12f32 / character_aspect_ratio,
|
||||
status_bounds.h() / 8f32,
|
||||
) as u32;
|
||||
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||
let drawing = draw
|
||||
.text(&status)
|
||||
.xy(rect.xy())
|
||||
.wh(rect.wh())
|
||||
.xy(status_rect.xy())
|
||||
.wh(status_rect.wh())
|
||||
.color(WHITE)
|
||||
.font_size((rect.h() * 0.02f32).trunc() as u32)
|
||||
.font_size(font_size)
|
||||
.align_text_middle_y()
|
||||
.font(font)
|
||||
.font(model.font.clone())
|
||||
.color(match player {
|
||||
Player::Red => RED,
|
||||
Player::Black => WHITE,
|
||||
|
@ -213,14 +268,14 @@ fn hand(
|
|||
HAND_CARD_COUNT as f32 * HAND_ASPECT_WIDTH,
|
||||
HAND_ASPECT_HEIGHT,
|
||||
)
|
||||
.fit_into(&bounds)
|
||||
.fit_into(bounds)
|
||||
.align_bottom_of(bounds);
|
||||
|
||||
let current_player = *model
|
||||
.current_player
|
||||
.read()
|
||||
.expect("current player poisoned");
|
||||
for (idx, rect) in hand_rect
|
||||
for (idx, &rect) in hand_rect
|
||||
.split_horizontal::<HAND_CARD_COUNT>()
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
@ -239,11 +294,11 @@ fn hand(
|
|||
let image_rect = Rect::from_x_y_w_h(
|
||||
rect.x(),
|
||||
rect.y(),
|
||||
model.texture.width() as f32,
|
||||
model.texture.height() as f32,
|
||||
model.textures.ant.width() as f32,
|
||||
model.textures.ant.height() as f32,
|
||||
)
|
||||
.fit_into(rect)
|
||||
.align_bottom_of(*rect);
|
||||
.align_bottom_of(rect);
|
||||
|
||||
draw.text(&format!(
|
||||
"{:?}\n{}{}",
|
||||
|
@ -275,7 +330,7 @@ fn hand(
|
|||
.font(model.font.clone())
|
||||
.finish();
|
||||
|
||||
draw.texture(&model.texture)
|
||||
draw.texture(&model.textures.ant)
|
||||
.xy(image_rect.xy())
|
||||
.wh(image_rect.wh())
|
||||
.finish();
|
||||
|
@ -339,22 +394,11 @@ fn view(app: &App, model: &Model, frame: Frame) {
|
|||
|
||||
let window_rect = window.rect();
|
||||
|
||||
let player_one_bounds = window_rect.left_part(0.2);
|
||||
player_panel(
|
||||
&draw,
|
||||
player_one_bounds,
|
||||
model.stats_of(Player::Black),
|
||||
Player::Black,
|
||||
model.font.clone(),
|
||||
);
|
||||
let player_two_bounds = window_rect.right_part(0.2);
|
||||
player_panel(
|
||||
&draw,
|
||||
player_two_bounds,
|
||||
model.stats_of(Player::Red),
|
||||
Player::Red,
|
||||
model.font.clone(),
|
||||
);
|
||||
let [player_one_rect, player_two_rect] = window_rect.split_horizontal::<2>();
|
||||
let player_one_bounds = player_one_rect;
|
||||
player_panel(model, &draw, player_one_bounds, Player::Black);
|
||||
let player_two_bounds = player_two_rect;
|
||||
player_panel(model, &draw, player_two_bounds, Player::Red);
|
||||
|
||||
let hand_bounds = window_rect.bottom_part(0.3);
|
||||
hand(
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
use nannou::geom::Rect;
|
||||
use nannou::{geom::Rect, math::num_traits::Float};
|
||||
|
||||
pub trait RectHelper {
|
||||
fn fit_into(&self, bounds: &Rect<f32>) -> Rect<f32>;
|
||||
pub trait RectHelper<S: Float> {
|
||||
fn fit_into(self, bounds: Rect<S>) -> Rect<S>;
|
||||
|
||||
fn bottom_half(&self) -> Rect<f32>;
|
||||
fn bottom_part(&self, part: f32) -> Rect<f32>;
|
||||
fn bottom_half(self) -> Rect<S>;
|
||||
fn bottom_part(self, part: S) -> Rect<S>;
|
||||
|
||||
fn top_half(&self) -> Rect<f32>;
|
||||
fn top_part(&self, part: f32) -> Rect<f32>;
|
||||
fn top_half(self) -> Rect<S>;
|
||||
fn top_part(self, part: S) -> Rect<S>;
|
||||
|
||||
fn left_half(&self) -> Rect<f32>;
|
||||
fn left_part(&self, part: f32) -> Rect<f32>;
|
||||
fn left_half(self) -> Rect<S>;
|
||||
fn left_part(self, part: S) -> Rect<S>;
|
||||
|
||||
fn right_half(&self) -> Rect<f32>;
|
||||
fn right_part(&self, part: f32) -> Rect<f32>;
|
||||
fn right_half(self) -> Rect<S>;
|
||||
fn right_part(self, part: S) -> Rect<S>;
|
||||
|
||||
fn split_horizontal<const N: usize>(&self) -> [Rect<f32>; N];
|
||||
fn split_vertical<const N: usize>(&self) -> [Rect<f32>; N];
|
||||
fn split_horizontal_vec(&self, num: usize) -> Vec<Rect<f32>>;
|
||||
fn split_vertical_vec(&self, num: usize) -> Vec<Rect<f32>>;
|
||||
fn part_horizontal(self, part: S) -> [Rect<S>; 2];
|
||||
fn part_vertical(self, part: S) -> [Rect<S>; 2];
|
||||
|
||||
fn split_horizontal<const N: usize>(self) -> [Rect<S>; N];
|
||||
fn split_vertical<const N: usize>(self) -> [Rect<S>; N];
|
||||
fn split_horizontal_vec(self, num: usize) -> Vec<Rect<S>>;
|
||||
fn split_vertical_vec(self, num: usize) -> Vec<Rect<S>>;
|
||||
}
|
||||
|
||||
impl RectHelper for Rect<f32> {
|
||||
fn fit_into(&self, bounds: &Rect<f32>) -> Self {
|
||||
impl RectHelper<f32> for Rect<f32> {
|
||||
fn fit_into(self, bounds: Self) -> Self {
|
||||
let content_aspect_ratio = self.w() / self.h();
|
||||
let bounds_aspect_ratio = bounds.w() / bounds.h();
|
||||
|
||||
|
@ -43,11 +46,11 @@ impl RectHelper for Rect<f32> {
|
|||
}
|
||||
}
|
||||
|
||||
fn bottom_half(&self) -> Self {
|
||||
fn bottom_half(self) -> Self {
|
||||
Self::from_corners(self.mid_left(), self.bottom_right())
|
||||
}
|
||||
|
||||
fn bottom_part(&self, part: f32) -> Self {
|
||||
fn bottom_part(self, part: f32) -> Self {
|
||||
debug_assert!((0f32..=1f32).contains(&part));
|
||||
Self::from_corner_points(
|
||||
[self.left(), self.bottom()],
|
||||
|
@ -55,11 +58,11 @@ impl RectHelper for Rect<f32> {
|
|||
)
|
||||
}
|
||||
|
||||
fn top_half(&self) -> Self {
|
||||
fn top_half(self) -> Self {
|
||||
Self::from_corners(self.top_left(), self.mid_right())
|
||||
}
|
||||
|
||||
fn top_part(&self, part: f32) -> Self {
|
||||
fn top_part(self, part: f32) -> Self {
|
||||
debug_assert!((0f32..=1f32).contains(&part));
|
||||
Self::from_corner_points(
|
||||
[self.left(), self.top()],
|
||||
|
@ -67,11 +70,11 @@ impl RectHelper for Rect<f32> {
|
|||
)
|
||||
}
|
||||
|
||||
fn left_half(&self) -> Self {
|
||||
fn left_half(self) -> Self {
|
||||
Self::from_corners(self.top_left(), self.mid_bottom())
|
||||
}
|
||||
|
||||
fn left_part(&self, part: f32) -> Self {
|
||||
fn left_part(self, part: f32) -> Self {
|
||||
debug_assert!((0f32..=1f32).contains(&part));
|
||||
Self::from_corner_points(
|
||||
[self.left(), self.bottom()],
|
||||
|
@ -79,11 +82,11 @@ impl RectHelper for Rect<f32> {
|
|||
)
|
||||
}
|
||||
|
||||
fn right_half(&self) -> Self {
|
||||
Self::from_corners(self.top_left(), self.mid_bottom())
|
||||
fn right_half(self) -> Self {
|
||||
Self::from_corners(self.mid_top(), self.bottom_right())
|
||||
}
|
||||
|
||||
fn right_part(&self, part: f32) -> Self {
|
||||
fn right_part(self, part: f32) -> Self {
|
||||
debug_assert!((0f32..=1f32).contains(&part));
|
||||
Self::from_corner_points(
|
||||
[self.right(), self.bottom()],
|
||||
|
@ -91,8 +94,16 @@ impl RectHelper for Rect<f32> {
|
|||
)
|
||||
}
|
||||
|
||||
fn part_horizontal(self, part: f32) -> [Self; 2] {
|
||||
[self.left_part(part), self.right_part(1f32 - part)]
|
||||
}
|
||||
|
||||
fn part_vertical(self, part: f32) -> [Self; 2] {
|
||||
[self.bottom_part(part), self.top_part(1f32 - part)]
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn split_horizontal<const N: usize>(&self) -> [Self; N] {
|
||||
fn split_horizontal<const N: usize>(self) -> [Self; N] {
|
||||
let mut subdivisions = [unsafe { std::mem::zeroed() }; N];
|
||||
|
||||
let subdivided_width = self.w() / N as f32;
|
||||
|
@ -108,7 +119,7 @@ impl RectHelper for Rect<f32> {
|
|||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn split_horizontal_vec(&self, num: usize) -> Vec<Self> {
|
||||
fn split_horizontal_vec(self, num: usize) -> Vec<Self> {
|
||||
let mut subdivisions = Vec::with_capacity(num);
|
||||
|
||||
let subdivided_width = self.w() / num as f32;
|
||||
|
@ -124,7 +135,7 @@ impl RectHelper for Rect<f32> {
|
|||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn split_vertical<const N: usize>(&self) -> [Self; N] {
|
||||
fn split_vertical<const N: usize>(self) -> [Self; N] {
|
||||
let mut subdivisions = [unsafe { std::mem::zeroed() }; N];
|
||||
|
||||
let subdivided_height = self.h() / N as f32;
|
||||
|
@ -140,7 +151,7 @@ impl RectHelper for Rect<f32> {
|
|||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn split_vertical_vec(&self, num: usize) -> Vec<Self> {
|
||||
fn split_vertical_vec(self, num: usize) -> Vec<Self> {
|
||||
let mut subdivisions = Vec::with_capacity(num);
|
||||
|
||||
let subdivided_height = self.h() / num as f32;
|
||||
|
|
Loading…
Reference in a new issue