Cleaned up starfield and added sprite start edge
parent
7d5b244492
commit
56160a8abe
|
@ -28,8 +28,8 @@ starfield.max_size = 1.8
|
|||
# Z-axis (parallax) range for starfield stars
|
||||
starfield.min_dist = 75.0
|
||||
starfield.max_dist = 200.0
|
||||
# Name of starfield sprite
|
||||
starfield.sprite = "starfield"
|
||||
# Path to starfield sprite texture
|
||||
starfield.texture = "starfield.png"
|
||||
|
||||
|
||||
# Zoom level bounds.
|
||||
|
|
|
@ -1,17 +1,41 @@
|
|||
# TODO:
|
||||
# random start frame
|
||||
# repeat once: stay on last frame
|
||||
# blending mode: alpha / half-alpha / additive
|
||||
|
||||
|
||||
[sprite."starfield"]
|
||||
file = "starfield.png"
|
||||
|
||||
[sprite."star::star"]
|
||||
file = "star/B-09.png"
|
||||
|
||||
[sprite."flare::ion"]
|
||||
file = "flare/1.png"
|
||||
start_at = "rise:top"
|
||||
random_start_frame = false
|
||||
|
||||
section.idle.timing.duration = 5
|
||||
#section.idle.repeat = "reverse"
|
||||
section.idle.frames = ["flare/1.png", "flare/4.png", "flare/5.png"]
|
||||
section.idle.top = "reverse"
|
||||
section.idle.bot = "reverse"
|
||||
# stop: stop on last frame (special)
|
||||
# restart: go to opposite end (same as self:tail)
|
||||
# repeat: reverse and play again
|
||||
# TODO: implement random
|
||||
# spec: "idle:bot", "idle:top", or "idle:random"
|
||||
|
||||
section.rise.timing.duration = 0.15
|
||||
section.rise.top = "stop"
|
||||
section.rise.bot = "run:top"
|
||||
section.rise.frames = [
|
||||
"flare/6.png",
|
||||
"flare/5.png",
|
||||
"flare/4.png",
|
||||
"flare/3.png",
|
||||
"flare/2.png",
|
||||
]
|
||||
|
||||
section.run.timing.duration = 0.01
|
||||
section.run.top = "stop"
|
||||
section.run.bot = "stop"
|
||||
section.run.frames = ["flare/1.png"]
|
||||
|
||||
|
||||
[sprite."planet::earth"]
|
||||
file = "planet/earth.png"
|
||||
|
@ -70,6 +94,19 @@ file = "ui/landscape/test.png"
|
|||
[sprite."ui::landscapemask"]
|
||||
file = "ui/landscape-mask.png"
|
||||
|
||||
[sprite."ui::planet::button"]
|
||||
start_at = "off:top"
|
||||
random_start_frame = false
|
||||
|
||||
section.off.top = "stop"
|
||||
section.off.bot = "stop"
|
||||
section.off.timing.fps = 60
|
||||
section.off.frames = ["ui/planet-button-off.png"]
|
||||
|
||||
section.on.top = "stop"
|
||||
section.on.bot = "stop"
|
||||
section.on.timing.fps = 60
|
||||
section.on.frames = ["ui/planet-button-on.png"]
|
||||
|
||||
[sprite."particle::blaster"]
|
||||
timing.duration = 0.15
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{AnimSectionHandle, Content, SectionEdge, SpriteHandle};
|
||||
use crate::{AnimSectionHandle, Content, SectionEdge, SpriteHandle, SpriteStart};
|
||||
|
||||
/// A single frame's state
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -72,33 +72,35 @@ impl AnimAutomaton {
|
|||
/// Create a new AnimAutomaton
|
||||
pub fn new(ct: &Content, sprite_handle: SpriteHandle) -> Self {
|
||||
let sprite = ct.get_sprite(sprite_handle);
|
||||
|
||||
let (current_section, texture, current_direction) = match sprite.start_at {
|
||||
SpriteStart::Top { section } => (
|
||||
section,
|
||||
*sprite.get_section(section).frames.first().unwrap(),
|
||||
AnimDirection::Down,
|
||||
),
|
||||
SpriteStart::Bot { section } => (
|
||||
section,
|
||||
*sprite.get_section(section).frames.last().unwrap(),
|
||||
AnimDirection::Up,
|
||||
),
|
||||
};
|
||||
|
||||
Self {
|
||||
current_direction: AnimDirection::Down,
|
||||
sprite: sprite.handle,
|
||||
current_frame: 0,
|
||||
current_fade: 0.0,
|
||||
current_section: sprite.default_section,
|
||||
|
||||
last_texture: *sprite
|
||||
.get_section(sprite.default_section)
|
||||
.frames
|
||||
.first()
|
||||
.unwrap(),
|
||||
|
||||
next_texture: *sprite
|
||||
.get_section(sprite.default_section)
|
||||
.frames
|
||||
.first()
|
||||
.unwrap(),
|
||||
current_direction,
|
||||
current_section,
|
||||
last_texture: texture,
|
||||
next_texture: texture,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset this animation
|
||||
pub fn reset(&mut self, ct: &Content) {
|
||||
let sprite = ct.get_sprite(self.sprite);
|
||||
self.current_fade = 0.0;
|
||||
self.current_frame = 0;
|
||||
self.current_section = sprite.default_section
|
||||
*self = Self::new(ct, self.sprite);
|
||||
}
|
||||
|
||||
/// Reverse this animation's direction
|
||||
|
|
|
@ -141,8 +141,6 @@ pub struct Content {
|
|||
/// Map strings to texture names.
|
||||
/// This is only necessary because we need to hard-code a few texture names for UI elements.
|
||||
sprite_index: HashMap<String, SpriteHandle>,
|
||||
/// The texture to use for starfield stars
|
||||
starfield_handle: Option<SpriteHandle>,
|
||||
|
||||
/// Keeps track of which images are in which texture
|
||||
sprite_atlas: SpriteAtlas,
|
||||
|
@ -206,7 +204,7 @@ impl Content {
|
|||
let mut content = Self {
|
||||
config: {
|
||||
if let Some(c) = root.config {
|
||||
c.build(&asset_root)
|
||||
c.build(&asset_root, &atlas)
|
||||
.with_context(|| "while parsing config table")?
|
||||
} else {
|
||||
bail!("failed loading content: no config table specified")
|
||||
|
@ -222,7 +220,6 @@ impl Content {
|
|||
factions: Vec::new(),
|
||||
effects: Vec::new(),
|
||||
sprite_index: HashMap::new(),
|
||||
starfield_handle: None,
|
||||
};
|
||||
|
||||
// TODO: enforce sprite and image limits
|
||||
|
@ -280,16 +277,6 @@ impl Content {
|
|||
(0..self.systems.len()).map(|x| SystemHandle { index: x })
|
||||
}
|
||||
|
||||
/// Get the handle for the starfield sprite
|
||||
pub fn get_starfield_texture(&self) -> u32 {
|
||||
let h = match self.starfield_handle {
|
||||
Some(h) => h,
|
||||
None => unreachable!("Starfield sprite hasn't been loaded yet!"),
|
||||
};
|
||||
let sprite = self.get_sprite(h);
|
||||
sprite.get_section(sprite.default_section).frames[0]
|
||||
}
|
||||
|
||||
/// Get a handle from a sprite name
|
||||
pub fn get_sprite_handle(&self, name: &str) -> SpriteHandle {
|
||||
return match self.sprite_index.get(name) {
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::path::PathBuf;
|
|||
|
||||
pub(crate) mod syntax {
|
||||
use anyhow::{bail, Result};
|
||||
use galactica_packer::SpriteAtlas;
|
||||
use serde::Deserialize;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
|
@ -19,7 +20,7 @@ pub(crate) mod syntax {
|
|||
|
||||
impl Config {
|
||||
// TODO: clean up build trait
|
||||
pub fn build(self, asset_root: &Path) -> Result<super::Config> {
|
||||
pub fn build(self, asset_root: &Path, atlas: &SpriteAtlas) -> Result<super::Config> {
|
||||
for i in &self.fonts.files {
|
||||
if !asset_root.join(i).exists() {
|
||||
bail!("font file `{}` doesn't exist", i.display());
|
||||
|
@ -35,6 +36,16 @@ pub(crate) mod syntax {
|
|||
// An insufficient limit will result in some tiles not being drawn
|
||||
let starfield_instance_limit = 12 * starfield_count as u64;
|
||||
|
||||
let starfield_texture = match atlas.path_map.get(&self.starfield.texture) {
|
||||
Some(s) => *s,
|
||||
None => {
|
||||
bail!(
|
||||
"starfield texture `{}` doesn't exist",
|
||||
self.starfield.texture.display()
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
return Ok(super::Config {
|
||||
sprite_root: asset_root.join(self.sprite_root),
|
||||
font_files: self
|
||||
|
@ -53,7 +64,7 @@ pub(crate) mod syntax {
|
|||
starfield_min_dist: self.starfield.min_dist,
|
||||
starfield_max_size: self.starfield.max_size,
|
||||
starfield_min_size: self.starfield.min_size,
|
||||
starfield_sprite: self.starfield.sprite,
|
||||
starfield_texture,
|
||||
starfield_count,
|
||||
starfield_density,
|
||||
starfield_size,
|
||||
|
@ -80,7 +91,7 @@ pub(crate) mod syntax {
|
|||
pub max_size: f32,
|
||||
pub min_dist: f32,
|
||||
pub max_dist: f32,
|
||||
pub sprite: String,
|
||||
pub texture: PathBuf,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,8 +128,8 @@ pub struct Config {
|
|||
/// Maximum z-distance of starfield star, in game units
|
||||
pub starfield_max_dist: f32,
|
||||
|
||||
/// Name of starfield sprite
|
||||
pub starfield_sprite: String,
|
||||
/// Index of starfield texture
|
||||
pub starfield_texture: u32,
|
||||
|
||||
/// Size of a square starfield tile, in game units.
|
||||
/// A tile of size STARFIELD_Z_MAX * screen-size-in-game-units
|
||||
|
|
|
@ -8,7 +8,7 @@ pub(crate) mod syntax {
|
|||
use galactica_util::to_radians;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{Content, ContentBuildContext, EffectHandle};
|
||||
use crate::{Content, ContentBuildContext, EffectHandle, SpriteStart};
|
||||
// Raw serde syntax structs.
|
||||
// These are never seen by code outside this crate.
|
||||
|
||||
|
@ -56,8 +56,12 @@ pub(crate) mod syntax {
|
|||
TextOrFloat::Float(f) => f,
|
||||
TextOrFloat::Text(s) => {
|
||||
if s == "inherit" {
|
||||
// Match lifetime of first section of sprite
|
||||
let sprite = content.get_sprite(sprite);
|
||||
let sec = sprite.get_section(sprite.default_section);
|
||||
let sec = match sprite.start_at {
|
||||
SpriteStart::Top { section } => sprite.get_section(section),
|
||||
SpriteStart::Bot { section } => sprite.get_section(section),
|
||||
};
|
||||
sec.frame_duration * sec.frames.len() as f32
|
||||
} else {
|
||||
bail!("bad effect lifetime, must be float or \"inherit\"",)
|
||||
|
|
|
@ -51,7 +51,7 @@ pub(crate) mod syntax {
|
|||
#[derive(Debug, Deserialize)]
|
||||
pub struct CompleteSprite {
|
||||
pub section: HashMap<String, SpriteSection>,
|
||||
pub default_section: String,
|
||||
pub start_at: SectionEdge,
|
||||
}
|
||||
|
||||
/// A single animation section
|
||||
|
@ -109,12 +109,12 @@ pub(crate) mod syntax {
|
|||
}
|
||||
|
||||
let edge_top = match &self.top {
|
||||
Some(x) => x.resolve(all_sections)?,
|
||||
Some(x) => x.resolve_as_edge(all_sections)?,
|
||||
None => super::SectionEdge::Stop,
|
||||
};
|
||||
|
||||
let edge_bot = match &self.bot {
|
||||
Some(x) => x.resolve(all_sections)?,
|
||||
Some(x) => x.resolve_as_edge(all_sections)?,
|
||||
None => super::SectionEdge::Stop,
|
||||
};
|
||||
|
||||
|
@ -138,7 +138,23 @@ pub(crate) mod syntax {
|
|||
}
|
||||
|
||||
impl SectionEdge {
|
||||
pub fn resolve(
|
||||
pub fn resolve_as_start(
|
||||
&self,
|
||||
all_sections: &HashMap<String, AnimSectionHandle>,
|
||||
) -> Result<super::SpriteStart> {
|
||||
let e = self
|
||||
.resolve_as_edge(all_sections)
|
||||
.with_context(|| format!("while resolving start edge"))?;
|
||||
match e {
|
||||
super::SectionEdge::Bot { section } => Ok(super::SpriteStart::Bot { section }),
|
||||
super::SectionEdge::Top { section } => Ok(super::SpriteStart::Top { section }),
|
||||
_ => {
|
||||
bail!("bad section start specification `{}`", self.val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_as_edge(
|
||||
&self,
|
||||
all_sections: &HashMap<String, AnimSectionHandle>,
|
||||
) -> Result<super::SectionEdge> {
|
||||
|
@ -184,7 +200,7 @@ pub(crate) mod syntax {
|
|||
// TODO: should be pub crate
|
||||
/// A handle for an animation section inside a sprite
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct AnimSectionHandle(usize);
|
||||
pub struct AnimSectionHandle(pub(crate) usize);
|
||||
|
||||
/// An edge between two animation sections
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -211,6 +227,22 @@ pub enum SectionEdge {
|
|||
Restart,
|
||||
}
|
||||
|
||||
/// Where to start an animation
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SpriteStart {
|
||||
/// Play the given section from the bottm
|
||||
Bot {
|
||||
/// The section to play
|
||||
section: AnimSectionHandle,
|
||||
},
|
||||
|
||||
/// Play the given section from the top
|
||||
Top {
|
||||
/// The section to play
|
||||
section: AnimSectionHandle,
|
||||
},
|
||||
}
|
||||
|
||||
/// Represents a sprite that may be used in the game.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Sprite {
|
||||
|
@ -220,8 +252,8 @@ pub struct Sprite {
|
|||
/// This sprite's handle
|
||||
pub handle: SpriteHandle,
|
||||
|
||||
/// This sprite's default section
|
||||
pub default_section: AnimSectionHandle,
|
||||
/// Where this sprite starts playing
|
||||
pub start_at: SpriteStart,
|
||||
|
||||
/// This sprite's animation sections
|
||||
sections: Vec<SpriteSection>,
|
||||
|
@ -236,6 +268,14 @@ impl Sprite {
|
|||
&self.sections[section.0]
|
||||
}
|
||||
|
||||
/// Get this sprite's first frame
|
||||
pub fn get_first_frame(&self) -> u32 {
|
||||
match self.start_at {
|
||||
SpriteStart::Bot { section } => *self.get_section(section).frames.last().unwrap(),
|
||||
SpriteStart::Top { section } => *self.get_section(section).frames.first().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate this sprite's sections
|
||||
pub fn iter_sections(&self) -> impl Iterator<Item = &SpriteSection> {
|
||||
self.sections.iter()
|
||||
|
@ -293,20 +333,13 @@ impl crate::Build for Sprite {
|
|||
aspect,
|
||||
};
|
||||
|
||||
if sprite_name == content.config.starfield_sprite {
|
||||
if content.starfield_handle.is_none() {
|
||||
content.starfield_handle = Some(h)
|
||||
} else {
|
||||
// This can't happen, since this is a hashmap.
|
||||
unreachable!("Found two starfield sprites! Something is very wrong.")
|
||||
}
|
||||
}
|
||||
|
||||
content.sprite_index.insert(sprite_name.clone(), h);
|
||||
|
||||
content.sprites.push(Self {
|
||||
name: sprite_name,
|
||||
default_section: AnimSectionHandle(0),
|
||||
start_at: SpriteStart::Top {
|
||||
section: AnimSectionHandle(0),
|
||||
},
|
||||
sections: vec![SpriteSection {
|
||||
frames: vec![img.idx],
|
||||
// We implement unanimated sprites with a very fast framerate
|
||||
|
@ -333,11 +366,6 @@ impl crate::Build for Sprite {
|
|||
aspect,
|
||||
};
|
||||
|
||||
// TODO: remove?
|
||||
if sprite_name == content.config.starfield_sprite {
|
||||
unreachable!("Starfield texture may not be animated")
|
||||
}
|
||||
|
||||
let mut sections = Vec::new();
|
||||
sections.push(section);
|
||||
|
||||
|
@ -345,7 +373,9 @@ impl crate::Build for Sprite {
|
|||
content.sprites.push(Self {
|
||||
name: sprite_name,
|
||||
sections,
|
||||
default_section: AnimSectionHandle(0),
|
||||
start_at: SpriteStart::Bot {
|
||||
section: AnimSectionHandle(0),
|
||||
},
|
||||
handle: h,
|
||||
aspect,
|
||||
});
|
||||
|
@ -358,13 +388,10 @@ impl crate::Build for Sprite {
|
|||
idx += 1;
|
||||
}
|
||||
|
||||
if !section_names.contains_key(&s.default_section) {
|
||||
bail!(
|
||||
"could not load sprite `{}`, default section `{}` doesn't exist",
|
||||
sprite_name,
|
||||
s.default_section
|
||||
);
|
||||
}
|
||||
let start_at = s
|
||||
.start_at
|
||||
.resolve_as_start(§ion_names)
|
||||
.with_context(|| format!("while loading sprite `{}`", sprite_name))?;
|
||||
|
||||
let mut sections = Vec::with_capacity(idx);
|
||||
let mut dim = None;
|
||||
|
@ -405,7 +432,7 @@ impl crate::Build for Sprite {
|
|||
content.sprites.push(Self {
|
||||
name: sprite_name,
|
||||
sections,
|
||||
default_section: *section_names.get(&s.default_section).unwrap(),
|
||||
start_at,
|
||||
handle: h,
|
||||
aspect,
|
||||
});
|
||||
|
@ -413,13 +440,6 @@ impl crate::Build for Sprite {
|
|||
}
|
||||
}
|
||||
|
||||
if content.starfield_handle.is_none() {
|
||||
bail!(
|
||||
"Could not find a starfield texture (name: `{}`)",
|
||||
content.config.starfield_sprite
|
||||
)
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ impl GPUState {
|
|||
);
|
||||
|
||||
let sprite = state.ct.get_sprite(o.sprite);
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
// Push this object's instance
|
||||
self.state.push_object_buffer(ObjectInstance {
|
||||
|
|
|
@ -49,7 +49,7 @@ impl<'a> super::GPUState {
|
|||
// Write all new particles to GPU buffer
|
||||
for i in input.particles.iter() {
|
||||
let sprite = input.ct.get_sprite(i.sprite);
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
self.state.push_particle_buffer(ParticleInstance {
|
||||
position: [i.pos.x, i.pos.y],
|
||||
|
@ -306,7 +306,7 @@ impl<'a> super::GPUState {
|
|||
],
|
||||
window_scale: [self.state.window.scale_factor() as f32, 0.0],
|
||||
window_aspect: [self.state.window_aspect, 0.0],
|
||||
starfield_sprite: [input.ct.get_starfield_texture(), 0],
|
||||
starfield_sprite: [input.ct.get_config().starfield_texture, 0],
|
||||
starfield_tile_size: [input.ct.get_config().starfield_size, 0.0],
|
||||
starfield_size_limits: [
|
||||
input.ct.get_config().starfield_min_size,
|
||||
|
|
|
@ -61,7 +61,7 @@ impl Radar {
|
|||
let arrow_sprite = input.ct.get_sprite_handle("ui::centerarrow");
|
||||
|
||||
let sprite = input.ct.get_sprite(input.ct.get_sprite_handle("ui::radar"));
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
// Push this object's instance
|
||||
state.push_ui_buffer(UiInstance {
|
||||
|
@ -92,7 +92,7 @@ impl Radar {
|
|||
}
|
||||
|
||||
let sprite = input.ct.get_sprite(planet_sprite);
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
// Push this object's instance
|
||||
state.push_ui_buffer(UiInstance {
|
||||
|
@ -153,7 +153,7 @@ impl Radar {
|
|||
+ (d * (radar_size / 2.0));
|
||||
|
||||
let sprite = input.ct.get_sprite(ship_sprite);
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
state.push_ui_buffer(UiInstance {
|
||||
anchor: PositionAnchor::NwC.to_int(),
|
||||
|
@ -181,7 +181,7 @@ impl Radar {
|
|||
let size = 7.0f32.min((0.8 - m) * 70.0);
|
||||
|
||||
let sprite = input.ct.get_sprite(sprite);
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
state.push_ui_buffer(UiInstance {
|
||||
anchor: PositionAnchor::NwNw.to_int(),
|
||||
|
@ -253,7 +253,7 @@ impl Radar {
|
|||
+ Rotation2::new(angle) * Vector2::new(0.915 * (radar_size / 2.0), 0.0);
|
||||
|
||||
let sprite = input.ct.get_sprite(arrow_sprite);
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
state.push_ui_buffer(UiInstance {
|
||||
anchor: PositionAnchor::NwC.to_int(),
|
||||
|
|
|
@ -48,7 +48,7 @@ impl Status {
|
|||
let sprite = input
|
||||
.ct
|
||||
.get_sprite(input.ct.get_sprite_handle("ui::status"));
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
state.push_ui_buffer(UiInstance {
|
||||
anchor: PositionAnchor::NeNe.to_int(),
|
||||
|
|
|
@ -45,7 +45,7 @@ impl UiSprite {
|
|||
}
|
||||
|
||||
let sprite = input.ct.get_sprite(self.sprite);
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
state.push_ui_buffer(UiInstance {
|
||||
anchor: PositionAnchor::CC.to_int(),
|
||||
|
@ -59,7 +59,7 @@ impl UiSprite {
|
|||
.mask
|
||||
.map(|x| {
|
||||
let sprite = input.ct.get_sprite(x);
|
||||
let texture_b = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_b = sprite.get_first_frame(); // ANIMATE
|
||||
[1, texture_b]
|
||||
})
|
||||
.unwrap_or([0, 0]),
|
||||
|
@ -101,7 +101,7 @@ impl UiElement for UiSprite {
|
|||
}
|
||||
|
||||
let sprite = input.ct.get_sprite(self.sprite);
|
||||
let texture_a = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_a = sprite.get_first_frame(); // ANIMATE
|
||||
|
||||
state.push_ui_buffer(UiInstance {
|
||||
anchor: PositionAnchor::CNw.to_int(),
|
||||
|
@ -115,7 +115,7 @@ impl UiElement for UiSprite {
|
|||
.mask
|
||||
.map(|x| {
|
||||
let sprite = input.ct.get_sprite(x);
|
||||
let texture_b = sprite.get_section(sprite.default_section).frames[0]; // ANIMATE
|
||||
let texture_b = sprite.get_first_frame(); // ANIMATE
|
||||
[1, texture_b]
|
||||
})
|
||||
.unwrap_or([0, 0]),
|
||||
|
|
Loading…
Reference in New Issue