Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flip unit sprites horizontally #473

Merged
merged 1 commit into from May 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion ggwp-zscene/src/action.rs
Expand Up @@ -2,7 +2,7 @@ use std::{fmt::Debug, time::Duration};

pub use crate::action::{
change_color_to::ChangeColorTo, empty::Empty, fork::Fork, hide::Hide, move_by::MoveBy,
sequence::Sequence, set_color::SetColor, show::Show, sleep::Sleep,
sequence::Sequence, set_color::SetColor, set_facing::SetFacing, show::Show, sleep::Sleep,
};

mod change_color_to;
Expand All @@ -12,6 +12,7 @@ mod hide;
mod move_by;
mod sequence;
mod set_color;
mod set_facing;
mod show;
mod sleep;

Expand Down
20 changes: 20 additions & 0 deletions ggwp-zscene/src/action/set_facing.rs
@@ -0,0 +1,20 @@
use crate::{Action, Facing, Sprite};

#[derive(Debug)]
pub struct SetFacing {
sprite: Sprite,
facing: Facing,
}

impl SetFacing {
pub fn new(sprite: &Sprite, facing: Facing) -> Self {
let sprite = sprite.clone();
Self { sprite, facing }
}
}

impl Action for SetFacing {
fn begin(&mut self) {
self.sprite.set_facing(self.facing);
}
}
2 changes: 1 addition & 1 deletion ggwp-zscene/src/lib.rs
Expand Up @@ -14,7 +14,7 @@ use ggez::{Context, GameResult};
pub use crate::{
action::{Action, Boxed},
error::Error,
sprite::Sprite,
sprite::{Facing, Sprite},
};

pub mod action;
Expand Down
27 changes: 27 additions & 0 deletions ggwp-zscene/src/sprite.rs
Expand Up @@ -8,12 +8,19 @@ use ggez::{

use crate::{Error, Result};

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Facing {
Left,
Right,
}

struct SpriteData {
drawable: Box<dyn Drawable>,
dimensions: Rect,
basic_scale: f32,
param: graphics::DrawParam,
offset: Vector2<f32>,
facing: Facing,
}

impl fmt::Debug for SpriteData {
Expand All @@ -24,6 +31,7 @@ impl fmt::Debug for SpriteData {
.field("basic_scale", &self.basic_scale)
.field("param", &self.param)
.field("offset", &self.offset)
.field("facing", &self.facing)
.finish()
}
}
Expand Down Expand Up @@ -54,6 +62,7 @@ impl Sprite {
basic_scale: scale,
param,
offset: Vector2::new(0.0, 0.0),
facing: Facing::Right,
};
let data = Rc::new(RefCell::new(data));
Ok(Self { data })
Expand All @@ -70,6 +79,24 @@ impl Sprite {

// TODO: some method to change the image.

pub fn set_facing(&mut self, facing: Facing) {
if facing == self.data.borrow().facing {
return;
}
let offset;
{
let mut data = self.data.borrow_mut();
data.facing = facing;
data.param.scale.x *= -1.0;
let mut dimensions = data.dimensions;
dimensions.scale(data.param.scale.x, data.param.scale.y);
let off_x = -data.offset.x / dimensions.w;
let off_y = -data.offset.y / dimensions.h;
offset = Vector2::new(-off_x, off_y);
}
self.set_offset(offset);
}

pub fn set_centered(&mut self, is_centered: bool) {
let offset = if is_centered {
Vector2::new(0.5, 0.5)
Expand Down
28 changes: 28 additions & 0 deletions src/geom.rs
Expand Up @@ -30,3 +30,31 @@ pub fn rand_tile_offset(size: f32, radius: f32) -> Vector2<f32> {
thread_rng().gen_range(-r, r) * FLATNESS_COEFFICIENT,
)
}

#[derive(Clone, Copy, Debug)]
pub enum Facing {
Left,
Right,
}

impl Facing {
pub fn from_positions(tile_size: f32, from: PosHex, to: PosHex) -> Option<Self> {
if from == to {
return None;
}
let from = hex_to_point(tile_size, from);
let to = hex_to_point(tile_size, to);
Some(if to.x > from.x {
Facing::Right
} else {
Facing::Left
})
}

pub fn to_scene_facing(self) -> scene::Facing {
match self {
Facing::Left => scene::Facing::Left,
Facing::Right => scene::Facing::Right,
}
}
}
2 changes: 1 addition & 1 deletion src/main.rs
Expand Up @@ -101,7 +101,7 @@ fn main() -> ZResult {
const APP_ID: &str = "zemeroth";
const APP_AUTHOR: &str = "ozkriff";
const ASSETS_DIR_NAME: &str = "assets";
const ASSETS_HASHSUM: &str = "a9ac7e886bb9319f7ec5cdddba24731b";
const ASSETS_HASHSUM: &str = "a42fb4a97d6529620dabec3defea8aa9";

fn enable_backtrace() {
if std::env::var("RUST_BACKTRACE").is_err() {
Expand Down
115 changes: 61 additions & 54 deletions src/screen/battle/visualize.rs
Expand Up @@ -8,13 +8,13 @@ use ggez::{
};
use log::{debug, info};
use rand::{thread_rng, Rng};
use scene::{action, Action, Boxed, Sprite};
use scene::{action, Action, Boxed, Facing, Sprite};

use crate::{
core::{
battle::{
ability::Ability,
component::{ObjType, WeaponType},
component::{Component, WeaponType},
effect::{self, Effect},
event::{self, ActiveEvent, Event},
execute::{hit_chance, ApplyPhase},
Expand Down Expand Up @@ -407,10 +407,10 @@ fn sprite_params(name: &str) -> SpriteInfo {
"spearman" => ("/spearman.png", 0.2, 0.05, 1.0),
"hammerman" => ("/hammerman.png", 0.05, 0.1, 1.0),
"alchemist" => ("/alchemist.png", 0.05, 0.1, 1.0),
"imp" => ("/imp.png", -0.05, 0.15, 1.3),
"imp_toxic" => ("/imp_toxic.png", -0.05, 0.15, 1.2),
"imp_bomber" => ("/imp_bomber.png", -0.05, 0.15, 1.2),
"imp_summoner" => ("/imp_summoner.png", -0.05, 0.15, 1.3),
"imp" => ("/imp.png", 0.0, 0.15, 1.3),
"imp_toxic" => ("/imp_toxic.png", 0.0, 0.15, 1.2),
"imp_bomber" => ("/imp_bomber.png", 0.0, 0.15, 1.2),
"imp_summoner" => ("/imp_summoner.png", 0.0, 0.15, 1.3),
"boulder" => ("/boulder.png", 0.0, 0.4, 2.5),
"bomb_damage" => ("/bomb.png", 0.0, 0.2, 0.7),
"bomb_push" => ("/bomb.png", 0.0, 0.2, 0.7),
Expand Down Expand Up @@ -521,49 +521,6 @@ fn visualize_event(
Ok(action)
}

fn visualize_create(
view: &mut BattleView,
context: &mut Context,
id: ObjId,
pos: PosHex,
prototype: &ObjType,
) -> ZResult<Box<dyn Action>> {
// TODO: Move to some .ron config:
let SpriteInfo {
path,
offset_x,
offset_y,
shadow_size_coefficient,
} = sprite_params(prototype.0.as_str());
let point = geom::hex_to_point(view.tile_size(), pos);
let color = [1.0, 1.0, 1.0, 1.0].into();
let size = view.tile_size() * 2.0;
let sprite_object = {
let mut sprite = Sprite::from_path(context, path, size)?;
sprite.set_color(Color { a: 0.0, ..color });
sprite.set_offset(Vector2::new(0.5 - offset_x, 1.0 - offset_y));
sprite.set_pos(point);
sprite
};
let sprite_shadow = {
let image_shadow = view.images().shadow.clone();
let mut sprite = Sprite::from_image(context, image_shadow, size * shadow_size_coefficient)?;
sprite.set_centered(true);
sprite.set_color(Color { a: 0.0, ..color });
sprite.set_pos(point);
sprite
};
view.add_object(id, &sprite_object, &sprite_shadow);
let action_change_shadow_color =
action::ChangeColorTo::new(&sprite_shadow, color, time_s(0.2)).boxed();
Ok(seq(vec![
action::Show::new(&view.layers().shadows, &sprite_shadow).boxed(),
action::Show::new(&view.layers().objects, &sprite_object).boxed(),
fork(action_change_shadow_color),
action::ChangeColorTo::new(&sprite_object, color, time_s(0.25)).boxed(),
]))
}

fn visualize_event_move_to(
_: &State,
view: &mut BattleView,
Expand All @@ -583,13 +540,16 @@ fn visualize_event_move_to(
for step in event.path.steps() {
let from = geom::hex_to_point(view.tile_size(), step.from);
let to = geom::hex_to_point(view.tile_size(), step.to);
let facing = geom::Facing::from_positions(view.tile_size(), step.from, step.to)
.expect("Bad path step");
let diff = to - from;
let step_height = view.tile_size() * 0.25;
let step_time = time_s(0.13);
let move_time = time_s(0.3);
let main_move = action::MoveBy::new(&sprite, diff, move_time).boxed();
let shadow_move = action::MoveBy::new(&sprite_shadow, diff, move_time).boxed();
let action = seq(vec![
action::SetFacing::new(&sprite, facing.to_scene_facing()).boxed(),
fork(main_move),
fork(shadow_move),
up_and_down_move(view, &sprite, step_height, step_time),
Expand Down Expand Up @@ -628,6 +588,9 @@ fn visualize_event_attack(
let action_shadow_move_to = action::MoveBy::new(&sprite_shadow, diff, time_to).boxed();
let action_sprite_move_from = action::MoveBy::new(&sprite, -diff, time_from).boxed();
let action_shadow_move_from = action::MoveBy::new(&sprite_shadow, -diff, time_from).boxed();
if let Some(facing) = geom::Facing::from_positions(view.tile_size(), map_from, map_to) {
actions.push(action::SetFacing::new(&sprite, facing.to_scene_facing()).boxed());
}
actions.push(fork(action_shadow_move_to));
actions.push(action_sprite_move_to);
actions.push(show_weapon_flash(view, context, map_to, event.weapon_type)?);
Expand Down Expand Up @@ -786,10 +749,14 @@ fn visualize_event_use_ability(
};
let pos = state.parts().pos.get(event.id).0;
let text = event.ability.to_string();
Ok(seq(vec![
action_main,
message(view, context, pos, &format!("<{}>", text))?,
]))
let mut actions = Vec::new();
if let Some(facing) = geom::Facing::from_positions(view.tile_size(), pos, event.pos) {
let sprite = view.id_to_sprite(event.id).clone();
actions.push(action::SetFacing::new(&sprite, facing.to_scene_facing()).boxed());
}
actions.push(action_main);
actions.push(message(view, context, pos, &format!("<{}>", text))?);
Ok(seq(actions))
}

fn visualize_event_effect_tick(
Expand Down Expand Up @@ -865,7 +832,47 @@ fn visualize_effect_create(
target_id: ObjId,
effect: &effect::Create,
) -> ZResult<Box<dyn Action>> {
visualize_create(view, context, target_id, effect.pos, &effect.prototype).map(fork)
// TODO: Move to some .ron config:
let SpriteInfo {
path,
offset_x,
offset_y,
shadow_size_coefficient,
} = sprite_params(effect.prototype.0.as_str());
let point = geom::hex_to_point(view.tile_size(), effect.pos);
let color = [1.0, 1.0, 1.0, 1.0].into();
let size = view.tile_size() * 2.0;
let sprite_object = {
let mut sprite = Sprite::from_path(context, path, size)?;
sprite.set_color(Color { a: 0.0, ..color });
sprite.set_offset(Vector2::new(0.5 - offset_x, 1.0 - offset_y));
sprite.set_pos(point);
for component in &effect.components {
if let Component::BelongsTo(belongs_to) = component {
if belongs_to.0 == PlayerId(1) {
sprite.set_facing(Facing::Left);
}
}
}
sprite
};
let sprite_shadow = {
let image_shadow = view.images().shadow.clone();
let mut sprite = Sprite::from_image(context, image_shadow, size * shadow_size_coefficient)?;
sprite.set_centered(true);
sprite.set_color(Color { a: 0.0, ..color });
sprite.set_pos(point);
sprite
};
view.add_object(target_id, &sprite_object, &sprite_shadow);
let action_change_shadow_color =
action::ChangeColorTo::new(&sprite_shadow, color, time_s(0.2)).boxed();
Ok(fork(seq(vec![
action::Show::new(&view.layers().shadows, &sprite_shadow).boxed(),
action::Show::new(&view.layers().objects, &sprite_object).boxed(),
fork(action_change_shadow_color),
action::ChangeColorTo::new(&sprite_object, color, time_s(0.25)).boxed(),
])))
}

fn visualize_effect_kill(
Expand Down