From cf64fb485191d4ff9057c13bbb669f01d22d78de Mon Sep 17 00:00:00 2001 From: wm-c Date: Mon, 26 Apr 2021 14:02:02 -0400 Subject: [PATCH 1/4] added pufferfish mob --- assets/worlds/mainworld.json | 9 +++++++++ src/entities/enemy/mod.rs | 3 ++- src/entities/enemy/pufferfish.rs | 33 ++++++++++++++++++++++++++++++++ src/world.rs | 10 ++-------- 4 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 src/entities/enemy/pufferfish.rs diff --git a/assets/worlds/mainworld.json b/assets/worlds/mainworld.json index 9c46d40..bceb923 100644 --- a/assets/worlds/mainworld.json +++ b/assets/worlds/mainworld.json @@ -40,5 +40,14 @@ "rotation": 0 } + ], + "pufferfish": [ + { + "position" : { + "x": 400, + "y": 150 + } + } + ] } \ No newline at end of file diff --git a/src/entities/enemy/mod.rs b/src/entities/enemy/mod.rs index 18acd78..91246eb 100644 --- a/src/entities/enemy/mod.rs +++ b/src/entities/enemy/mod.rs @@ -1,4 +1,5 @@ pub mod base; pub mod jellyfish; pub mod octopus; -pub mod whirlpool; \ No newline at end of file +pub mod whirlpool; +pub mod pufferfish; \ No newline at end of file diff --git a/src/entities/enemy/pufferfish.rs b/src/entities/enemy/pufferfish.rs new file mode 100644 index 0000000..57080b3 --- /dev/null +++ b/src/entities/enemy/pufferfish.rs @@ -0,0 +1,33 @@ +use raylib::prelude::*; + +use serde::{Deserialize, Serialize}; + +use super::base::EnemyBase; + + +#[derive(Debug, Serialize, Deserialize, Default, Clone)] +pub struct Pufferfish{ + pub position: Vector2, + +} + + +impl EnemyBase for Pufferfish{ + fn render( + &mut self, + context_2d: &mut RaylibMode2D, + player: &mut crate::player::Player, + resources: &mut crate::resources::GlobalResources, + dt: f64, + ) { + context_2d.draw_circle(self.position.x as i32, self.position.y as i32, 12.0, Color::RED); + } + + fn handle_logic(&mut self, player: &mut crate::player::Player, dt: f64) { + + } + + fn handle_getting_attacked(&mut self, stun_duration: f64, current_time: f64) { + + } +} \ No newline at end of file diff --git a/src/world.rs b/src/world.rs index e1e1e00..15f592b 100644 --- a/src/world.rs +++ b/src/world.rs @@ -4,14 +4,7 @@ use failure::Error; use raylib::math::{Rectangle, Vector2}; use serde::{Deserialize, Serialize}; -use crate::{ - entities::{ - enemy::{jellyfish::JellyFish, octopus::Octopus, whirlpool::Whirlpool,}, - fish::FishEntity, - - }, - player::Player, -}; +use crate::{entities::{enemy::{jellyfish::JellyFish, octopus::Octopus, pufferfish::Pufferfish, whirlpool::Whirlpool}, fish::FishEntity}, player::Player}; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct World { @@ -31,6 +24,7 @@ pub struct World { pub jellyfish: Vec, pub octopus: Vec, pub whirlpool: Vec, + pub pufferfish: Vec } From e8a00b9907b13c0395dcd0f4372e2e1123dbabce Mon Sep 17 00:00:00 2001 From: wm-c Date: Mon, 26 Apr 2021 14:03:36 -0400 Subject: [PATCH 2/4] pufferfish handling stub --- src/logic/ingame/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/logic/ingame/mod.rs b/src/logic/ingame/mod.rs index 85bebba..7a9b9b0 100644 --- a/src/logic/ingame/mod.rs +++ b/src/logic/ingame/mod.rs @@ -253,6 +253,17 @@ impl Screen for InGameScreen { } + // Iterates over pufferfish + for pufferfish in game_core.world.pufferfish.iter_mut(){ + + pufferfish.handle_logic(&mut game_core.player, dt); + pufferfish.render(&mut context_2d, &mut game_core.player, &mut game_core.resources, dt); + + + + } + + // Removes whirlpools set for removal game_core.world.whirlpool.retain(|x| !x.should_remove()); From b7655130753dcec0a6763d40b9bc699c5e8e81e7 Mon Sep 17 00:00:00 2001 From: wm-c Date: Mon, 26 Apr 2021 16:23:33 -0400 Subject: [PATCH 3/4] Expanding pufferfish --- assets/worlds/mainworld.json | 8 ++++++- src/entities/enemy/pufferfish.rs | 37 ++++++++++++++++++++++++++++-- src/logic/ingame/playerlogic.rs | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/assets/worlds/mainworld.json b/assets/worlds/mainworld.json index bceb923..7b8a9bb 100644 --- a/assets/worlds/mainworld.json +++ b/assets/worlds/mainworld.json @@ -46,7 +46,13 @@ "position" : { "x": 400, "y": 150 - } + }, + "is_knocking_back": false, + "time_knocking_back": 0.0, + "inflate_timer": 0.0, + "size": 6.0, + "is_stunned": false + } ] diff --git a/src/entities/enemy/pufferfish.rs b/src/entities/enemy/pufferfish.rs index 57080b3..9031c1c 100644 --- a/src/entities/enemy/pufferfish.rs +++ b/src/entities/enemy/pufferfish.rs @@ -8,7 +8,12 @@ use super::base::EnemyBase; #[derive(Debug, Serialize, Deserialize, Default, Clone)] pub struct Pufferfish{ pub position: Vector2, + pub is_knocking_back: bool, + pub time_knocking_back: f64, + pub inflate_timer: f64, + pub size: f32, + pub is_stunned: bool, } @@ -20,11 +25,39 @@ impl EnemyBase for Pufferfish{ resources: &mut crate::resources::GlobalResources, dt: f64, ) { - context_2d.draw_circle(self.position.x as i32, self.position.y as i32, 12.0, Color::RED); + + + + + context_2d.draw_circle(self.position.x as i32, self.position.y as i32, self.size, Color::RED); } fn handle_logic(&mut self, player: &mut crate::player::Player, dt: f64) { - + if self.position.distance_to(player.position).abs() <= self.size + 6.0{ + self.is_knocking_back = true; + + } + + if self.is_knocking_back{ + self.time_knocking_back += dt; + } + + if self.time_knocking_back >= 0.5{ + self.is_knocking_back = false; + self.time_knocking_back = 0.0; + } + + if self.position.distance_to(player.position).abs() <= 100.0{ + self.inflate_timer += dt; + }else{ + self.inflate_timer = 0.0; + } + + self.size = (6.0 * (1.0 + self.inflate_timer / 1.0)).clamp(6.0, 12.0) as f32; + + + + } fn handle_getting_attacked(&mut self, stun_duration: f64, current_time: f64) { diff --git a/src/logic/ingame/playerlogic.rs b/src/logic/ingame/playerlogic.rs index cf9a397..4dc5172 100644 --- a/src/logic/ingame/playerlogic.rs +++ b/src/logic/ingame/playerlogic.rs @@ -202,6 +202,45 @@ pub fn update_player_movement( } + for pufferfish in game_core.world.pufferfish.iter_mut(){ + + if pufferfish.is_knocking_back{ + // Calculates info for formulas + + // Deltas between positions + let net_pose = game_core.player.position - pufferfish.position; + + // Angle between: UNITS: RADIANS + let angle = net_pose.y.atan2(net_pose.x); + + + // Calculates force + let force = 1.0 / game_core.player.position.distance_to(pufferfish.position); + + // Calculates componets of force + let mut force_x = (force as f32 * angle.cos()).clamp(-1.0, 1.0); + let mut force_y = (force as f32 * angle.sin()).clamp(-1.0, 1.0); + + // Prevents Nan erros + if force_x.is_nan(){ + force_x = 1.0 * net_pose.x; + } + + if force_y.is_nan(){ + force_y = 1.0 * net_pose.y; + } + + game_core.player.additional_vel.x += force_x; + game_core.player.additional_vel.y += force_y; + + should_apply_friction = false; + + } + + + + } + if should_apply_friction { game_core.player.additional_vel.x /= PLAYER_FRICTION; game_core.player.additional_vel.y /= PLAYER_FRICTION; From 67899182a45094ba7c5fbf1ad613077eb614748b Mon Sep 17 00:00:00 2001 From: wm-c Date: Mon, 26 Apr 2021 18:24:16 -0400 Subject: [PATCH 4/4] Pufferfish added --- assets/worlds/mainworld.json | 87 +++++++++++++++++- src/entities/enemy/pufferfish.rs | 152 ++++++++++++++++++++++++------- src/logic/ingame/playerlogic.rs | 5 +- src/player.rs | 5 + src/resources.rs | 40 ++++++++ 5 files changed, 250 insertions(+), 39 deletions(-) diff --git a/assets/worlds/mainworld.json b/assets/worlds/mainworld.json index 8cf91cf..5c86b0f 100644 --- a/assets/worlds/mainworld.json +++ b/assets/worlds/mainworld.json @@ -188,14 +188,93 @@ "pufferfish": [ { "position" : { - "x": 400, - "y": 150 + "x": 261, + "y": 387 }, "is_knocking_back": false, "time_knocking_back": 0.0, "inflate_timer": 0.0, - "size": 6.0, - "is_stunned": false + "is_large": false, + "stun_timer": 0.0, + "puffer_state": "SmallIdle" + + }, + { + "position" : { + "x": 195, + "y": 694 + }, + "is_knocking_back": false, + "time_knocking_back": 0.0, + "inflate_timer": 0.0, + "is_large": false, + "stun_timer": 0.0, + "puffer_state": "SmallIdle" + + }, + { + "position" : { + "x": 635, + "y": 731 + }, + "is_knocking_back": false, + "time_knocking_back": 0.0, + "inflate_timer": 0.0, + "is_large": false, + "stun_timer": 0.0, + "puffer_state": "SmallIdle" + + }, + { + "position" : { + "x": 169, + "y": 1104 + }, + "is_knocking_back": false, + "time_knocking_back": 0.0, + "inflate_timer": 0.0, + "is_large": false, + "stun_timer": 0.0, + "puffer_state": "SmallIdle" + + }, + { + "position" : { + "x": 478, + "y": 1333 + }, + "is_knocking_back": false, + "time_knocking_back": 0.0, + "inflate_timer": 0.0, + "is_large": false, + "stun_timer": 0.0, + "puffer_state": "SmallIdle" + + }, + { + "position" : { + "x": 499, + "y": 1775 + }, + "is_knocking_back": false, + "time_knocking_back": 0.0, + "inflate_timer": 0.0, + "is_large": false, + "stun_timer": 0.0, + "puffer_state": "SmallIdle" + + }, + { + "position" : { + "x": 74, + "y": 1259 + }, + "is_knocking_back": false, + "time_knocking_back": 0.0, + "inflate_timer": 0.0, + "is_large": false, + "stun_timer": 0.0, + "puffer_state": "SmallIdle" } diff --git a/src/entities/enemy/pufferfish.rs b/src/entities/enemy/pufferfish.rs index 9031c1c..9f72119 100644 --- a/src/entities/enemy/pufferfish.rs +++ b/src/entities/enemy/pufferfish.rs @@ -2,22 +2,31 @@ use raylib::prelude::*; use serde::{Deserialize, Serialize}; +use crate::{lib::utils::calculate_linear_slide, pallette::TRANSLUCENT_RED_64}; + use super::base::EnemyBase; - -#[derive(Debug, Serialize, Deserialize, Default, Clone)] -pub struct Pufferfish{ - pub position: Vector2, - pub is_knocking_back: bool, - pub time_knocking_back: f64, - - pub inflate_timer: f64, - pub size: f32, - pub is_stunned: bool, +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +pub enum PufferState { + SmallIdle, + Growing, + LargeIdle, + Blowing, } +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct Pufferfish { + pub position: Vector2, + pub is_knocking_back: bool, + pub time_knocking_back: f64, -impl EnemyBase for Pufferfish{ + pub inflate_timer: f64, + pub is_large: bool, + pub stun_timer: f64, + pub puffer_state: PufferState, +} + +impl EnemyBase for Pufferfish { fn render( &mut self, context_2d: &mut RaylibMode2D, @@ -25,42 +34,121 @@ impl EnemyBase for Pufferfish{ resources: &mut crate::resources::GlobalResources, dt: f64, ) { - + + let is_stunned = self.stun_timer > 0.0; + + // Render the stun ring + if is_stunned { + println!("Stunned"); + let stun_ring_alpha = + calculate_linear_slide(self.stun_timer / 1.0); + context_2d.draw_circle_v( + self.position, + 12.0, + TRANSLUCENT_RED_64.fade(0.55 * stun_ring_alpha as f32), + ); + + self.stun_timer -= dt; + } + + + let angle = player.position.angle_to(self.position).to_degrees(); + match self.puffer_state { + PufferState::SmallIdle => { + resources.pufferfish_small.draw( + context_2d, + Vector2 { + x: self.position.x, + y: self.position.y, + }, + angle, + ); - context_2d.draw_circle(self.position.x as i32, self.position.y as i32, self.size, Color::RED); + if self.position.distance_to(player.position).abs() <= 100.0 && self.inflate_timer > 1.0{ + self.puffer_state = PufferState::Growing; + } + self.is_large = false; + }, + PufferState::Growing => { + self.inflate_timer = 0.0; + resources.pufferfish_expand.draw( + context_2d, + Vector2 { + x: self.position.x, + y: self.position.y, + }, + angle, + ); + + if resources.pufferfish_expand.get_current_frame_id(context_2d) == 3 { + self.puffer_state = PufferState::LargeIdle; + } + self.is_large = true; + + }, + PufferState::LargeIdle => { + self.inflate_timer = 0.0; + resources.pufferfish_big.draw( + context_2d, + Vector2 { + x: self.position.x, + y: self.position.y, + }, + angle, + ); + + if self.position.distance_to(player.position).abs() <= 65.0{ + self.puffer_state = PufferState::Blowing; + self.is_knocking_back = true; + self.time_knocking_back = 0.0; + } + + self.is_large = true; + }, + PufferState::Blowing => { + + resources.pufferfish_attack.draw( + context_2d, + Vector2 { + x: self.position.x, + y: self.position.y, + }, + angle, + ); + + + if resources.pufferfish_expand.get_current_frame_id(context_2d) == 3 && self.inflate_timer > 1.0{ + self.puffer_state = PufferState::SmallIdle; + self.inflate_timer = 0.0; + } + self.is_large = false; + }, + } } fn handle_logic(&mut self, player: &mut crate::player::Player, dt: f64) { - if self.position.distance_to(player.position).abs() <= self.size + 6.0{ - self.is_knocking_back = true; - - } - if self.is_knocking_back{ - self.time_knocking_back += dt; - } + + + self.inflate_timer += dt; + self.time_knocking_back += dt; if self.time_knocking_back >= 0.5{ self.is_knocking_back = false; - self.time_knocking_back = 0.0; } - if self.position.distance_to(player.position).abs() <= 100.0{ - self.inflate_timer += dt; - }else{ + if self.position.distance_to(player.position).abs() > 120.0 && self.is_large { + self.puffer_state = PufferState::Blowing; self.inflate_timer = 0.0; } - self.size = (6.0 * (1.0 + self.inflate_timer / 1.0)).clamp(6.0, 12.0) as f32; - - - - } fn handle_getting_attacked(&mut self, stun_duration: f64, current_time: f64) { - - } -} \ No newline at end of file + + self.stun_timer = stun_duration; + + } +} diff --git a/src/logic/ingame/playerlogic.rs b/src/logic/ingame/playerlogic.rs index 84ca05b..108b829 100644 --- a/src/logic/ingame/playerlogic.rs +++ b/src/logic/ingame/playerlogic.rs @@ -80,7 +80,7 @@ pub fn update_player_movement( game_core .player .begin_attack(&mut game_core.world, draw_handle.get_time()); - println!("{{\"x\":{}, \"y\":{}}},",f32::round(game_core.player.position.x),f32::round(game_core.player.position.y)); + //println!("{{\"x\":{}, \"y\":{}}},",f32::round(game_core.player.position.x),f32::round(game_core.player.position.y)); } // Move the player in their direction @@ -214,9 +214,8 @@ pub fn update_player_movement( // Angle between: UNITS: RADIANS let angle = net_pose.y.atan2(net_pose.x); - // Calculates force - let force = 1.0 / game_core.player.position.distance_to(pufferfish.position); + let force = 1.0; // Calculates componets of force let mut force_x = (force as f32 * angle.cos()).clamp(-1.0, 1.0); diff --git a/src/player.rs b/src/player.rs index b11b086..c173602 100644 --- a/src/player.rs +++ b/src/player.rs @@ -103,6 +103,11 @@ impl Player { if whirlpool.position.distance_to(self.position).abs() <= stun_reach { whirlpool.handle_getting_attacked(self.attacking_timer, current_time); } + } + for pufferfish in world.pufferfish.iter_mut() { + if pufferfish.position.distance_to(self.position).abs() <= stun_reach { + pufferfish.handle_getting_attacked(self.attacking_timer, current_time); + } } } } diff --git a/src/resources.rs b/src/resources.rs index 35b16ac..b890fd8 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -33,6 +33,10 @@ pub struct GlobalResources { pub octopus_animation_regular: FrameAnimationWrapper, pub octopus_animation_attack: FrameAnimationWrapper, pub whirlpool: FrameAnimationWrapper, + pub pufferfish_big: FrameAnimationWrapper, + pub pufferfish_small: FrameAnimationWrapper, + pub pufferfish_attack: FrameAnimationWrapper, + pub pufferfish_expand: FrameAnimationWrapper, // Darkness layer pub darkness_overlay: Texture2D, @@ -257,6 +261,42 @@ impl GlobalResources { 4, 4, ), + pufferfish_big: FrameAnimationWrapper::new( + raylib.load_texture_from_image( + &thread, + &Image::load_image("./assets/img/enemies/pufferFishBigIdle.png")?, + )?, + Vector2 { x: 19.0, y: 19.0 }, + 3, + 2, + ), + pufferfish_small: FrameAnimationWrapper::new( + raylib.load_texture_from_image( + &thread, + &Image::load_image("./assets/img/enemies/pufferFishIdle.png")?, + )?, + Vector2 { x: 19.0, y: 19.0 }, + 6, + 2, + ), + pufferfish_attack: FrameAnimationWrapper::new( + raylib.load_texture_from_image( + &thread, + &Image::load_image("./assets/img/enemies/pufferFishAttack.png")?, + )?, + Vector2 { x: 39.0, y: 25.0 }, + 4, + 2, + ), + pufferfish_expand: FrameAnimationWrapper::new( + raylib.load_texture_from_image( + &thread, + &Image::load_image("./assets/img/enemies/pufferFishExpand.png")?, + )?, + Vector2 { x: 19.0, y: 19.0 }, + 4, + 2, + ), }) } }