enemy can take damage

This commit is contained in:
artem 2024-02-21 09:18:34 +03:00
parent 6ef12b6332
commit 85d4e5c658
3 changed files with 98 additions and 25 deletions

View File

@ -33,6 +33,7 @@ enum Animations {
Run = 1,
Fight = 2,
Dead = 3,
Block = 4,
}
const DISTANCE_TO_FIGHT: f32 = 0.5;
@ -50,6 +51,7 @@ pub struct Enemy {
fight: bool,
win: bool,
dead: bool,
block: bool,
#[reflect(hidden)]
#[visit(skip)]
@ -75,6 +77,10 @@ impl Enemy {
return a.round() as i32;
}
pub fn take_damage(&mut self, _damage: &f32) {
self.block = true;
}
fn intersections_box(&self, graph: &mut Graph) -> bool {
let self_node = match graph.try_get(self.handle) {
Some(node) => node,
@ -175,9 +181,11 @@ impl Enemy {
Some(script) => {
if script.get_health() <= 0.0 {
self.fight = false;
self.block = false;
self.win = true;
break;
}
self.block = false;
script.take_damage(&self.attack_damage);
}
None => {}
@ -284,6 +292,9 @@ impl Enemy {
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, enemy_rigid_data.lin_vel().y));
@ -292,14 +303,21 @@ impl Enemy {
fn animate_choose(&mut self, context: &mut ScriptContext) {
self.current_animation = Animations::Idle;
if self.get_speed(context) != 0.0 {
self.current_animation = Animations::Run;
if self.block {
self.current_animation = Animations::Block;
return;
}
if self.fight {
self.current_animation = Animations::Fight;
return;
}
if self.dead {
self.current_animation = Animations::Dead;
return;
}
if self.get_speed(context) != 0.0 {
self.current_animation = Animations::Run;
return;
}
}
@ -310,6 +328,9 @@ impl Enemy {
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 {

View File

@ -41,6 +41,27 @@ impl EnemySpawn {
return EnemySpawn::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(),
@ -134,6 +155,7 @@ impl EnemySpawn {
self.run_anmation(resource_manager),
self.attack_anmation(resource_manager),
self.die_anmation(resource_manager),
self.block_anmation(resource_manager),
];
material
.set_property(
@ -146,7 +168,7 @@ impl EnemySpawn {
.unwrap();
let shape = ColliderShape::Capsule(CapsuleShape {
begin: Vector2::new(0.0, -0.80),
end: Vector2::new(0.0, -0.40),
end: Vector2::new(0.0, -0.35),
radius: 0.2,
});
let rb_transform = TransformBuilder::new()

View File

@ -2,7 +2,7 @@ use std::collections::VecDeque;
use fyrox::{
core::{
algebra::{Vector2, Vector3},
algebra::{Vector2, Vector3, Point2},
color::Color,
impl_component_provider,
log::Log,
@ -14,9 +14,11 @@ use fyrox::{
event::{ElementState, Event, TouchPhase, WindowEvent},
keyboard::{KeyCode, PhysicalKey},
scene::{
collider::InteractionGroups,
animation::spritesheet::SpriteSheetAnimation,
base::BaseBuilder,
dim2::{
physics::{Intersection, RayCastOptions},
rectangle::{Rectangle, RectangleBuilder},
rigidbody::RigidBody,
},
@ -26,6 +28,7 @@ use fyrox::{
script::{ScriptContext, ScriptTrait, ScriptMessageContext, ScriptMessagePayload},
};
use crate::msg::Message;
use crate::Enemy;
#[derive(Visit, Reflect, Debug, Clone, Default)]
pub struct Player {
@ -43,6 +46,7 @@ pub struct Player {
start_y_position: f32,
start_fight_last: f32,
prev_y_velosity: f32,
damage: f32,
pub window_height: u32, // TODO: need change place
pub window_width: u32,
@ -180,9 +184,6 @@ impl Player {
KeyCode::ArrowRight => self.move_right = is_pressed,
KeyCode::ArrowUp => self.jump = is_pressed,
KeyCode::Space => {
// if (context.elapsed_time - self.start_fight_last) > 0.3 {
// self.fight = false;
// }
if !is_pressed {
self.fight = false;
self.start_fight_last = 0.0;
@ -195,23 +196,6 @@ impl Player {
}
self.start_fight_last = context.elapsed_time;
self.fight = is_pressed;
// if self.fight && is_pressed {
// self.fight = false;
// return;
// }
// // if self.fight && !is_pressed {
// // self.start_fight_last = context.elapsed_time;
// // self.fight = false;
// // return;
// // }
// // if !self.fight && !is_pressed {
// // self.fight = false;
// // return;
// // }
// if !self.fight && is_pressed {
// self.fight = true;
// return;
// }
}
_ => (),
}
@ -330,6 +314,52 @@ impl Player {
None => self.current_animation.push_front(animation as u32),
}
}
fn attack_enemy(&self, context: &mut ScriptContext) {
if !self.fight {
return;
}
let self_node = match context.scene.graph.try_get(context.handle) {
Some(node) => node,
None => return,
};
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();
context.scene.graph.physics2d.cast_ray(
RayCastOptions {
ray_origin: Point2::new(self_position.x, self_position.y),
ray_direction: Vector2::new(-1.0, 0.0),
max_len: 1.0,
groups: InteractionGroups::default(),
// groups: InteractionGroups::default(),
// Sort the results by distance
sort_results: true,
},
// Store the collisions in the vector
&mut buffer,
);
if buffer.len() == 0 {
return ;
}
for i in 0..buffer.len() {
if buffer[i].toi == 0.0 {
continue;
}
if let Some(d) = context.scene.graph.try_get(buffer[i].collider) {
match context.scene.graph.try_get_script_of_mut::<Enemy>(d.parent()) {
Some(script) => {
script.take_damage(&self.damage);
break;
}
None => {}
}
}
}
}
fn animate_choose(&mut self, context: &mut ScriptContext) {
if self.health <= 0.0 {
return;
@ -510,7 +540,7 @@ impl ScriptTrait for Player {
self.change_orientation(context);
self.animation_do(context);
self.update_health(context);
self.attack_enemy(context);
self.loop_over(context);
}
}