diff --git a/src/entities/enemy/base.rs b/src/entities/enemy/base.rs index 83f7af2..d5c3f68 100644 --- a/src/entities/enemy/base.rs +++ b/src/entities/enemy/base.rs @@ -3,7 +3,12 @@ use raylib::prelude::*; use crate::{player::Player, resources::GlobalResources}; pub trait EnemyBase { - fn render(&mut self, context_2d: &mut RaylibMode2D, resources: &mut GlobalResources); + fn render( + &mut self, + context_2d: &mut RaylibMode2D, + resources: &mut GlobalResources, + dt: f64, + ); fn handle_logic(&mut self, player: &mut Player, dt: f64); - fn handle_getting_attacked(&mut self); -} \ No newline at end of file + fn handle_getting_attacked(&mut self, stun_duration: f64); +} diff --git a/src/entities/enemy/jellyfish.rs b/src/entities/enemy/jellyfish.rs index cf6ca10..74a79e5 100644 --- a/src/entities/enemy/jellyfish.rs +++ b/src/entities/enemy/jellyfish.rs @@ -1,5 +1,8 @@ use super::base::EnemyBase; -use crate::{player::Player, resources::GlobalResources}; +use crate::{ + lib::utils::calculate_linear_slide, pallette::TRANSLUCENT_RED_64, player::Player, + resources::GlobalResources, +}; use raylib::prelude::*; use serde::{Deserialize, Serialize}; @@ -9,6 +12,8 @@ pub struct JellyFish { #[serde(skip)] pub stunned_timer: f64, + #[serde(skip)] + pub max_stunned_time: f64, #[serde(skip)] pub do_stun_player: bool, @@ -21,31 +26,51 @@ impl EnemyBase for JellyFish { &mut self, context_2d: &mut raylib::prelude::RaylibMode2D, resources: &mut GlobalResources, + dt: f64 ) { + let is_jelly_stunned = self.stunned_timer != 0.0; + // Simple sine position - let v_trans = context_2d.get_time().sin(); + let v_trans = if is_jelly_stunned { + 0.0 + } else { + context_2d.get_time().sin() + }; + let trans_pose = Vector2 { + x: self.position.x, + y: self.position.y + (2.0 * v_trans as f32), + }; + + // Render the stun ring + if self.max_stunned_time > 0.0 && self.stunned_timer > 0.0 { + let stun_ring_radius = + calculate_linear_slide(self.stunned_timer / self.max_stunned_time); + context_2d.draw_circle_v( + trans_pose, + stun_ring_radius as f32 * 20.0, + TRANSLUCENT_RED_64, + ); + self.stunned_timer -= dt; + } // Render the jellyfish - resources.jellyfish_animation_regular.draw( - context_2d, - Vector2 { - x: self.position.x, - y: self.position.y + (2.0 * v_trans as f32), - }, - 0.0, - ); - resources.jellyfish_animation_attack.draw( - context_2d, - Vector2 { - x: self.position.x, - y: self.position.y + (2.0 * v_trans as f32), - }, - 0.0, - ); - self.do_stun_player = resources + resources + .jellyfish_animation_regular + .draw(context_2d, trans_pose, 0.0); + + // Only do stun loop if not stunned + if !is_jelly_stunned { + resources + .jellyfish_animation_attack + .draw(context_2d, trans_pose, 0.0); + } + + // Check if the jelly is in stun mode + self.do_stun_player = (resources .jellyfish_animation_attack .get_current_frame_id(context_2d) - == 13; + == 13) + && !is_jelly_stunned; } fn handle_logic(&mut self, player: &mut Player, dt: f64) { @@ -53,7 +78,9 @@ impl EnemyBase for JellyFish { if self.do_stun_player {} } - fn handle_getting_attacked(&mut self) { - todo!() + fn handle_getting_attacked(&mut self, stun_duration: f64) { + println!("Attack"); + self.stunned_timer = stun_duration; + self.max_stunned_time = stun_duration; } } diff --git a/src/items.rs b/src/items.rs index 60d99a3..90ae94d 100644 --- a/src/items.rs +++ b/src/items.rs @@ -10,13 +10,13 @@ impl StunGun { pub fn lvl1() -> Self { Self { range: 30.0, - duration: 0.5, + duration: 0.75, } } pub fn lvl2() -> Self { Self { range: 60.0, - duration: 0.75, + duration: 1.25, } } } diff --git a/src/logic/ingame/mod.rs b/src/logic/ingame/mod.rs index 469d761..f3b6cb8 100644 --- a/src/logic/ingame/mod.rs +++ b/src/logic/ingame/mod.rs @@ -3,7 +3,12 @@ mod playerlogic; use raylib::prelude::*; -use crate::{entities::enemy::base::EnemyBase, gamecore::{GameCore, GameState}, lib::wrappers::audio::player::AudioPlayer, pallette::{SKY, WATER}}; +use crate::{ + entities::enemy::base::EnemyBase, + gamecore::{GameCore, GameState}, + lib::wrappers::audio::player::AudioPlayer, + pallette::{SKY, WATER}, +}; use super::screen::Screen; @@ -64,11 +69,7 @@ impl InGameScreen { ) { // Render every collider for collider in game_core.world.colliders.iter() { - context_2d.draw_rectangle_lines_ex( - collider, - 1, - Color::RED, - ); + context_2d.draw_rectangle_lines_ex(collider, 1, Color::RED); } } } @@ -110,7 +111,7 @@ impl Screen for InGameScreen { // Render the world self.render_world(&mut context_2d, game_core); - if game_core.show_simple_debug_info{ + if game_core.show_simple_debug_info { self.render_colliders(&mut context_2d, game_core); } @@ -121,11 +122,13 @@ impl Screen for InGameScreen { fish.render(&mut context_2d); } for jellyfish in game_core.world.jellyfish.iter_mut() { - jellyfish.render(&mut context_2d, &mut game_core.resources); + jellyfish.render(&mut context_2d, &mut game_core.resources, dt); } // Render Player - game_core.player.render(&mut context_2d, &mut game_core.resources, dt); + game_core + .player + .render(&mut context_2d, &mut game_core.resources, dt); } // Render the hud diff --git a/src/pallette.rs b/src/pallette.rs index 5d675ca..b6cb182 100644 --- a/src/pallette.rs +++ b/src/pallette.rs @@ -33,4 +33,11 @@ pub const WATER: Color = Color { g: 66, b: 143, a: 255 +}; + +pub const TRANSLUCENT_RED_64: Color = Color { + r: 230, + g: 41, + b: 55, + a: 64, }; \ No newline at end of file diff --git a/src/player.rs b/src/player.rs index d2335bf..cafded3 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,6 +1,14 @@ +use crate::{ + entities::enemy::base::EnemyBase, + gamecore::{GameCore, GameProgress}, + items::{AirBag, Flashlight, Flippers, StunGun}, + lib::utils::calculate_linear_slide, + pallette::{TRANSLUCENT_WHITE_64, TRANSLUCENT_WHITE_96}, + resources::GlobalResources, + world::World, +}; use raylib::prelude::*; -use serde::{Serialize, Deserialize}; -use crate::{entities::enemy::base::EnemyBase, gamecore::{GameCore, GameProgress}, items::{AirBag, Flashlight, Flippers, StunGun}, lib::utils::{calculate_linear_slide}, pallette::{TRANSLUCENT_WHITE_64, TRANSLUCENT_WHITE_96}, resources::GlobalResources, world::World}; +use serde::{Deserialize, Serialize}; const AOE_RING_MAX_RADIUS: f32 = 60.0; const STUN_ATTACK_TIME: f64 = 0.75; @@ -10,7 +18,16 @@ pub struct PlayerInventory { pub stun_gun: Option, pub air_bag: Option, pub flashlight: Option, - pub flippers: Option + pub flippers: Option, +} + +impl PlayerInventory { + pub fn new() -> Self { + Self { + stun_gun: Some(StunGun::lvl1()), //TMP + ..Default::default() + } + } } #[derive(Debug, Default)] @@ -39,6 +56,7 @@ impl Player { is_moving: true, radius: 4.5, position: spawn.clone(), + inventory: PlayerInventory::new(), ..Default::default() } } @@ -84,12 +102,12 @@ impl Player { if self.inventory.stun_gun.is_some() && self.stun_timer == 0.0 { self.attacking_timer = self.inventory.stun_gun.as_ref().unwrap().duration; - // Stun everything in reach + // Stun everything in reach let stun_reach = self.inventory.stun_gun.as_ref().unwrap().range; for jellyfish in world.jellyfish.iter_mut() { if jellyfish.position.distance_to(self.position).abs() <= stun_reach { - jellyfish.handle_getting_attacked(); + jellyfish.handle_getting_attacked(self.attacking_timer); } } } @@ -151,7 +169,9 @@ impl Player { // Calculate AOE ring if self.is_stun_gun_active() { - let aoe_ring = calculate_linear_slide( self.attacking_timer / self.inventory.stun_gun.as_ref().unwrap().duration) as f32; + let aoe_ring = calculate_linear_slide( + self.attacking_timer / self.inventory.stun_gun.as_ref().unwrap().duration, + ) as f32; self.attacking_timer = (self.attacking_timer - dt).max(0.0); // Render attack AOE