Skip to content
Snippets Groups Projects
spawner.rs 3.33 KiB
Newer Older
Louis's avatar
Louis committed
use std::time::Duration;

Louis's avatar
Louis committed
use bevy::ecs::system::SystemParam;
use bevy::prelude::*;
Louis's avatar
Louis committed
use bevy_tweening::lens::{TextColorLens, UiPositionLens};
use bevy_tweening::{Animator, EaseFunction, Tween, TweeningType};
Louis's avatar
Louis committed

use crate::assets::AssetHandles;
use crate::control::ai::{Automated, ShouldAct};
Louis's avatar
Louis committed
use crate::entities::animations::FrameAnimation;
use crate::entities::curses::{CurseEvent, CurseText};
use crate::entities::lifecycle::{GameEntity, Player};
Louis's avatar
Louis committed
use crate::system::camera::ChaseCam;
use crate::system::graphics::LAYER_CREATURE;
use crate::world::level_map::GridPosition;
Louis's avatar
Louis committed

const PLAYER_SPRITE: usize = 2;

#[derive(SystemParam)]
pub struct EntitySpawner<'w, 's> {
	pub commands: Commands<'w, 's>,
	pub handles: Res<'w, AssetHandles>,
}

impl<'w, 's> EntitySpawner<'w, 's> {
	pub fn spawn_player(&mut self, grid_position: UVec2) {
		let mut entity = self.commands.spawn();

		entity
			.insert(ChaseCam)
			.insert(GameEntity)
			.insert(Player)
			.insert(ShouldAct)
Louis's avatar
Louis committed
			.insert(FrameAnimation::new(
				vec![PLAYER_SPRITE, PLAYER_SPRITE + 1],
				Duration::from_millis(250),
			))
			.insert(GridPosition(grid_position));
Louis's avatar
Louis committed

		entity.insert_bundle(SpriteSheetBundle {
			texture_atlas: self.handles.atlas("creatures"),
			transform: Transform::from_translation(grid_position.as_vec2().extend(LAYER_CREATURE)),
			sprite: TextureAtlasSprite {
				index: PLAYER_SPRITE,
				..Default::default()
			},
			..Default::default()
		});
	}
	pub fn spawn_creature(&mut self, sprite: usize, grid_position: UVec2) {
		let mut entity = self.commands.spawn();
		entity
			.insert(GameEntity)
			.insert(Automated)
			.insert(FrameAnimation::new(
				vec![sprite, sprite + 1],
				Duration::from_millis(250),
			))
			.insert(GridPosition(grid_position));

		entity.insert_bundle(SpriteSheetBundle {
			texture_atlas: self.handles.atlas("creatures"),
			transform: Transform::from_translation(grid_position.as_vec2().extend(LAYER_CREATURE)),
			sprite: TextureAtlasSprite {
				index: sprite,
				..Default::default()
			},
			..Default::default()
		});
	}

Louis's avatar
Louis committed
	pub fn spawn_curse_text(&mut self, curse: CurseEvent) {
		let position_animation = Tween::new(
			EaseFunction::ExponentialIn,
			TweeningType::Once,
			Duration::from_millis(750),
			UiPositionLens {
				start: UiRect::new(Val::Auto, Val::Px(20.0), Val::Px(200.0), Val::Auto),
				end: UiRect::new(Val::Auto, Val::Px(20.0), Val::Px(20.0), Val::Auto),
			},
		);

		let colour_in_animation = Tween::new(
			EaseFunction::SineIn,
			TweeningType::Once,
			Duration::from_millis(500),
			TextColorLens {
				section: 0,
				start: (*Color::GOLD.set_a(0.0)).into(),
				end: (*Color::GOLD.set_a(1.0)).into(),
			},
		);

		self.commands
			.spawn_bundle(NodeBundle {
				color: Color::rgba(0.0, 0.0, 0.0, 0.0).into(),
				style: Style {
					position: UiRect::new(Val::Auto, Val::Px(20.0), Val::Px(100.0), Val::Auto),
					position_type: PositionType::Absolute,
					..Default::default()
				},
				..Default::default()
			})
			.insert(Animator::new(position_animation))
			.insert(CurseText)
			.with_children(|builder| {
				builder
					.spawn_bundle(TextBundle {
						text: Text::from_section(
							curse.to_string(),
							TextStyle {
								color: (*Color::GOLD.set_a(0.0)),
								font: self.handles.font("main"),
								font_size: 32.0,
							},
						),
						..Default::default()
					})
					.insert(Animator::new(colour_in_animation));
			});
	}
Louis's avatar
Louis committed
}