commit
c207966b75
BIN
assets/img/map/fish.aseprite
Normal file
BIN
assets/img/map/fish.aseprite
Normal file
Binary file not shown.
26
assets/img/map/fish.json
Normal file
26
assets/img/map/fish.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{ "frames": {
|
||||||
|
"fish 62.aseprite": {
|
||||||
|
"frame": { "x": 806, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 50
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"app": "http://www.aseprite.org/",
|
||||||
|
"version": "1.2.27-x64",
|
||||||
|
"image": "fish.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": { "w": 819, "h": 9 },
|
||||||
|
"scale": "1",
|
||||||
|
"frameTags": [
|
||||||
|
],
|
||||||
|
"layers": [
|
||||||
|
{ "name": "Layer 1", "opacity": 255, "blendMode": "normal" }
|
||||||
|
],
|
||||||
|
"slices": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
BIN
assets/img/map/fish.png
Normal file
BIN
assets/img/map/fish.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
BIN
assets/img/map/fishIdle.aseprite
Normal file
BIN
assets/img/map/fishIdle.aseprite
Normal file
Binary file not shown.
130
assets/img/map/fishStill.json
Normal file
130
assets/img/map/fishStill.json
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
{ "frames": {
|
||||||
|
"fishIdle 0.aseprite": {
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 1.aseprite": {
|
||||||
|
"frame": { "x": 13, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 2.aseprite": {
|
||||||
|
"frame": { "x": 26, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 3.aseprite": {
|
||||||
|
"frame": { "x": 39, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 4.aseprite": {
|
||||||
|
"frame": { "x": 52, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 5.aseprite": {
|
||||||
|
"frame": { "x": 65, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 6.aseprite": {
|
||||||
|
"frame": { "x": 78, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 7.aseprite": {
|
||||||
|
"frame": { "x": 91, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 8.aseprite": {
|
||||||
|
"frame": { "x": 104, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 9.aseprite": {
|
||||||
|
"frame": { "x": 117, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 10.aseprite": {
|
||||||
|
"frame": { "x": 130, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 11.aseprite": {
|
||||||
|
"frame": { "x": 143, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 12.aseprite": {
|
||||||
|
"frame": { "x": 156, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
"fishIdle 13.aseprite": {
|
||||||
|
"frame": { "x": 169, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 13, "h": 9 },
|
||||||
|
"sourceSize": { "w": 13, "h": 9 },
|
||||||
|
"duration": 100
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"app": "http://www.aseprite.org/",
|
||||||
|
"version": "1.2.27-x64",
|
||||||
|
"image": "fishIdle.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": { "w": 182, "h": 9 },
|
||||||
|
"scale": "1",
|
||||||
|
"frameTags": [
|
||||||
|
],
|
||||||
|
"layers": [
|
||||||
|
{ "name": "Layer 1", "opacity": 255, "blendMode": "normal" }
|
||||||
|
],
|
||||||
|
"slices": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
BIN
assets/img/map/fishStill.png
Normal file
BIN
assets/img/map/fishStill.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
@ -2,7 +2,11 @@ use rand::{prelude::ThreadRng, Rng};
|
|||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gamecore::GameCore, lib::utils::triangles::rotate_vector, player::Player, world::World,
|
gamecore::{self, GameCore},
|
||||||
|
lib::utils::triangles::rotate_vector,
|
||||||
|
player::Player,
|
||||||
|
resources::GlobalResources,
|
||||||
|
world::World,
|
||||||
};
|
};
|
||||||
|
|
||||||
const FISH_FOLLOW_PLAYER_DISTANCE: f32 = 30.0;
|
const FISH_FOLLOW_PLAYER_DISTANCE: f32 = 30.0;
|
||||||
@ -25,9 +29,11 @@ pub struct FishEntity {
|
|||||||
direction: Vector2,
|
direction: Vector2,
|
||||||
velocity: Vector2,
|
velocity: Vector2,
|
||||||
pub following_player: bool,
|
pub following_player: bool,
|
||||||
|
current_frame: u8,
|
||||||
|
animation_counter: u32,
|
||||||
size: Vector2,
|
size: Vector2,
|
||||||
|
color: u8,
|
||||||
rng: ThreadRng,
|
rng: ThreadRng,
|
||||||
color: Color,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FishEntity {
|
impl FishEntity {
|
||||||
@ -35,16 +41,16 @@ impl FishEntity {
|
|||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
Self {
|
Self {
|
||||||
position: position,
|
position: position,
|
||||||
direction: Vector2::zero(),
|
direction: Vector2 {
|
||||||
|
x: rng.gen_range(0.0..1.0),
|
||||||
|
y: rng.gen_range(0.0..1.0),
|
||||||
|
},
|
||||||
velocity: Vector2::zero(),
|
velocity: Vector2::zero(),
|
||||||
following_player: false,
|
following_player: false,
|
||||||
|
animation_counter: 0,
|
||||||
|
current_frame: 0,
|
||||||
size: Vector2 { x: 5.0, y: 8.0 },
|
size: Vector2 { x: 5.0, y: 8.0 },
|
||||||
color: Color {
|
color: rng.gen_range(0..6),
|
||||||
r: rng.gen_range(128..225),
|
|
||||||
g: rng.gen_range(128..225),
|
|
||||||
b: rng.gen_range(128..225),
|
|
||||||
a: 140,
|
|
||||||
},
|
|
||||||
rng,
|
rng,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,21 +144,17 @@ impl FishEntity {
|
|||||||
// Distance and direction to player
|
// Distance and direction to player
|
||||||
let dist_to_player = player.position - self.position;
|
let dist_to_player = player.position - self.position;
|
||||||
let dist_to_player_lin = self.position.distance_to(player.position);
|
let dist_to_player_lin = self.position.distance_to(player.position);
|
||||||
let mut direction_to_player = dist_to_player;
|
|
||||||
direction_to_player.normalize();
|
|
||||||
|
|
||||||
// Handle player picking up fish
|
// Handle player picking up fish
|
||||||
if player.position.distance_to(self.position).abs() <= player.size.y * 2.2 {
|
if player.position.distance_to(self.position).abs() <= player.size.y * 2.2 {
|
||||||
self.following_player = true;
|
self.following_player = true;
|
||||||
self.velocity = self.direction.normalized();
|
self.velocity = self.direction.normalized();
|
||||||
|
self.current_frame = 0;
|
||||||
|
self.animation_counter = 0;
|
||||||
|
|
||||||
// Add currency to the player
|
// Add currency to the player
|
||||||
player.coins += 1;
|
player.coins += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look at the player;
|
|
||||||
self.position = self.position;
|
|
||||||
self.direction = direction_to_player;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_position(&mut self, player: &mut Player, dt: f64, other_fish: &Vec<FishEntity>) {
|
pub fn update_position(&mut self, player: &mut Player, dt: f64, other_fish: &Vec<FishEntity>) {
|
||||||
@ -163,40 +165,45 @@ impl FishEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, context_2d: &mut RaylibMode2D<RaylibDrawHandle>) {
|
pub fn render(
|
||||||
|
&mut self,
|
||||||
|
context_2d: &mut RaylibMode2D<RaylibDrawHandle>,
|
||||||
|
resources: &mut GlobalResources,
|
||||||
|
) {
|
||||||
// Direction
|
// Direction
|
||||||
let direction =
|
let direction = (Vector2::zero().angle_to(self.direction.normalized())).to_degrees();
|
||||||
Vector2::zero().angle_to(self.direction.normalized()) + (90.0 as f32).to_radians();
|
|
||||||
|
|
||||||
// Get the corners of the fish
|
self.animation_counter += 1;
|
||||||
let fish_front = rotate_vector(
|
|
||||||
Vector2 {
|
|
||||||
x: 0.0,
|
|
||||||
y: (self.size.y / 2.0) * -1.0,
|
|
||||||
},
|
|
||||||
direction,
|
|
||||||
);
|
|
||||||
let fish_bl = rotate_vector(
|
|
||||||
Vector2 {
|
|
||||||
x: (self.size.x / 2.0) * -1.0,
|
|
||||||
y: (self.size.y / 2.0),
|
|
||||||
},
|
|
||||||
direction,
|
|
||||||
);
|
|
||||||
let fish_br = rotate_vector(
|
|
||||||
Vector2 {
|
|
||||||
x: (self.size.x / 2.0),
|
|
||||||
y: (self.size.y / 2.0),
|
|
||||||
},
|
|
||||||
direction,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Draw the fish as a triangle with rotation
|
// swimming
|
||||||
context_2d.draw_triangle(
|
if self.following_player {
|
||||||
self.position + fish_front,
|
if self.animation_counter % 3 == 0 {
|
||||||
self.position + fish_bl,
|
self.current_frame += 1;
|
||||||
self.position + fish_br,
|
if self.current_frame == 8 {
|
||||||
self.color,
|
self.current_frame = 0;
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
resources.fish_animation_swim.draw_frame(
|
||||||
|
context_2d,
|
||||||
|
self.position,
|
||||||
|
direction,
|
||||||
|
(self.current_frame + self.color * 9) as u32,
|
||||||
|
);
|
||||||
|
// idle
|
||||||
|
} else {
|
||||||
|
if self.animation_counter % 10 == 0 {
|
||||||
|
if self.current_frame == 0 {
|
||||||
|
self.current_frame = 1;
|
||||||
|
} else {
|
||||||
|
self.current_frame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resources.fish_animation_idle.draw_frame(
|
||||||
|
context_2d,
|
||||||
|
self.position,
|
||||||
|
direction,
|
||||||
|
(self.current_frame + self.color * 2) as u32,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ impl InGameScreen {
|
|||||||
let fish_clone = game_core.world.fish.clone();
|
let fish_clone = game_core.world.fish.clone();
|
||||||
for fish in game_core.world.fish.iter_mut() {
|
for fish in game_core.world.fish.iter_mut() {
|
||||||
fish.update_position(&mut game_core.player, dt, &fish_clone);
|
fish.update_position(&mut game_core.player, dt, &fish_clone);
|
||||||
fish.render(context_2d);
|
fish.render(context_2d, &mut game_core.resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the world texture
|
// Render the world texture
|
||||||
|
@ -17,6 +17,10 @@ pub struct GlobalResources {
|
|||||||
pub player_animation_boost_charge: FrameAnimationWrapper,
|
pub player_animation_boost_charge: FrameAnimationWrapper,
|
||||||
pub player_animation_boost: FrameAnimationWrapper,
|
pub player_animation_boost: FrameAnimationWrapper,
|
||||||
pub player_animation_stunned: FrameAnimationWrapper,
|
pub player_animation_stunned: FrameAnimationWrapper,
|
||||||
|
|
||||||
|
// Fish
|
||||||
|
pub fish_animation_idle: FrameAnimationWrapper,
|
||||||
|
pub fish_animation_swim: FrameAnimationWrapper,
|
||||||
|
|
||||||
// Cave
|
// Cave
|
||||||
pub cave_mid_layer: Texture2D,
|
pub cave_mid_layer: Texture2D,
|
||||||
@ -80,6 +84,24 @@ impl GlobalResources {
|
|||||||
4,
|
4,
|
||||||
100 / 8,
|
100 / 8,
|
||||||
),
|
),
|
||||||
|
fish_animation_idle: FrameAnimationWrapper::new(
|
||||||
|
raylib.load_texture_from_image(
|
||||||
|
&thread,
|
||||||
|
&Image::load_image("./assets/img/map/fishStill.png")?,
|
||||||
|
)?,
|
||||||
|
Vector2 { x: 13.0, y: 9.0 },
|
||||||
|
14,
|
||||||
|
30,
|
||||||
|
),
|
||||||
|
fish_animation_swim: FrameAnimationWrapper::new(
|
||||||
|
raylib.load_texture_from_image(
|
||||||
|
&thread,
|
||||||
|
&Image::load_image("./assets/img/map/fish.png")?,
|
||||||
|
)?,
|
||||||
|
Vector2 { x: 13.0, y: 9.0 },
|
||||||
|
63,
|
||||||
|
30,
|
||||||
|
),
|
||||||
cave_mid_layer: raylib.load_texture_from_image(
|
cave_mid_layer: raylib.load_texture_from_image(
|
||||||
&thread,
|
&thread,
|
||||||
&Image::load_image("./assets/img/map/cave.png")?,
|
&Image::load_image("./assets/img/map/cave.png")?,
|
||||||
|
Reference in New Issue
Block a user