Merge branch 'ouchies' into shop
This commit is contained in:
commit
8a174918c8
50
assets/img/character/stunned.json
Normal file
50
assets/img/character/stunned.json
Normal file
@ -0,0 +1,50 @@
|
||||
{ "frames": {
|
||||
"walk1 0.png": {
|
||||
"frame": { "x": 0, "y": 0, "w": 12, "h": 22 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 12, "h": 22 },
|
||||
"sourceSize": { "w": 12, "h": 22 },
|
||||
"duration": 200
|
||||
},
|
||||
"walk1 1.png": {
|
||||
"frame": { "x": 12, "y": 0, "w": 12, "h": 22 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 12, "h": 22 },
|
||||
"sourceSize": { "w": 12, "h": 22 },
|
||||
"duration": 200
|
||||
},
|
||||
"walk1 2.png": {
|
||||
"frame": { "x": 24, "y": 0, "w": 12, "h": 22 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 12, "h": 22 },
|
||||
"sourceSize": { "w": 12, "h": 22 },
|
||||
"duration": 200
|
||||
},
|
||||
"walk1 3.png": {
|
||||
"frame": { "x": 36, "y": 0, "w": 12, "h": 22 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 12, "h": 22 },
|
||||
"sourceSize": { "w": 12, "h": 22 },
|
||||
"duration": 200
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"app": "http://www.aseprite.org/",
|
||||
"version": "1.2.27-x64",
|
||||
"image": "stunned.png",
|
||||
"format": "RGBA8888",
|
||||
"size": { "w": 48, "h": 22 },
|
||||
"scale": "1",
|
||||
"frameTags": [
|
||||
],
|
||||
"layers": [
|
||||
{ "name": "Layer", "opacity": 255, "blendMode": "normal" }
|
||||
],
|
||||
"slices": [
|
||||
]
|
||||
}
|
||||
}
|
BIN
assets/img/character/stunned.png
Normal file
BIN
assets/img/character/stunned.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 841 B |
BIN
assets/img/enemies/jelly.aseprite
Normal file
BIN
assets/img/enemies/jelly.aseprite
Normal file
Binary file not shown.
66
assets/img/enemies/jelly.json
Normal file
66
assets/img/enemies/jelly.json
Normal file
@ -0,0 +1,66 @@
|
||||
{ "frames": {
|
||||
"Sprite-0001 0.": {
|
||||
"frame": { "x": 0, "y": 0, "w": 10, "h": 10 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 10, "h": 10 },
|
||||
"sourceSize": { "w": 10, "h": 10 },
|
||||
"duration": 300
|
||||
},
|
||||
"Sprite-0001 1.": {
|
||||
"frame": { "x": 10, "y": 0, "w": 10, "h": 10 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 10, "h": 10 },
|
||||
"sourceSize": { "w": 10, "h": 10 },
|
||||
"duration": 300
|
||||
},
|
||||
"Sprite-0001 2.": {
|
||||
"frame": { "x": 20, "y": 0, "w": 10, "h": 10 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 10, "h": 10 },
|
||||
"sourceSize": { "w": 10, "h": 10 },
|
||||
"duration": 300
|
||||
},
|
||||
"Sprite-0001 3.": {
|
||||
"frame": { "x": 30, "y": 0, "w": 10, "h": 10 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 10, "h": 10 },
|
||||
"sourceSize": { "w": 10, "h": 10 },
|
||||
"duration": 300
|
||||
},
|
||||
"Sprite-0001 4.": {
|
||||
"frame": { "x": 40, "y": 0, "w": 10, "h": 10 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 10, "h": 10 },
|
||||
"sourceSize": { "w": 10, "h": 10 },
|
||||
"duration": 300
|
||||
},
|
||||
"Sprite-0001 5.": {
|
||||
"frame": { "x": 50, "y": 0, "w": 10, "h": 10 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 10, "h": 10 },
|
||||
"sourceSize": { "w": 10, "h": 10 },
|
||||
"duration": 300
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"app": "http://www.aseprite.org/",
|
||||
"version": "1.2.27-x64",
|
||||
"image": "jelly.png",
|
||||
"format": "RGBA8888",
|
||||
"size": { "w": 60, "h": 10 },
|
||||
"scale": "1",
|
||||
"frameTags": [
|
||||
],
|
||||
"layers": [
|
||||
{ "name": "Layer 1", "opacity": 255, "blendMode": "normal" }
|
||||
],
|
||||
"slices": [
|
||||
]
|
||||
}
|
||||
}
|
BIN
assets/img/enemies/jelly.png
Normal file
BIN
assets/img/enemies/jelly.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 354 B |
138
assets/img/enemies/jellyAttack.json
Normal file
138
assets/img/enemies/jellyAttack.json
Normal file
@ -0,0 +1,138 @@
|
||||
{ "frames": {
|
||||
"jelly 0.aseprite": {
|
||||
"frame": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 1.aseprite": {
|
||||
"frame": { "x": 20, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 2.aseprite": {
|
||||
"frame": { "x": 40, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 3.aseprite": {
|
||||
"frame": { "x": 60, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 4.aseprite": {
|
||||
"frame": { "x": 80, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 5.aseprite": {
|
||||
"frame": { "x": 100, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 6.aseprite": {
|
||||
"frame": { "x": 120, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 7.aseprite": {
|
||||
"frame": { "x": 140, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 8.aseprite": {
|
||||
"frame": { "x": 160, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 9.aseprite": {
|
||||
"frame": { "x": 180, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 10.aseprite": {
|
||||
"frame": { "x": 200, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 11.aseprite": {
|
||||
"frame": { "x": 220, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 12.aseprite": {
|
||||
"frame": { "x": 240, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 13.aseprite": {
|
||||
"frame": { "x": 260, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
},
|
||||
"jelly 14.aseprite": {
|
||||
"frame": { "x": 280, "y": 0, "w": 20, "h": 20 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 20, "h": 20 },
|
||||
"sourceSize": { "w": 20, "h": 20 },
|
||||
"duration": 200
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"app": "http://www.aseprite.org/",
|
||||
"version": "1.2.27-x64",
|
||||
"image": "jellyAttack.png",
|
||||
"format": "RGBA8888",
|
||||
"size": { "w": 300, "h": 20 },
|
||||
"scale": "1",
|
||||
"frameTags": [
|
||||
],
|
||||
"layers": [
|
||||
{ "name": "Layer 3", "opacity": 255, "blendMode": "normal" }
|
||||
],
|
||||
"slices": [
|
||||
]
|
||||
}
|
||||
}
|
BIN
assets/img/enemies/jellyAttack.png
Normal file
BIN
assets/img/enemies/jellyAttack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 358 B |
92
src/entities/enemy/jellyfish.rs
Normal file
92
src/entities/enemy/jellyfish.rs
Normal file
@ -0,0 +1,92 @@
|
||||
use super::base::EnemyBase;
|
||||
use crate::{
|
||||
lib::utils::calculate_linear_slide, pallette::TRANSLUCENT_RED_64, player::Player,
|
||||
resources::GlobalResources,
|
||||
};
|
||||
use raylib::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const JELLYFISH_STUN_DURATION: f64 = 0.75;
|
||||
const JELLYFISH_STUN_REACH: f32 = 20.0;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
||||
pub struct JellyFish {
|
||||
pub position: Vector2,
|
||||
|
||||
#[serde(skip)]
|
||||
pub stunned_timer: f64,
|
||||
#[serde(skip)]
|
||||
pub max_stunned_time: f64,
|
||||
|
||||
#[serde(skip)]
|
||||
pub do_stun_player: bool,
|
||||
}
|
||||
|
||||
impl JellyFish {}
|
||||
|
||||
impl EnemyBase for JellyFish {
|
||||
fn render(
|
||||
&mut self,
|
||||
context_2d: &mut raylib::prelude::RaylibMode2D<raylib::prelude::RaylibDrawHandle>,
|
||||
resources: &mut GlobalResources,
|
||||
dt: f64,
|
||||
) {
|
||||
let is_jelly_stunned = self.stunned_timer > 0.0;
|
||||
|
||||
// Simple sine position
|
||||
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_alpha =
|
||||
calculate_linear_slide(self.stunned_timer / self.max_stunned_time);
|
||||
context_2d.draw_circle_v(
|
||||
trans_pose,
|
||||
JELLYFISH_STUN_REACH,
|
||||
TRANSLUCENT_RED_64.fade(0.55 * stun_ring_alpha as f32),
|
||||
);
|
||||
self.stunned_timer -= dt;
|
||||
}
|
||||
|
||||
// Render the jellyfish
|
||||
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)
|
||||
&& !is_jelly_stunned;
|
||||
}
|
||||
|
||||
fn handle_logic(&mut self, player: &mut Player, dt: f64) {
|
||||
// Handle stunning the player
|
||||
if self.do_stun_player {
|
||||
if self.position.distance_to(player.position).abs() <= JELLYFISH_STUN_REACH {
|
||||
player.set_stun_seconds(JELLYFISH_STUN_DURATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_getting_attacked(&mut self, stun_duration: f64) {
|
||||
self.stunned_timer = stun_duration;
|
||||
self.max_stunned_time = stun_duration;
|
||||
}
|
||||
}
|
158
src/items.rs
158
src/items.rs
@ -2,84 +2,45 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct StunGun {
|
||||
pub level: u32,
|
||||
pub cost: u32,
|
||||
pub range: f32,
|
||||
pub duration: f64,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl StunGun {
|
||||
pub fn level_up(new_level: u32) -> Self {
|
||||
pub fn lvl1() -> Self {
|
||||
Self {
|
||||
level: new_level,
|
||||
range: (new_level * 30) as f32,
|
||||
duration: new_level as f64 * 0.25,
|
||||
cost: 5 * new_level,
|
||||
name: String::from("Stun Gun"),
|
||||
range: 30.0,
|
||||
duration: 0.5,
|
||||
}
|
||||
}
|
||||
pub fn lvl2() -> Self {
|
||||
Self {
|
||||
range: 60.0,
|
||||
duration: 0.75,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct AirBag {
|
||||
pub level: u32,
|
||||
pub cost: u32,
|
||||
pub additonal_oxegen: u32,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl AirBag {
|
||||
pub fn level_up(new_level: u32) -> Self {
|
||||
Self {
|
||||
level: new_level,
|
||||
cost: new_level * 5,
|
||||
additonal_oxegen: 15 * new_level,
|
||||
name: String::from("Air Bag"),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct AirBag;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct Flashlight {
|
||||
pub level: u32,
|
||||
pub cost: u32,
|
||||
pub brightness: u32,
|
||||
pub battery_life: u32,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Flashlight {
|
||||
pub fn level_up(new_level: u32) -> Self {
|
||||
Self {
|
||||
level: new_level,
|
||||
cost: new_level * 5,
|
||||
brightness: (0.5 * new_level as f64) as u32,
|
||||
battery_life: 5 * new_level,
|
||||
name: String::from("Flash Light"),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct Flashlight;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct Flippers {
|
||||
pub level: u32,
|
||||
pub cost: u32,
|
||||
pub speed_increase: f32,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Flippers {
|
||||
pub fn level_up(new_level: u32) -> Self {
|
||||
pub fn lvl1() -> Self {
|
||||
Self {
|
||||
level: new_level,
|
||||
cost: new_level * 5,
|
||||
speed_increase: (if new_level > 1 {
|
||||
1.2 + (new_level as f32) * 0.3
|
||||
} else {
|
||||
1.2 * new_level as f32
|
||||
}),
|
||||
name: String::from("Flippers"),
|
||||
speed_increase: 1.2
|
||||
}
|
||||
}
|
||||
pub fn lvl2() -> Self {
|
||||
Self {
|
||||
speed_increase: 1.5
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,43 +51,58 @@ pub enum ShopItems {
|
||||
StunGun(u8, u8, String),
|
||||
AirBag(u8, u8, String),
|
||||
Flashlight(u8, u8, String),
|
||||
Flippers(u8, u8, String),
|
||||
Flippers(u8, u8, String)
|
||||
}
|
||||
|
||||
impl ShopItems {
|
||||
pub fn get_inital_items() -> [ShopItems; 4] {
|
||||
[
|
||||
ShopItems::StunGun(1, 10, String::from("Stun Gun")),
|
||||
ShopItems::AirBag(1, 10, String::from("Air Bag")),
|
||||
ShopItems::Flashlight(1, 12, String::from("Flash Light")),
|
||||
ShopItems::Flippers(1, 10, String::from("Flippers")),
|
||||
]
|
||||
}
|
||||
impl ShopItems{
|
||||
|
||||
pub fn get_level(item: &ShopItems) -> u8 {
|
||||
match item {
|
||||
ShopItems::StunGun(x, _, _) => *x,
|
||||
ShopItems::AirBag(x, _, _) => *x,
|
||||
ShopItems::Flashlight(x, _, _) => *x,
|
||||
ShopItems::Flippers(x, _, _) => *x,
|
||||
}
|
||||
}
|
||||
pub fn get_inital_items() -> [ShopItems; 4]{
|
||||
|
||||
[ShopItems::StunGun(1, 10, String::from("Stun Gun")), ShopItems::AirBag(1, 10, String::from("Air Bag")),
|
||||
ShopItems::Flashlight(1, 12, String::from("Flash Light")), ShopItems::Flippers(1, 10, String::from("Flippers"))]
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub fn get_level(item: &ShopItems) -> u8{
|
||||
|
||||
|
||||
match item {
|
||||
ShopItems::StunGun(x, _, _) => *x,
|
||||
ShopItems::AirBag(x, _, _) => *x,
|
||||
ShopItems::Flashlight(x, _, _) => *x,
|
||||
ShopItems::Flippers(x, _, _) => *x
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn get_cost(item: &ShopItems) -> u8{
|
||||
|
||||
match item {
|
||||
ShopItems::StunGun(x, _, _) => *x,
|
||||
ShopItems::AirBag(x, _, _) => *x,
|
||||
ShopItems::Flashlight(x, _, _) => *x,
|
||||
ShopItems::Flippers(x, _, _) => *x
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn get_name(item: &ShopItems) -> String{
|
||||
|
||||
match item {
|
||||
ShopItems::StunGun(_, _, x) => x.to_string(),
|
||||
ShopItems::AirBag(_, _, x) => x.to_string(),
|
||||
ShopItems::Flashlight(_, _, x) => x.to_string(),
|
||||
ShopItems::Flippers(_, _, x) => x.to_string()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn get_cost(item: &ShopItems) -> u8 {
|
||||
match item {
|
||||
ShopItems::StunGun(x, _, _) => *x,
|
||||
ShopItems::AirBag(x, _, _) => *x,
|
||||
ShopItems::Flashlight(x, _, _) => *x,
|
||||
ShopItems::Flippers(x, _, _) => *x,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_name(item: &ShopItems) -> String {
|
||||
match item {
|
||||
ShopItems::StunGun(_, _, x) => x.to_string(),
|
||||
ShopItems::AirBag(_, _, x) => x.to_string(),
|
||||
ShopItems::Flashlight(_, _, x) => x.to_string(),
|
||||
ShopItems::Flippers(_, _, x) => x.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user