Simplify ingame.rs, fix adding new entities

Former-commit-id: 3e92c4c8c1c580e2b2d95eecd213ac42cf0dd0bc
This commit is contained in:
Imbris 2019-05-20 02:57:44 -04:00
parent e9683ba639
commit db910855df
3 changed files with 65 additions and 181 deletions

View File

@ -48,10 +48,12 @@ const MANA_COLOR: Color = Color::Rgba(0.42, 0.41, 0.66, 1.0);
widget_ids! {
struct Ids {
// Character Names
ingame_elements[],
name_tags[],
// Health Bars
health_bars[],
health_bar_backs[],
// Test
temp,
bag_space_add,
// Debug
debug_bg,
@ -279,7 +281,9 @@ impl Hud {
let stats = ecs.read_storage::<comp::Stats>();
let entities = ecs.entities();
let player = client.entity();
let mut id_walker = self.ids.ingame_elements.walk();
let mut name_id_walker = self.ids.name_tags.walk();
let mut health_id_walker = self.ids.health_bars.walk();
let mut health_back_id_walker = self.ids.health_bar_backs.walk();
for (pos, name) in
(&entities, &pos, &actor)
.join()
@ -290,8 +294,8 @@ impl Hud {
_ => None,
})
{
let id = id_walker.next(
&mut self.ids.ingame_elements,
let id = name_id_walker.next(
&mut self.ids.name_tags,
&mut ui_widgets.widget_id_generator(),
);
Text::new(&name)
@ -312,35 +316,32 @@ impl Hud {
}
})
{
let id = id_walker.next(
&mut self.ids.ingame_elements,
let back_id = health_back_id_walker.next(
&mut self.ids.health_bar_backs,
&mut ui_widgets.widget_id_generator(),
);
(
// Healh Bar
Rectangle::fill_with([120.0, 8.0], Color::Rgba(0.3, 0.3, 0.3, 0.5))
.x_y(0.0, -25.0),
// Filling
Rectangle::fill_with(
[120.0 * (hp.current as f64 / hp.maximum as f64), 8.0],
HP_COLOR,
)
.x_y(0.0, -25.0),
)
let bar_id = health_id_walker.next(
&mut self.ids.health_bars,
&mut ui_widgets.widget_id_generator(),
);
// Healh Bar
Rectangle::fill_with([120.0, 8.0], Color::Rgba(0.3, 0.3, 0.3, 0.5))
.x_y(0.0, -25.0)
.position_ingame(pos + Vec3::new(0.0, 0.0, 3.0))
.resolution(100.0)
.set(id, ui_widgets);
.set(back_id, ui_widgets);
// Filling
Rectangle::fill_with(
[120.0 * (hp.current as f64 / hp.maximum as f64), 8.0],
HP_COLOR,
)
.x_y(0.0, -25.0)
.position_ingame(pos + Vec3::new(0.0, 0.0, 3.0))
.resolution(100.0)
.set(bar_id, ui_widgets);
}
}
// test
Text::new("Squarefection")
.font_size(20)
.color(TEXT_COLOR)
.font_id(self.fonts.opensans)
.x_y(0.0, 0.0)
.position_ingame([0.0, 25.0, 25.0].into())
.resolution(40.0)
.set(self.ids.temp, ui_widgets);
// Display debug window.
if self.show.debug {

View File

@ -14,7 +14,7 @@ pub use graphic::Graphic;
pub use scale::ScaleMode;
pub use widgets::{
image_slider::ImageSlider,
ingame::{Ingame, Ingameable},
ingame::{Ingame, IngameAnchor, Ingameable},
toggle_button::ToggleButton,
};
@ -255,6 +255,7 @@ impl Ui {
// Check for a change in the scissor.
let new_scissor = {
let (l, b, w, h) = scizzor.l_b_w_h();
let scale_factor = self.scale.scale_factor_physical();
// Calculate minimum x and y coordinates while
// flipping y axis (from +up to +down) and
// moving origin to top-left corner (from middle).
@ -262,12 +263,12 @@ impl Ui {
let min_y = self.ui.win_h / 2.0 - b - h;
Aabr {
min: Vec2 {
x: (min_x * p_scale_factor) as u16,
y: (min_y * p_scale_factor) as u16,
x: (min_x * scale_factor) as u16,
y: (min_y * scale_factor) as u16,
},
max: Vec2 {
x: ((min_x + w) * p_scale_factor) as u16,
y: ((min_y + h) * p_scale_factor) as u16,
x: ((min_x + w) * scale_factor) as u16,
y: ((min_y + h) * scale_factor) as u16,
},
}
.intersection(window_scissor)
@ -530,7 +531,6 @@ impl Ui {
}
_ => {} // TODO: Add this.
//PrimitiveKind::TrianglesMultiColor {..} => {println!("primitive kind multicolor with id {:?}", id);}
// Other unneeded for now.
}
}
// Enter the final command.
@ -539,6 +539,19 @@ impl Ui {
State::Image => DrawCommand::image(start..mesh.vertices().len()),
});
// Draw glyoh cache (use for debugging)
/*self.draw_commands
.push(DrawCommand::Scissor(default_scissor(renderer)));
start = mesh.vertices().len();
mesh.push_quad(create_ui_quad(
Aabr { min: (-1.0, -1.0).into(), max: (1.0, 1.0).into() },
Aabr { min: (0.0, 1.0).into(), max: (1.0, 0.0).into() },
Rgba::new(1.0, 1.0, 1.0, 0.8),
UiMode::Text,
));
self.draw_commands
.push(DrawCommand::plain(start..mesh.vertices().len()));*/
// Create a larger dynamic model if the mesh is larger than the current model size.
if self.model.vbuf.len() < mesh.vertices().len() {
self.model = renderer
@ -589,7 +602,7 @@ impl Ui {
}
}
fn default_scissor(renderer: &mut Renderer) -> Aabr<u16> {
fn default_scissor(renderer: &Renderer) -> Aabr<u16> {
let (screen_w, screen_h) = renderer.get_resolution().map(|e| e as u16).into_tuple();
Aabr {
min: Vec2 { x: 0, y: 0 },

View File

@ -15,27 +15,23 @@ pub struct Ingame<W> {
parameters: IngameParameters,
}
pub trait Ingameable: Sized {
type Event;
pub trait Ingameable: Widget + Sized {
fn prim_count(&self) -> usize;
fn set_ingame(self, ids: Ids, parent_id: Id, ui: &mut UiCell) -> Self::Event;
fn init_ids(mut id_gen: widget::id::Generator) -> Ids;
// Note this is not responsible for the 3d positioning
// Only call this directly if using IngameAnchor
fn set_ingame(self, id: widget::Id, parent_id: Id, ui: &mut UiCell) -> Self::Event {
self
// should pass focus to the window if these are clicked
// (they are not displayed where conrod thinks they are)
.graphics_for(ui.window)
//.parent(parent_id) // is this needed
.set(id, ui)
}
fn position_ingame(self, pos: Vec3<f32>) -> Ingame<Self> {
Ingame::new(pos, self)
}
}
// Note this is not responsible for the positioning
// Only call this directly if using IngameAnchor
pub fn set_ingame<W: Widget>(widget: W, parent_id: Id, id: Id, ui: &mut UiCell) -> W::Event {
widget
// should pass focus to the window if these are clicked
// (they are not displayed where conrod thinks they are)
.graphics_for(ui.window)
//.parent(id) // is this needed
.set(id, ui)
}
pub trait PrimitiveMarker {}
impl PrimitiveMarker for widget::Line {}
impl PrimitiveMarker for widget::Image {}
@ -51,135 +47,9 @@ impl<P> Ingameable for P
where
P: Widget + PrimitiveMarker,
{
type Event = P::Event;
fn prim_count(&self) -> usize {
1
}
fn set_ingame(self, ids: Ids, parent_id: Id, ui: &mut UiCell) -> Self::Event {
let id = ids.one().unwrap();
set_ingame(self, parent_id, id, ui)
}
fn init_ids(mut id_gen: widget::id::Generator) -> Ids {
Ids::One(id_gen.next())
}
}
pub trait IngameWidget: Ingameable + Widget {}
impl<T> IngameWidget for T where T: Ingameable + Widget {}
impl<W, E> Ingameable for (W, E)
where
W: IngameWidget,
E: IngameWidget,
{
type Event = (<W as Widget>::Event, <E as Widget>::Event);
fn prim_count(&self) -> usize {
self.0.prim_count() + self.1.prim_count()
}
fn set_ingame(self, ids: Ids, parent_id: Id, ui: &mut UiCell) -> Self::Event {
let (w1, w2) = self;
let [id1, id2] = ids.two().unwrap();
(
set_ingame(w1, parent_id, id1, ui),
set_ingame(w2, parent_id, id2, ui),
)
}
fn init_ids(mut id_gen: widget::id::Generator) -> Ids {
Ids::Two([id_gen.next(), id_gen.next()])
}
}
impl<W, E, R> Ingameable for (W, E, R)
where
W: IngameWidget,
E: IngameWidget,
R: IngameWidget,
{
type Event = (
<W as Widget>::Event,
<E as Widget>::Event,
<R as Widget>::Event,
);
fn prim_count(&self) -> usize {
self.0.prim_count() + self.1.prim_count() + self.2.prim_count()
}
fn set_ingame(self, ids: Ids, parent_id: Id, ui: &mut UiCell) -> Self::Event {
let (w1, w2, w3) = self;
let ids = ids.three().unwrap();
(
set_ingame(w1, parent_id, ids[0], ui),
set_ingame(w2, parent_id, ids[1], ui),
set_ingame(w3, parent_id, ids[2], ui),
)
}
fn init_ids(mut id_gen: widget::id::Generator) -> Ids {
Ids::Three([id_gen.next(), id_gen.next(), id_gen.next()])
}
}
impl<W, E, R, T> Ingameable for (W, E, R, T)
where
W: IngameWidget,
E: IngameWidget,
R: IngameWidget,
T: IngameWidget,
{
type Event = (
<W as Widget>::Event,
<E as Widget>::Event,
<R as Widget>::Event,
<T as Widget>::Event,
);
fn prim_count(&self) -> usize {
self.0.prim_count() + self.1.prim_count() + self.2.prim_count() + self.3.prim_count()
}
fn set_ingame(self, ids: Ids, parent_id: Id, ui: &mut UiCell) -> Self::Event {
let (w1, w2, w3, w4) = self;
let ids = ids.four().unwrap();
(
set_ingame(w1, parent_id, ids[0], ui),
set_ingame(w2, parent_id, ids[1], ui),
set_ingame(w3, parent_id, ids[2], ui),
set_ingame(w4, parent_id, ids[3], ui),
)
}
fn init_ids(mut id_gen: widget::id::Generator) -> Ids {
Ids::Four([id_gen.next(), id_gen.next(), id_gen.next(), id_gen.next()])
}
}
#[derive(Clone, Copy)]
pub enum Ids {
None,
One(Id),
Two([Id; 2]),
Three([Id; 3]),
Four([Id; 4]),
}
impl Ids {
fn one(self) -> Option<Id> {
match self {
Ids::One(id) => Some(id),
_ => None,
}
}
fn two(self) -> Option<[Id; 2]> {
match self {
Ids::Two(ids) => Some(ids),
_ => None,
}
}
fn three(self) -> Option<[Id; 3]> {
match self {
Ids::Three(ids) => Some(ids),
_ => None,
}
}
fn four(self) -> Option<[Id; 4]> {
match self {
Ids::Four(ids) => Some(ids),
_ => None,
}
}
}
#[derive(Copy, Clone, PartialEq)]
@ -195,7 +65,7 @@ pub struct IngameParameters {
}
pub struct State {
ids: Ids,
id: Option<widget::Id>,
pub parameters: IngameParameters,
}
@ -223,9 +93,9 @@ impl<W: Ingameable> Widget for Ingame<W> {
type Style = Style;
type Event = W::Event;
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
fn init_state(&self, mut id_gen: widget::id::Generator) -> Self::State {
State {
ids: W::init_ids(id_gen),
id: Some(id_gen.next()),
parameters: self.parameters,
}
}
@ -247,7 +117,7 @@ impl<W: Ingameable> Widget for Ingame<W> {
});
}
widget.set_ingame(state.ids, id, ui)
widget.set_ingame(state.id.unwrap(), id, ui)
}
fn default_x_position(&self, ui: &Ui) -> Position {
@ -306,7 +176,7 @@ impl Widget for IngameAnchor {
fn init_state(&self, _: widget::id::Generator) -> Self::State {
State {
ids: Ids::None,
id: None,
parameters: self.parameters,
}
}