move the enemies to different places

This commit is contained in:
artem 2024-03-08 10:19:56 +03:00
parent e061a1405a
commit f0142c3ed2
9 changed files with 736 additions and 25 deletions

View File

@ -0,0 +1,479 @@
use crate::Player;
use fyrox::graph::SceneGraph;
use fyrox::{
core::{
algebra::{Point2, Vector2, Vector3},
impl_component_provider,
pool::Handle,
reflect::prelude::*,
uuid_provider,
visitor::prelude::*,
},
scene::{
animation::spritesheet::SpriteSheetAnimation,
collider::{BitMask, InteractionGroups},
dim2::{
physics::{Intersection, RayCastOptions},
rectangle::Rectangle,
rigidbody::RigidBody,
},
graph::Graph,
node::Node,
},
script::{ScriptContext, ScriptTrait},
};
impl_component_provider!(Archer,);
uuid_provider!(Archer = "a5671d19-9f1a-4286-8486-add4ebaadaec");
#[derive(Debug, Clone, Default, Copy)]
enum Animations {
#[default]
Idle = 0,
Run = 1,
Fight = 2,
Dead = 3,
Block = 4,
}
const DISTANCE_TO_FIGHT: f32 = 0.5;
const DISTANCE_TO_VIEW: f32 = 5.0;
const END_MAP_LEFT: f32 = -30.0;
const END_MAP_RIGHT: f32 = 30.0;
const SPEED: f32 = 3.1;
#[derive(Visit, Reflect, Debug, Clone, Default)]
pub struct Archer {
// pub sprite: Handle<Node>,
move_left: bool,
move_right: bool,
jump: bool,
pub animations: Vec<SpriteSheetAnimation>,
fight: bool,
win: bool,
dead: bool,
block: bool,
#[reflect(hidden)]
#[visit(skip)]
current_animation: Animations,
handle: Handle<Node>,
player_handle: Handle<Node>,
player_collider: Handle<Node>,
attack_damage: f32,
attack_timer: f32,
attack_speed: f32,
pub x: f32,
pub y: f32,
}
impl Archer {
fn init(&mut self) {
self.attack_damage = 100.0;
self.attack_speed = 0.1;
}
fn round(&self, a: f32) -> i32 {
return a.round() as i32;
}
pub fn take_damage(&mut self, _damage: &f32) {
if self.dead {
return;
}
self.block = true;
}
fn intersections_box(&self, graph: &mut Graph) -> bool {
if self.dead {
return false;
}
let self_node = match graph.try_get_mut(self.handle) {
Some(node) => node,
None => return false,
};
let self_position = self_node.global_position();
// Cast a ray from *this* node in the direction of the player node
let mut buffer = Vec::<Intersection>::new();
graph.physics2d.cast_ray(
RayCastOptions {
ray_origin: Point2::new(self_position.x, self_position.y),
ray_direction: Vector2::new(0.0, 1.0),
max_len: 0.5,
groups: InteractionGroups::default(),
// Sort the results by distance
sort_results: true,
},
// Store the collisions in the vector
&mut buffer,
);
if buffer.len() == 0 {
return false;
}
for i in 0..buffer.len() {
if self.player_handle == buffer[i].collider {
continue;
}
if buffer[i].toi == 0.0 {
continue;
}
if self.round(buffer[i].position[0]) != self.round(self_position.x) {
continue;
}
if self.round(buffer[i].position[1]) == self.round(self_position.y) {
continue;
}
return true;
}
return false;
}
fn intersections_player(&self, graph: &mut Graph, max_len: f32) -> Option<Vec<Intersection>> {
if self.dead {
return None;
}
// Get *this* node instance
let self_node = match graph.try_get_mut(self.handle) {
Some(node) => node,
None => return None,
};
let self_position = self_node.global_position();
// Get the player node
let player_node = match graph.try_get_mut(self.player_handle) {
Some(node) => node,
None => return None,
};
// Get the current position of *this* node and the player node
let player_position = player_node.global_position();
// Calculate the direction vector from *this* node to the player node
let direction = player_position - self_position;
// Cast a ray from *this* node in the direction of the player node
let mut buffer = Vec::<Intersection>::new();
graph.physics2d.cast_ray(
RayCastOptions {
ray_origin: Point2::new(self_position.x, self_position.y),
ray_direction: Vector2::new(direction.x, direction.y),
max_len: max_len,
groups: InteractionGroups::new(
// Only collide with the player
BitMask(0b1000_0000_0000_0000_0000_0000_0000_0000),
BitMask(0b0111_1111_1111_1111_1111_1111_1111_1111),
),
// groups: InteractionGroups::default(),
// Sort the results by distance
sort_results: true,
},
// Store the collisions in the vector
&mut buffer,
);
if buffer.len() == 0 {
return None;
}
return Some(buffer);
}
fn attack_player(&mut self, ctx: &mut ScriptContext) {
if self.win {
return;
}
if !self.fight {
return;
}
let player_script = ctx
.scene
.graph
.try_get_script_of_mut::<Player>(self.player_handle)
.unwrap();
if player_script.get_health() <= 0.0 {
self.fight = false;
self.block = false;
self.win = true;
return;
}
self.block = false;
player_script.take_damage(&self.attack_damage);
}
fn get_player_position(&self, context: &mut ScriptContext) -> Vector3<f32> {
let player_binding = context.scene.graph.try_get_mut(self.player_handle).unwrap();
let player_rigid_body = player_binding.cast::<RigidBody>();
let player_rigid_data = match player_rigid_body {
Some(rigid_body) => rigid_body,
None => panic!("wrong player position"),
};
return Vector3::new(
player_rigid_data.local_transform().position().x,
player_rigid_data.local_transform().position().y,
player_rigid_data.local_transform().position().z,
);
}
fn distance_to_player(&self, context: &mut ScriptContext) -> f32 {
let player_position = self.get_player_position(context);
let enemy_binding = context.scene.graph.try_get_mut(context.handle).unwrap();
let enemy_rigid_body = enemy_binding.cast::<RigidBody>();
let enemy_rigid_data = match enemy_rigid_body {
Some(rigid_data) => rigid_data,
None => return 0.0,
};
// TODO: if player is places abroad maps - stop activity
// if player_position.x <= END_MAP_LEFT || player_position.x >= END_MAP_RIGHT {
// return 100.0;
// }
let enemy_position = enemy_rigid_data.local_transform().position();
if player_position.y > enemy_position.y {
return DISTANCE_TO_VIEW * 2.0;
}
return player_position.x - enemy_position.x;
}
fn get_speed(&self, context: &mut ScriptContext) -> f32 {
if self.dead {
return 0.0;
}
if self.win {
return 0.0;
}
let collaider = self.intersections_player(&mut context.scene.graph, DISTANCE_TO_VIEW);
let mut see_player: bool = false;
if let Some(collaider_data) = collaider {
for i in 0..collaider_data.len() {
if collaider_data[i].toi == 0.0 {
continue;
}
if collaider_data[i].collider == self.player_collider {
see_player = true;
}
break;
}
}
if !see_player {
return 0.0;
}
let player_position = self.get_player_position(context);
let enemy_rigid_body = context.scene.graph[context.handle]
.cast_mut::<RigidBody>()
.unwrap();
if enemy_rigid_body.global_position().x <= END_MAP_LEFT {
return 0.0;
}
if enemy_rigid_body.global_position().x >= END_MAP_RIGHT {
return 0.0;
}
let mut dif_x = player_position.x - enemy_rigid_body.global_position().x;
if enemy_rigid_body.global_position().x > player_position.x {
dif_x = player_position.x - enemy_rigid_body.global_position().x;
}
if dif_x < 0.0 {
dif_x *= -1.0;
}
if player_position.y > enemy_rigid_body.global_position().y && dif_x < 1.0 {
if player_position.x > enemy_rigid_body.global_position().x {
return SPEED * -1.0;
}
if player_position.x < enemy_rigid_body.global_position().x {
return SPEED;
}
}
if enemy_rigid_body.global_position().x < END_MAP_LEFT + 3.0 {
return SPEED / 2.0;
}
if enemy_rigid_body.global_position().x > END_MAP_RIGHT - 3.0 {
return SPEED / 2.0;
}
let distance = self.distance_to_player(context);
if distance > DISTANCE_TO_VIEW {
return 0.0;
}
if distance > DISTANCE_TO_FIGHT {
return SPEED;
}
if distance < DISTANCE_TO_FIGHT * -1.0 {
return SPEED * -1.0;
}
return 0.0;
}
fn change_orientation(&self, context: &mut ScriptContext) {
let x_speed = self.get_speed(context);
if x_speed == 0.0 {
return;
}
let sprite = context.scene.graph.try_get_mut(context.handle);
match sprite {
Some(sprite_data) => {
// It is always a good practice to check whether the handles are valid, at this point we don't know
// for sure what's the value of the `sprite` field. It can be unassigned and the following code won't
// execute. A simple `context.scene.graph[self.sprite]` would just panicked in this case.
let local_transform: &mut fyrox::scene::transform::Transform =
sprite_data.local_transform_mut();
let current_scale = **local_transform.scale();
local_transform.set_scale(Vector3::new(
// Just change X scaling to mirror player's sprite.
current_scale.x.copysign(-x_speed),
current_scale.y,
current_scale.z,
));
}
None => {}
}
}
fn move_do(&mut self, context: &mut ScriptContext) {
let x_speed = self.get_speed(context);
if x_speed > 0.0 {
self.block = false;
}
let enemy_rigid_body = context.scene.graph[context.handle].cast_mut::<RigidBody>();
if let Some(enemy_rigid_data) = enemy_rigid_body {
enemy_rigid_data.set_lin_vel(Vector2::new(x_speed, -1.0));
}
}
fn animate_choose(&mut self, context: &mut ScriptContext) {
self.current_animation = Animations::Idle;
if self.win {
return;
}
if self.block {
self.current_animation = Animations::Block;
return;
}
if self.dead {
self.current_animation = Animations::Dead;
return;
}
if self.get_speed(context) != 0.0 {
self.current_animation = Animations::Run;
return;
}
if self.fight {
self.current_animation = Animations::Fight;
return;
}
}
fn set_fight(&mut self, context: &mut ScriptContext) {
if self.win {
return;
}
if self.dead {
return;
}
if self.block {
return;
}
let distance = self.distance_to_player(context);
self.fight = distance < DISTANCE_TO_FIGHT && distance > -1.0 * DISTANCE_TO_FIGHT;
if !self.fight {
self.attack_timer = 0.0;
return;
}
self.attack_timer += context.dt;
if self.attack_timer >= self.attack_speed {
self.attack_player(context);
self.attack_timer = 0.0;
return;
}
self.fight = false;
}
pub fn animation_do(&mut self, context: &mut ScriptContext) {
self.animate_choose(context);
let cur_anim = self.current_animation as usize;
let current_animation = self.animations.get_mut(cur_anim);
match current_animation {
Some(animation_data) => {
{
let graph_ctx = context.scene.graph.begin_multi_borrow();
let enemy_rigid_data = match graph_ctx.try_get(context.handle) {
Ok(rigid_body) => rigid_body,
Err(_) => return,
};
for child in enemy_rigid_data.children().iter() {
if let Ok(mut enemy) = graph_ctx.try_get_mut(*child) {
if !enemy.is_rectangle() {
continue;
}
let sprite: &mut Rectangle = enemy.cast_mut::<Rectangle>().unwrap();
animation_data.update(context.dt);
sprite
.material()
.data_ref()
.set_texture(&"diffuseTexture".into(), animation_data.texture())
.unwrap();
sprite.set_uv_rect(
animation_data.current_frame_uv_rect().unwrap_or_default(),
);
break;
}
}
}
animation_data.update(context.dt);
if let Some(sprite) = context
.scene
.graph
.try_get_mut(context.handle)
.and_then(|n| n.cast_mut::<Rectangle>())
{
sprite
.material()
.data_ref()
.set_texture(&"diffuseTexture".into(), animation_data.texture())
.unwrap();
sprite.set_uv_rect(animation_data.current_frame_uv_rect().unwrap_or_default());
}
}
None => {}
}
}
}
impl ScriptTrait for Archer {
fn on_init(&mut self, context: &mut ScriptContext) {
self.init();
// Store reference to *this* instance of the enemy node
self.handle = context.handle;
// Find the Player node
match context.scene.graph.find_by_name_from_root("Player") {
// (Handle<Node>, Node)
Some(handle) => {
// If found, store the handle
self.player_handle = handle.0;
// Find and store the Player's collider node handle
for child in handle.1.children().iter() {
self.player_collider = *child;
break;
}
}
None => {}
}
}
fn on_update(&mut self, context: &mut ScriptContext) {
if self.intersections_box(&mut context.scene.graph) {
self.dead = true
}
self.set_fight(context);
self.change_orientation(context);
self.animation_do(context);
self.move_do(context);
}
}

View File

@ -0,0 +1,2 @@
pub mod enemy;
pub mod spawn;

View File

@ -1,4 +1,4 @@
use crate::Enemy;
use crate::Archer;
use fyrox::{
asset::manager::ResourceManager,
core::{
@ -25,20 +25,20 @@ use fyrox::{
rigidbody::RigidBodyType,
transform::TransformBuilder,
},
script::{Script, ScriptContext, ScriptTrait},
script::{ScriptContext, ScriptTrait},
};
impl_component_provider!(EnemySpawn,);
uuid_provider!(EnemySpawn = "b5671d19-9f1a-4286-8486-add4ebaadaec");
impl_component_provider!(ArcherSpawn,);
uuid_provider!(ArcherSpawn = "b5671d19-9f1a-4286-8486-add4ebaadaec");
#[derive(Visit, Reflect, Debug, Clone, Default)]
pub struct EnemySpawn {
pub struct ArcherSpawn {
x: f32,
y: f32,
enemy: Enemy,
enemy: Archer,
}
impl EnemySpawn {
impl ArcherSpawn {
pub fn new() -> Self {
return EnemySpawn::default();
return ArcherSpawn::default();
}
@ -144,7 +144,7 @@ impl EnemySpawn {
pub fn spawn_enemy(&self, graph: &mut Graph, resource_manager: &ResourceManager, x: f32) {
// TODO: add with_build
let mut enemy = Enemy::default();
let mut enemy = Archer::default();
enemy.x = x;
enemy.y = -3.0;
let x = enemy.x;
@ -207,7 +207,7 @@ impl EnemySpawn {
.build(graph);
}
}
impl ScriptTrait for EnemySpawn {
impl ScriptTrait for ArcherSpawn {
fn on_init(&mut self, context: &mut ScriptContext) {
let resource_manager: &ResourceManager = &context.resource_manager;
self.spawn_enemy(&mut context.scene.graph, resource_manager, 0.0);

2
game/src/enemies/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod swordsman;
pub mod archer;

View File

@ -0,0 +1,2 @@
pub mod enemy;
pub mod spawn;

View File

@ -0,0 +1,216 @@
use crate::Swordman;
use fyrox::{
asset::manager::ResourceManager,
core::{
algebra::{Vector2, Vector3},
impl_component_provider,
math::Rect,
reflect::prelude::*,
sstorage::ImmutableString,
uuid_provider,
visitor::prelude::*,
},
generic_animation::spritesheet::{ImageParameters, SpriteSheetAnimation},
material::{shader::SamplerFallback, Material, MaterialResource, PropertyValue},
resource::texture::Texture,
scene::{
base::BaseBuilder,
collider::InteractionGroups,
dim2::{
collider::{CapsuleShape, ColliderBuilder, ColliderShape},
rectangle::RectangleBuilder,
rigidbody::RigidBodyBuilder,
},
graph::Graph,
rigidbody::RigidBodyType,
transform::TransformBuilder,
},
script::{ScriptContext, ScriptTrait},
};
impl_component_provider!(SwordmanSpawn,);
uuid_provider!(SwordmanSpawn = "b5671d19-9f1a-4286-8486-add4ebaadaec");
#[derive(Visit, Reflect, Debug, Clone, Default)]
pub struct SwordmanSpawn {
x: f32,
y: f32,
enemy: Swordman,
}
impl SwordmanSpawn {
pub fn new() -> Self {
return SwordmanSpawn::default();
}
fn block_anmation(&self, resource_manager: &ResourceManager) -> SpriteSheetAnimation<fyrox::asset::Resource<Texture>> {
let idle = resource_manager.request::<Texture>(
"assets/data/characters/skeleton/Skeleton_Warrior/Protect.png".to_owned(),
);
let mut idle_animation = SpriteSheetAnimation::new_from_image_parameters(ImageParameters {
width: 128,
height: 128,
frame_width: 128,
frame_height: 128,
first_frame: 0,
last_frame: 1,
column_major: false,
});
idle_animation.set_texture(Some(idle));
idle_animation.set_looping(false);
idle_animation.set_speed(20.);
idle_animation.play();
return idle_animation;
}
fn attack_anmation(&self, resource_manager: &ResourceManager) -> SpriteSheetAnimation<fyrox::asset::Resource<Texture>> {
let idle = resource_manager.request::<Texture>(
"assets/data/characters/skeleton/Skeleton_Warrior/Attack_3.png".to_owned(),
);
let mut idle_animation = SpriteSheetAnimation::new_from_image_parameters(ImageParameters {
width: 512,
height: 128,
frame_width: 128,
frame_height: 128,
first_frame: 0,
last_frame: 6,
column_major: false,
});
idle_animation.set_texture(Some(idle));
idle_animation.set_looping(true);
idle_animation.set_speed(20.);
idle_animation.play();
return idle_animation;
}
fn run_anmation(&self, resource_manager: &ResourceManager) -> SpriteSheetAnimation<fyrox::asset::Resource<Texture>> {
let idle = resource_manager.request::<Texture>(
"assets/data/characters/skeleton/Skeleton_Warrior/Run.png".to_owned(),
);
let mut idle_animation = SpriteSheetAnimation::new_from_image_parameters(ImageParameters {
width: 1024,
height: 128,
frame_width: 128,
frame_height: 128,
first_frame: 0,
last_frame: 8,
column_major: false,
});
idle_animation.set_texture(Some(idle));
idle_animation.set_looping(true);
idle_animation.set_speed(10.);
idle_animation.play();
return idle_animation;
}
fn die_anmation(&self, resource_manager: &ResourceManager) -> SpriteSheetAnimation<fyrox::asset::Resource<Texture>> {
let idle = resource_manager.request::<Texture>(
"assets/data/characters/skeleton/Skeleton_Warrior/Dead.png".to_owned(),
);
let mut idle_animation = SpriteSheetAnimation::new_from_image_parameters(ImageParameters {
width: 512,
height: 128,
frame_width: 128,
frame_height: 128,
first_frame: 0,
last_frame: 4,
column_major: false,
});
idle_animation.set_texture(Some(idle));
idle_animation.set_looping(false);
idle_animation.set_speed(10.);
idle_animation.play();
return idle_animation;
}
fn idle_anmation(&self, resource_manager: &ResourceManager) -> SpriteSheetAnimation<fyrox::asset::Resource<Texture>> {
let idle = resource_manager.request::<Texture>(
"assets/data/characters/skeleton/Skeleton_Warrior/Idle.png".to_owned(),
);
let mut idle_animation = SpriteSheetAnimation::new_from_image_parameters(ImageParameters {
width: 896,
height: 128,
frame_width: 128,
frame_height: 128,
first_frame: 0,
last_frame: 7,
column_major: false,
});
idle_animation.set_texture(Some(idle));
idle_animation.set_looping(true);
idle_animation.set_speed(10.);
idle_animation.play();
return idle_animation;
}
pub fn spawn_enemy(&self, graph: &mut Graph, resource_manager: &ResourceManager, x: f32) {
// TODO: add with_build
let mut enemy = Swordman::default();
enemy.x = x;
enemy.y = -3.0;
let x = enemy.x;
let y = enemy.y;
let mut material = Material::standard_2d();
enemy.animations = vec![
self.idle_anmation(resource_manager),
self.run_anmation(resource_manager),
self.attack_anmation(resource_manager),
self.die_anmation(resource_manager),
self.block_anmation(resource_manager),
];
material
.set_property(
&ImmutableString::new("diffuseTexture"),
PropertyValue::Sampler {
value: None,
fallback: SamplerFallback::Normal,
},
)
.unwrap();
let shape = ColliderShape::Capsule(CapsuleShape {
begin: Vector2::new(0.0, -0.80),
end: Vector2::new(0.0, -0.35),
radius: 0.2,
});
let rb_transform = TransformBuilder::new()
.with_local_position(Vector3::new(x, y, 0.0))
.with_local_scale(Vector3::new(2.0, 2.0, 1.0))
.build();
RigidBodyBuilder::new(
BaseBuilder::new()
.with_children(&[
// Collider to prevent player from moving past boundary
RectangleBuilder::new(BaseBuilder::new())
.with_material(MaterialResource::new_ok(Default::default(), material))
// Sprite is located in top left corner of sprite sheet
.with_uv_rect(Rect::new(0.0, 0.3, 0.13, 0.8))
.build(graph),
ColliderBuilder::new(BaseBuilder::new())
.with_shape(shape)
.with_collision_groups(InteractionGroups::default())
.with_solver_groups(InteractionGroups::default())
.build(graph),
])
// Optional, set name of tile
.with_name(format!("Sceleton ({x}, {y})",))
// Set position of tile
.with_local_transform(rb_transform)
.with_script(enemy),
)
.with_mass(20.0)
// Turn off gravity for tile
.with_gravity_scale(1.)
.with_lin_damping(0.0)
// Set tile to be static and not rotate
.with_rotation_locked(true)
.with_body_type(RigidBodyType::Dynamic)
.build(graph);
}
}
impl ScriptTrait for SwordmanSpawn {
fn on_init(&mut self, context: &mut ScriptContext) {
let resource_manager: &ResourceManager = &context.resource_manager;
self.spawn_enemy(&mut context.scene.graph, resource_manager, 0.0);
// self.enemy.on_init(context);
}
}

View File

@ -1,4 +1,5 @@
//! Game project.
use fyrox::graph::SceneGraph;
use fyrox::{
asset::manager::ResourceManager,
core::{log::Log, pool::Handle},
@ -11,18 +12,16 @@ use fyrox::{
UiNode, UserInterface,
},
plugin::{Plugin, PluginConstructor, PluginContext, PluginRegistrationContext},
scene::{graph::Graph, Scene,},
scene::{graph::Graph, Scene},
};
use fyrox::graph::SceneGraph;
use std::path::Path;
mod enemy;
mod enemy_spawn;
mod enemies;
mod map;
mod msg;
mod player;
use enemy::Enemy;
use enemy_spawn::EnemySpawn;
use enemies::swordsman::{enemy::Swordman, spawn::SwordmanSpawn};
use enemies::archer::{enemy::Archer, spawn::ArcherSpawn};
use map::build_map;
use msg::Message;
use player::Player;
@ -33,7 +32,7 @@ impl PluginConstructor for GameConstructor {
fn register(&self, context: PluginRegistrationContext) {
// Register your scripts here.
let script_constructors = &context.serialization_context.script_constructors;
script_constructors.add::<Enemy>("Enemy");
script_constructors.add::<Swordman>("Enemy");
script_constructors.add::<Player>("Player");
}
@ -47,6 +46,7 @@ pub struct Game {
new_game: Handle<UiNode>,
exit: Handle<UiNode>,
level: u32,
}
impl Game {
@ -56,7 +56,10 @@ impl Game {
|result, game: &mut Game, ctx| match result {
Ok(menu) => {
*ctx.user_interface = menu;
(game.new_game, _) = ctx.user_interface.find_by_name_from_root("NewGame").unwrap();
(game.new_game, _) = ctx
.user_interface
.find_by_name_from_root("NewGame")
.unwrap();
(game.exit, _) = ctx.user_interface.find_by_name_from_root("Exit").unwrap();
}
Err(e) => Log::err(format!("Unable to load main menu! Reason: {:?}", e)),
@ -68,6 +71,7 @@ impl Game {
scene: Handle::NONE,
new_game: Handle::NONE,
exit: Handle::NONE,
level: 1,
}
}
}
@ -113,8 +117,7 @@ impl Plugin for Game {
MessageDirection::ToWidget,
false,
));
ctx.async_scene_loader
.request("data/scene.rgs");
ctx.async_scene_loader.request("data/scene.rgs");
} else if message.destination() == self.exit {
if let Some(window_target) = ctx.window_target {
window_target.exit();
@ -148,6 +151,11 @@ impl Plugin for Game {
let graph: &mut Graph = &mut context.scenes[self.scene].graph;
let resource_manager: &ResourceManager = &context.resource_manager;
build_map(graph, resource_manager);
EnemySpawn::new().spawn_enemy(graph, resource_manager, -5.0);
if self.level == 1 {
SwordmanSpawn::new().spawn_enemy(graph, resource_manager, -5.0);
}
if self.level == 2 {
ArcherSpawn::new().spawn_enemy(graph, resource_manager, -5.0);
}
}
}

View File

@ -1,7 +1,7 @@
use std::collections::VecDeque;
use crate::msg::Message;
use crate::Enemy;
use crate::Swordman;
use fyrox::graph::BaseSceneGraph;
use fyrox::{
core::{
@ -52,6 +52,7 @@ pub struct Player {
start_fight_last: f32,
prev_y_velosity: f32,
damage: f32,
damage: f32,
pub window_height: u32, // TODO: need change place
pub window_width: u32,
@ -366,9 +367,10 @@ impl Player {
let enemy_script = context
.scene
.graph
.try_get_script_of_mut::<Enemy>(d)
.unwrap();
enemy_script.take_damage(&self.damage);
.try_get_script_of_mut::<Swordman>(d);
if let Some(enemy) = enemy_script {
enemy.take_damage(&self.damage);
}
}
}
}