Merge branch 'master' into assets
This commit is contained in:
commit
53a746c551
@ -13,9 +13,4 @@ serialstudio = "0.1.0"
|
|||||||
serde = "1.0.125"
|
serde = "1.0.125"
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
failure = "0.1.8"
|
failure = "0.1.8"
|
||||||
parry2d = "0.4.0"
|
|
||||||
log = "0.4.14"
|
|
||||||
env_logger = "0.8.3"
|
|
||||||
nalgebra = "0.26.1"
|
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
tiled = "0.9.4"
|
|
||||||
|
@ -29,5 +29,16 @@
|
|||||||
"y": 100
|
"y": 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"whirlpool": [
|
||||||
|
{
|
||||||
|
"position" : {
|
||||||
|
"x": 250,
|
||||||
|
"y": 250
|
||||||
|
},
|
||||||
|
"should_remove": false,
|
||||||
|
"rotation": 0
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
}
|
}
|
@ -28,7 +28,7 @@ impl EnemyBase for JellyFish {
|
|||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
context_2d: &mut raylib::prelude::RaylibMode2D<raylib::prelude::RaylibDrawHandle>,
|
context_2d: &mut raylib::prelude::RaylibMode2D<raylib::prelude::RaylibDrawHandle>,
|
||||||
player: &mut Player,
|
_player: &mut Player,
|
||||||
resources: &mut GlobalResources,
|
resources: &mut GlobalResources,
|
||||||
dt: f64,
|
dt: f64,
|
||||||
) {
|
) {
|
||||||
@ -77,7 +77,7 @@ impl EnemyBase for JellyFish {
|
|||||||
&& !is_jelly_stunned;
|
&& !is_jelly_stunned;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_logic(&mut self, player: &mut Player, dt: f64) {
|
fn handle_logic(&mut self, player: &mut Player, _dt: f64) {
|
||||||
// Handle stunning the player
|
// Handle stunning the player
|
||||||
if self.do_stun_player {
|
if self.do_stun_player {
|
||||||
if self.position.distance_to(player.position).abs() <= JELLYFISH_STUN_REACH {
|
if self.position.distance_to(player.position).abs() <= JELLYFISH_STUN_REACH {
|
||||||
@ -86,7 +86,7 @@ impl EnemyBase for JellyFish {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_getting_attacked(&mut self, stun_duration: f64, current_time: f64) {
|
fn handle_getting_attacked(&mut self, stun_duration: f64, _current_time: f64) {
|
||||||
self.stunned_timer = stun_duration;
|
self.stunned_timer = stun_duration;
|
||||||
self.max_stunned_time = stun_duration;
|
self.max_stunned_time = stun_duration;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
pub mod base;
|
pub mod base;
|
||||||
pub mod jellyfish;
|
pub mod jellyfish;
|
||||||
pub mod octopus;
|
pub mod octopus;
|
||||||
|
pub mod whirlpool;
|
@ -1,11 +1,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
lib::utils::calculate_linear_slide,
|
lib::utils::calculate_linear_slide,
|
||||||
pallette::{TRANSLUCENT_RED_64, TRANSLUCENT_WHITE_128, TRANSLUCENT_WHITE_64},
|
pallette::{TRANSLUCENT_RED_64, TRANSLUCENT_WHITE_128},
|
||||||
player::Player,
|
player::Player,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::base::EnemyBase;
|
use super::base::EnemyBase;
|
||||||
use rand::{prelude::ThreadRng, Rng};
|
use rand::Rng;
|
||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -13,7 +13,6 @@ const OCTOPUS_SUCK_AIR_DELAY: f64 = 3.5;
|
|||||||
const OCTOPUS_SUCK_AIR_RANGE: f32 = 70.0;
|
const OCTOPUS_SUCK_AIR_RANGE: f32 = 70.0;
|
||||||
const OCTOPUS_SUCK_AIR_DURATION: f64 = 1.0;
|
const OCTOPUS_SUCK_AIR_DURATION: f64 = 1.0;
|
||||||
const OCTOPUS_SUCK_AIR_AMOUNT: f32 = 0.1;
|
const OCTOPUS_SUCK_AIR_AMOUNT: f32 = 0.1;
|
||||||
// const RNG: ThreadRng = rand::thread_rng();
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
||||||
struct OctopusAirBubble {
|
struct OctopusAirBubble {
|
||||||
@ -124,7 +123,7 @@ impl EnemyBase for Octopus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_logic(&mut self, player: &mut crate::player::Player, dt: f64) {
|
fn handle_logic(&mut self, player: &mut crate::player::Player, _dt: f64) {
|
||||||
if self.suck_air_time_remaining > 0.0 && !self.has_taken_air_from_player {
|
if self.suck_air_time_remaining > 0.0 && !self.has_taken_air_from_player {
|
||||||
if player.position.distance_to(self.current_position).abs() <= OCTOPUS_SUCK_AIR_RANGE {
|
if player.position.distance_to(self.current_position).abs() <= OCTOPUS_SUCK_AIR_RANGE {
|
||||||
// Take air from the player
|
// Take air from the player
|
||||||
@ -136,7 +135,7 @@ impl EnemyBase for Octopus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_getting_attacked(&mut self, stun_duration: f64, current_time: f64) {
|
fn handle_getting_attacked(&mut self, stun_duration: f64, _current_time: f64) {
|
||||||
self.stunned_timer = stun_duration;
|
self.stunned_timer = stun_duration;
|
||||||
self.max_stunned_time = stun_duration;
|
self.max_stunned_time = stun_duration;
|
||||||
}
|
}
|
||||||
|
52
src/entities/enemy/whirlpool.rs
Normal file
52
src/entities/enemy/whirlpool.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
use raylib::prelude::*;
|
||||||
|
|
||||||
|
use super::base::EnemyBase;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
||||||
|
pub struct Whirlpool{
|
||||||
|
pub position: Vector2,
|
||||||
|
|
||||||
|
// Track if it needs removing
|
||||||
|
pub should_remove: bool,
|
||||||
|
|
||||||
|
// variable for tracking rotation
|
||||||
|
pub rotation: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Whirlpool{
|
||||||
|
|
||||||
|
// hook to see if item needs removing
|
||||||
|
pub fn should_remove(&self) -> bool{
|
||||||
|
return self.should_remove;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EnemyBase for Whirlpool{
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
context_2d: &mut RaylibMode2D<RaylibDrawHandle>,
|
||||||
|
player: &mut crate::player::Player,
|
||||||
|
resources: &mut crate::resources::GlobalResources,
|
||||||
|
dt: f64,
|
||||||
|
) {
|
||||||
|
|
||||||
|
resources.whirlpool.draw(context_2d, Vector2{x: self.position.x, y: self.position.y}, self.rotation);
|
||||||
|
self.rotation += 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_logic(&mut self, player: &mut crate::player::Player, dt: f64) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whirlpool removed if shoot
|
||||||
|
fn handle_getting_attacked(&mut self, stun_duration: f64, current_time: f64) {
|
||||||
|
self.should_remove = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,18 +1,7 @@
|
|||||||
use rand::{prelude::ThreadRng, Rng};
|
use rand::{prelude::ThreadRng, Rng};
|
||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{player::Player, resources::GlobalResources};
|
||||||
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_SPEED: f32 = 1.8;
|
|
||||||
const FISH_FOLLOW_PLAYER_SPEED_FAST: f32 = FISH_FOLLOW_PLAYER_SPEED * 3.0;
|
|
||||||
const FISH_ATTACH_RADIUS: f32 = 20.0;
|
|
||||||
|
|
||||||
const FISH_VISION: f32 = 25.0;
|
const FISH_VISION: f32 = 25.0;
|
||||||
const FISH_MAX_SPEED: f32 = 2.0;
|
const FISH_MAX_SPEED: f32 = 2.0;
|
||||||
@ -63,7 +52,12 @@ impl FishEntity {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_follow_player(&mut self, player: &Player, dt: f64, other_fish: &Vec<FishEntity>) {
|
pub fn handle_follow_player(
|
||||||
|
&mut self,
|
||||||
|
player: &Player,
|
||||||
|
_dt: f64,
|
||||||
|
other_fish: &Vec<FishEntity>,
|
||||||
|
) {
|
||||||
let mut acceleration: Vector2 = Vector2::zero();
|
let mut acceleration: Vector2 = Vector2::zero();
|
||||||
|
|
||||||
let mut steer: Vector2 = Vector2::zero();
|
let mut steer: Vector2 = Vector2::zero();
|
||||||
@ -140,11 +134,7 @@ impl FishEntity {
|
|||||||
self.position += self.velocity;
|
self.position += self.velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_free_movement(&mut self, player: &mut Player, dt: f64) {
|
pub fn handle_free_movement(&mut self, player: &mut Player, _dt: f64) {
|
||||||
// Distance and direction to player
|
|
||||||
let dist_to_player = player.position - self.position;
|
|
||||||
let dist_to_player_lin = self.position.distance_to(player.position);
|
|
||||||
|
|
||||||
// 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;
|
||||||
|
@ -5,15 +5,13 @@ use std::{fmt, fs::File, io::BufReader};
|
|||||||
use raylib::{
|
use raylib::{
|
||||||
camera::Camera2D, math::Vector2, prelude::RaylibDrawHandle, RaylibHandle, RaylibThread,
|
camera::Camera2D, math::Vector2, prelude::RaylibDrawHandle, RaylibHandle, RaylibThread,
|
||||||
};
|
};
|
||||||
|
use failure::Error;
|
||||||
use crate::{
|
use crate::{
|
||||||
player::{Player, PlayerInventory},
|
player::{Player, PlayerInventory},
|
||||||
resources::GlobalResources,
|
resources::GlobalResources,
|
||||||
world::World,
|
world::World,
|
||||||
};
|
};
|
||||||
|
|
||||||
use failure::Error;
|
|
||||||
use log::debug;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Overall states for the game
|
/// Overall states for the game
|
||||||
@ -26,7 +24,7 @@ pub enum GameState {
|
|||||||
InGame,
|
InGame,
|
||||||
GameEnd,
|
GameEnd,
|
||||||
InShop,
|
InShop,
|
||||||
WinGame
|
WinGame,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for GameState {
|
impl fmt::Display for GameState {
|
||||||
@ -80,7 +78,6 @@ impl GameProgress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, new_progress: &GameProgress) {
|
pub fn update(&mut self, new_progress: &GameProgress) {
|
||||||
|
|
||||||
// Bring in new data
|
// Bring in new data
|
||||||
self.coins = new_progress.coins;
|
self.coins = new_progress.coins;
|
||||||
self.inventory = new_progress.inventory.clone();
|
self.inventory = new_progress.inventory.clone();
|
||||||
@ -92,7 +89,6 @@ impl GameProgress {
|
|||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
println!("Could not save game state. Holding in RAM");
|
println!("Could not save game state. Holding in RAM");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,8 +148,6 @@ impl GameCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn switch_state(&mut self, new_state: GameState, draw_handle: Option<&RaylibDrawHandle>) {
|
pub fn switch_state(&mut self, new_state: GameState, draw_handle: Option<&RaylibDrawHandle>) {
|
||||||
debug!("Switching global state to: {}", new_state);
|
|
||||||
|
|
||||||
self.last_state = self.state;
|
self.last_state = self.state;
|
||||||
self.state = new_state;
|
self.state = new_state;
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ use raylib::{
|
|||||||
color::Color,
|
color::Color,
|
||||||
math::{Rectangle, Vector2},
|
math::{Rectangle, Vector2},
|
||||||
prelude::{RaylibDraw, RaylibDrawHandle},
|
prelude::{RaylibDraw, RaylibDrawHandle},
|
||||||
texture::Texture2D,
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
use std::usize;
|
|
||||||
|
|
||||||
use raylib::prelude::*;
|
|
||||||
|
|
||||||
pub struct FrameRange {
|
|
||||||
pub min: usize,
|
|
||||||
pub max: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ComplexAnimationTool {
|
|
||||||
sprite_sheet: Texture2D,
|
|
||||||
frames_per_second: f32,
|
|
||||||
frame_size: Vector2,
|
|
||||||
sprite_sheet_size_frames: Vector2
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ComplexAnimationTool {
|
|
||||||
pub fn render_loop(&self, context_2d: &mut RaylibMode2D<RaylibDrawHandle>, bounds: Rectangle, rotation: f32, range: &FrameRange) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_frame(&self, context_2d: &mut RaylibMode2D<RaylibDrawHandle>, bounds: Rectangle, rotation: f32, id: usize) {
|
|
||||||
|
|
||||||
// Convert the ID to an xy
|
|
||||||
let col_id = id % self.sprite_sheet_size_frames.x as usize;
|
|
||||||
let row_id = id / self.sprite_sheet_size_frames.y as usize;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,2 @@
|
|||||||
pub mod audio;
|
pub mod audio;
|
||||||
pub mod animation;
|
pub mod animation;
|
||||||
pub mod complexanimation;
|
|
@ -22,7 +22,7 @@ impl Screen for GameEndScreen {
|
|||||||
&mut self,
|
&mut self,
|
||||||
draw_handle: &mut RaylibDrawHandle,
|
draw_handle: &mut RaylibDrawHandle,
|
||||||
_thread: &RaylibThread,
|
_thread: &RaylibThread,
|
||||||
audio_system: &mut AudioPlayer,
|
_audio_system: &mut AudioPlayer,
|
||||||
game_core: &mut GameCore,
|
game_core: &mut GameCore,
|
||||||
) -> Option<GameState> {
|
) -> Option<GameState> {
|
||||||
draw_handle.clear_background(Color::GRAY);
|
draw_handle.clear_background(Color::GRAY);
|
||||||
@ -75,7 +75,7 @@ impl Screen for GameEndScreen {
|
|||||||
String::from("Return to shop"),
|
String::from("Return to shop"),
|
||||||
Rectangle {
|
Rectangle {
|
||||||
x: (((win_width / 2) - ((SCREEN_PANEL_SIZE.x as i32 + 6) / 2) + 5)
|
x: (((win_width / 2) - ((SCREEN_PANEL_SIZE.x as i32 + 6) / 2) + 5)
|
||||||
+ (0.15 * SCREEN_PANEL_SIZE.x) as i32) as f32,
|
+ (0.15 * SCREEN_PANEL_SIZE.x) as i32) as f32,
|
||||||
y: (((win_height / 2) - (SCREEN_PANEL_SIZE.y as i32 / 2) + 90) as f32) + 100.0,
|
y: (((win_height / 2) - (SCREEN_PANEL_SIZE.y as i32 / 2) + 90) as f32) + 100.0,
|
||||||
width: 210.0,
|
width: 210.0,
|
||||||
height: 50.0,
|
height: 50.0,
|
||||||
@ -87,78 +87,15 @@ impl Screen for GameEndScreen {
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
// render button
|
// render button
|
||||||
go_to_menu_button.render(draw_handle);
|
go_to_menu_button.render(draw_handle);
|
||||||
|
|
||||||
// If the player clicks on the button send them to shop
|
// If the player clicks on the button send them to shop
|
||||||
if go_to_menu_button.is_hovered(draw_handle) && draw_handle.is_mouse_button_pressed(MouseButton::MOUSE_LEFT_BUTTON){
|
if go_to_menu_button.is_hovered(draw_handle)
|
||||||
|
&& draw_handle.is_mouse_button_pressed(MouseButton::MOUSE_LEFT_BUTTON)
|
||||||
game_core.switch_state(GameState::InShop, Some(draw_handle));
|
{
|
||||||
|
return Some(GameState::InShop);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Save game progress
|
|
||||||
|
|
||||||
// // Close and quit buttons
|
|
||||||
// let bottom_left_button_dimensions = Rectangle {
|
|
||||||
// x: (win_width as f32 / 2.0) - (SCREEN_PANEL_SIZE.x / 2.0) + 5.0,
|
|
||||||
// y: (win_height as f32 / 2.0) + (SCREEN_PANEL_SIZE.y / 2.0) - 50.0,
|
|
||||||
// width: (SCREEN_PANEL_SIZE.x / 2.0) - 15.0,
|
|
||||||
// height: 40.0,
|
|
||||||
// };
|
|
||||||
// let bottom_right_button_dimensions = Rectangle {
|
|
||||||
// x: (win_width as f32 / 2.0) + 5.0,
|
|
||||||
// y: bottom_left_button_dimensions.y,
|
|
||||||
// width: bottom_left_button_dimensions.width,
|
|
||||||
// height: bottom_left_button_dimensions.height,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Check if the mouse is over either button
|
|
||||||
// let mouse_over_bottom_left_button =
|
|
||||||
// bottom_left_button_dimensions.check_collision_point_rec(mouse_position);
|
|
||||||
// let mouse_over_bottom_right_button =
|
|
||||||
// bottom_right_button_dimensions.check_collision_point_rec(mouse_position);
|
|
||||||
|
|
||||||
// // Render buttons
|
|
||||||
// draw_handle.draw_rectangle_lines_ex(
|
|
||||||
// bottom_left_button_dimensions,
|
|
||||||
// 3,
|
|
||||||
// match mouse_over_bottom_left_button {
|
|
||||||
// true => Color::GRAY,
|
|
||||||
// false => Color::BLACK,
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// draw_handle.draw_text(
|
|
||||||
// "Quit",
|
|
||||||
// bottom_left_button_dimensions.x as i32 + 15,
|
|
||||||
// bottom_left_button_dimensions.y as i32 + 5,
|
|
||||||
// 30,
|
|
||||||
// Color::BLACK,
|
|
||||||
// );
|
|
||||||
// draw_handle.draw_rectangle_lines_ex(
|
|
||||||
// bottom_right_button_dimensions,
|
|
||||||
// 3,
|
|
||||||
// match mouse_over_bottom_right_button {
|
|
||||||
// true => Color::GRAY,
|
|
||||||
// false => Color::BLACK,
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// draw_handle.draw_text(
|
|
||||||
// "Close",
|
|
||||||
// bottom_right_button_dimensions.x as i32 + 15,
|
|
||||||
// bottom_right_button_dimensions.y as i32 + 5,
|
|
||||||
// 30,
|
|
||||||
// Color::BLACK,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// // Handle click actions on the buttons
|
|
||||||
// if draw_handle.is_mouse_button_pressed(MouseButton::MOUSE_LEFT_BUTTON) {
|
|
||||||
// if mouse_over_bottom_left_button {
|
|
||||||
// return Some(GameState::GameQuit);
|
|
||||||
// } else if mouse_over_bottom_right_button {
|
|
||||||
// return Some(game_core.last_state);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -3,29 +3,19 @@ mod playerlogic;
|
|||||||
|
|
||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{entities::enemy::{base::EnemyBase, whirlpool::Whirlpool}, gamecore::{GameCore, GameState}, lib::wrappers::audio::player::AudioPlayer};
|
||||||
entities::enemy::base::EnemyBase,
|
|
||||||
gamecore::{GameCore, GameState},
|
|
||||||
lib::wrappers::audio::player::AudioPlayer,
|
|
||||||
pallette::{SKY, WATER, WATER_DARK},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::screen::Screen;
|
use super::screen::Screen;
|
||||||
|
use crate::entities::fish::FishEntity;
|
||||||
|
|
||||||
pub enum InGameState {
|
|
||||||
BUYING,
|
|
||||||
SWIMMING,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct InGameScreen {
|
pub struct InGameScreen {
|
||||||
current_state: InGameState,
|
|
||||||
shader_time_var_location: i32,
|
shader_time_var_location: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InGameScreen {
|
impl InGameScreen {
|
||||||
pub unsafe fn new(game_core: &GameCore) -> Self {
|
pub unsafe fn new(game_core: &GameCore) -> Self {
|
||||||
Self {
|
Self {
|
||||||
current_state: InGameState::SWIMMING,
|
|
||||||
shader_time_var_location: raylib::ffi::GetShaderLocation(
|
shader_time_var_location: raylib::ffi::GetShaderLocation(
|
||||||
*game_core.resources.pixel_shader,
|
*game_core.resources.pixel_shader,
|
||||||
rstr!("time").as_ptr(),
|
rstr!("time").as_ptr(),
|
||||||
@ -188,8 +178,8 @@ impl Screen for InGameScreen {
|
|||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
draw_handle: &mut RaylibDrawHandle,
|
draw_handle: &mut RaylibDrawHandle,
|
||||||
thread: &RaylibThread,
|
_thread: &RaylibThread,
|
||||||
audio_system: &mut AudioPlayer,
|
_audio_system: &mut AudioPlayer,
|
||||||
game_core: &mut GameCore,
|
game_core: &mut GameCore,
|
||||||
) -> Option<GameState> {
|
) -> Option<GameState> {
|
||||||
// Calculate DT
|
// Calculate DT
|
||||||
@ -207,7 +197,6 @@ impl Screen for InGameScreen {
|
|||||||
x: (win_width as f32 / 2.0),
|
x: (win_width as f32 / 2.0),
|
||||||
y: (win_height as f32 / 2.0),
|
y: (win_height as f32 / 2.0),
|
||||||
};
|
};
|
||||||
let camera_window_center = window_center * (1.0 / game_core.master_camera.zoom);
|
|
||||||
|
|
||||||
// Update player movement
|
// Update player movement
|
||||||
playerlogic::update_player_movement(draw_handle, game_core, window_center);
|
playerlogic::update_player_movement(draw_handle, game_core, window_center);
|
||||||
@ -249,6 +238,27 @@ impl Screen for InGameScreen {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterates over whirlpools and runs render and logic funcs
|
||||||
|
for whirlpool_mob in game_core.world.whirlpool.iter_mut(){
|
||||||
|
whirlpool_mob.handle_logic(&mut game_core.player, dt);
|
||||||
|
whirlpool_mob.render(&mut context_2d, &mut game_core.player, &mut game_core.resources, dt);
|
||||||
|
|
||||||
|
// Spawns 10 fish on spawn
|
||||||
|
if whirlpool_mob.should_remove(){
|
||||||
|
for _ in 0..10{
|
||||||
|
game_core.world.fish.push(FishEntity::new(whirlpool_mob.position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes whirlpools set for removal
|
||||||
|
game_core.world.whirlpool.retain(|x| !x.should_remove());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Render transponder
|
// Render transponder
|
||||||
game_core.resources.transponder.draw(
|
game_core.resources.transponder.draw(
|
||||||
&mut context_2d,
|
&mut context_2d,
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::gamecore::GameCore;
|
||||||
gamecore::GameCore,
|
|
||||||
pallette::{TRANSLUCENT_WHITE_128, TRANSLUCENT_WHITE_64, TRANSLUCENT_WHITE_96},
|
|
||||||
};
|
|
||||||
|
|
||||||
const NORMAL_PLAYER_SPEED: i32 = 1;
|
const NORMAL_PLAYER_SPEED: i32 = 1;
|
||||||
const BOOST_PLAYER_SPEED: i32 = NORMAL_PLAYER_SPEED * 2;
|
const BOOST_PLAYER_SPEED: i32 = NORMAL_PLAYER_SPEED * 2;
|
||||||
const CAMERA_FOLLOW_SPEED: f32 = 0.7;
|
const PLAYER_FRICTION: f32 = 1.05;
|
||||||
|
const WHIRLPOOL_PULL: f32 = 3.0;
|
||||||
const TURN_SPEED: f32 = 0.15;
|
const TURN_SPEED: f32 = 0.15;
|
||||||
const BOOST_DECREASE_PER_SECOND: f32 = 0.65;
|
const BOOST_DECREASE_PER_SECOND: f32 = 0.65;
|
||||||
const BOOST_REGEN_PER_SECOND: f32 = 0.25;
|
const BOOST_REGEN_PER_SECOND: f32 = 0.25;
|
||||||
@ -24,7 +22,7 @@ pub fn update_player_movement(
|
|||||||
// Handle player movement
|
// Handle player movement
|
||||||
let mouse_pose = draw_handle.get_mouse_position();
|
let mouse_pose = draw_handle.get_mouse_position();
|
||||||
let mouse_world_pose = draw_handle.get_screen_to_world2D(mouse_pose, game_core.master_camera);
|
let mouse_world_pose = draw_handle.get_screen_to_world2D(mouse_pose, game_core.master_camera);
|
||||||
let raw_movement_direction = mouse_world_pose - game_core.player.position;
|
let mut raw_movement_direction = mouse_world_pose - game_core.player.position;
|
||||||
let mut normalized_movement_direction = raw_movement_direction;
|
let mut normalized_movement_direction = raw_movement_direction;
|
||||||
normalized_movement_direction.normalize();
|
normalized_movement_direction.normalize();
|
||||||
|
|
||||||
@ -79,7 +77,9 @@ pub fn update_player_movement(
|
|||||||
let user_request_action = draw_handle.is_mouse_button_pressed(MouseButton::MOUSE_RIGHT_BUTTON);
|
let user_request_action = draw_handle.is_mouse_button_pressed(MouseButton::MOUSE_RIGHT_BUTTON);
|
||||||
|
|
||||||
if user_request_action {
|
if user_request_action {
|
||||||
game_core.player.begin_attack(&mut game_core.world, draw_handle.get_time());
|
game_core
|
||||||
|
.player
|
||||||
|
.begin_attack(&mut game_core.world, draw_handle.get_time());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the player in their direction
|
// Move the player in their direction
|
||||||
@ -150,34 +150,98 @@ pub fn update_player_movement(
|
|||||||
|
|
||||||
// Handle the player wearing flippers
|
// Handle the player wearing flippers
|
||||||
if game_core.player.inventory.flippers.is_some() {
|
if game_core.player.inventory.flippers.is_some() {
|
||||||
player_real_movement *= game_core.player.inventory.flippers.as_ref().unwrap().speed_increase;
|
player_real_movement *= game_core
|
||||||
|
.player
|
||||||
|
.inventory
|
||||||
|
.flippers
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.speed_increase;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut should_apply_friction: bool = true;
|
||||||
|
|
||||||
|
// Check each whirlpool for effects
|
||||||
|
for whirlpool in game_core.world.whirlpool.iter_mut(){
|
||||||
|
|
||||||
|
|
||||||
|
// check if its in range and not to close
|
||||||
|
if game_core.player.position.distance_to(whirlpool.position) <= 50.0 && game_core.player.position.distance_to(whirlpool.position) >= 10.0{
|
||||||
|
|
||||||
|
// Calculates info for formulas
|
||||||
|
|
||||||
|
// Deltas between positions
|
||||||
|
let net_pose = game_core.player.position - whirlpool.position;
|
||||||
|
|
||||||
|
// Angle between: UNITS: RADIANS
|
||||||
|
let angle = net_pose.y.atan2(net_pose.x);
|
||||||
|
|
||||||
|
|
||||||
|
// Calculates force
|
||||||
|
let force = WHIRLPOOL_PULL / game_core.player.position.distance_to(whirlpool.position);
|
||||||
|
|
||||||
|
// Calculates componets of force
|
||||||
|
let mut force_x = (force as f32 * angle.cos()).clamp(-5.0, 5.0);
|
||||||
|
let mut force_y = (force as f32 * angle.sin()).clamp(-5.0, 5.0);
|
||||||
|
|
||||||
|
// Prevents Nan erros
|
||||||
|
if force_x.is_nan(){
|
||||||
|
force_x = 5.0 * net_pose.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if force_y.is_nan(){
|
||||||
|
force_y = 5.0 * net_pose.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds values to drift tracker
|
||||||
|
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;
|
||||||
|
if f32::round(game_core.player.additional_vel.x * 10.0) == 0.0 {
|
||||||
|
game_core.player.additional_vel.x = 0.0;
|
||||||
|
}
|
||||||
|
if f32::round(game_core.player.additional_vel.y * 10.0) == 0.0 {
|
||||||
|
game_core.player.additional_vel.y = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(raw_movement_direction.distance_to(Vector2::zero()) > game_core.player.size.y / 2.0) {
|
||||||
|
player_real_movement = Vector2::zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle movement and collisions
|
// Handle movement and collisions
|
||||||
if raw_movement_direction.distance_to(Vector2::zero()) > game_core.player.size.y / 2.0
|
if !game_core.player.is_stunned() {
|
||||||
&& !game_core.player.is_stunned()
|
|
||||||
{
|
|
||||||
if game_core.player.is_moving {
|
if game_core.player.is_moving {
|
||||||
// move in x
|
// move in x
|
||||||
game_core.player.position.x += player_real_movement.x;
|
game_core.player.position.x += player_real_movement.x + game_core.player.additional_vel.x;
|
||||||
|
|
||||||
// Check for any collisions
|
// Check for any collisions
|
||||||
for collider in game_core.world.colliders.iter() {
|
for collider in game_core.world.colliders.iter() {
|
||||||
if game_core.player.collides_with_rec(collider) {
|
if game_core.player.collides_with_rec(collider) {
|
||||||
game_core.player.position.x -= player_real_movement.x;
|
game_core.player.position.x -= player_real_movement.x + game_core.player.additional_vel.x;
|
||||||
player_real_movement.x = 0.0;
|
player_real_movement.x = 0.0;
|
||||||
|
game_core.player.additional_vel.x = 0.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// move in y
|
// move in y
|
||||||
game_core.player.position.y += player_real_movement.y;
|
game_core.player.position.y += player_real_movement.y + game_core.player.additional_vel.y;
|
||||||
|
|
||||||
// Check for any collisions
|
// Check for any collisions
|
||||||
for collider in game_core.world.colliders.iter() {
|
for collider in game_core.world.colliders.iter() {
|
||||||
if game_core.player.collides_with_rec(collider) {
|
if game_core.player.collides_with_rec(collider) {
|
||||||
game_core.player.position.y -= player_real_movement.y;
|
game_core.player.position.y -= player_real_movement.y + game_core.player.additional_vel.y;
|
||||||
player_real_movement.y = 0.0;
|
player_real_movement.y = 0.0;
|
||||||
|
game_core.player.additional_vel.y = 0.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,17 +251,20 @@ pub fn update_player_movement(
|
|||||||
// Handle updating the stun timer
|
// Handle updating the stun timer
|
||||||
if player_stunned {
|
if player_stunned {
|
||||||
game_core.player.stun_timer -= dt;
|
game_core.player.stun_timer -= dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Move the camera to follow the player
|
// Move the camera to follow the player
|
||||||
let direction_from_cam_to_player =
|
|
||||||
(game_core.player.position - window_center) - game_core.master_camera.target;
|
|
||||||
let player_screen_position =
|
let player_screen_position =
|
||||||
draw_handle.get_world_to_screen2D(game_core.player.position, game_core.master_camera);
|
draw_handle.get_world_to_screen2D(game_core.player.position, game_core.master_camera);
|
||||||
|
|
||||||
// Camera only moves if you get close to the edge of the screen
|
// Camera only moves if you get close to the edge of the screen
|
||||||
if player_screen_position.distance_to(window_center).abs() > 100.0 {
|
if player_screen_position.distance_to(window_center).abs() > 100.0 {
|
||||||
game_core.master_camera.target += player_real_movement;
|
game_core.master_camera.target += player_real_movement + game_core.player.additional_vel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the player is not on screen, snap the camera to them
|
// If the player is not on screen, snap the camera to them
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
|
|
||||||
use crate::{gamecore::{GameCore, GameState}, lib::{utils::calculate_linear_slide, wrappers::audio::player::AudioPlayer}};
|
use crate::{
|
||||||
|
gamecore::{GameCore, GameState},
|
||||||
|
lib::{utils::calculate_linear_slide, wrappers::audio::player::AudioPlayer},
|
||||||
|
};
|
||||||
|
|
||||||
use super::screen::Screen;
|
use super::screen::Screen;
|
||||||
|
|
||||||
const SECONDS_PER_LOGO: f64 = 4.0;
|
const SECONDS_PER_LOGO: f64 = 4.0;
|
||||||
const RUST_ORANGE: Color = Color::new(222, 165, 132, 255);
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum LoadingScreenState {
|
enum LoadingScreenState {
|
||||||
@ -138,7 +140,7 @@ impl Screen for LoadingScreen {
|
|||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
draw_handle: &mut RaylibDrawHandle,
|
draw_handle: &mut RaylibDrawHandle,
|
||||||
thread: &RaylibThread,
|
_thread: &RaylibThread,
|
||||||
_audio_system: &mut AudioPlayer,
|
_audio_system: &mut AudioPlayer,
|
||||||
game_core: &mut GameCore,
|
game_core: &mut GameCore,
|
||||||
) -> Option<GameState> {
|
) -> Option<GameState> {
|
||||||
|
@ -3,7 +3,6 @@ use raylib::prelude::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
gamecore::{GameCore, GameState},
|
gamecore::{GameCore, GameState},
|
||||||
lib::wrappers::audio::player::AudioPlayer,
|
lib::wrappers::audio::player::AudioPlayer,
|
||||||
pallette::WATER_DARK,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::screen::Screen;
|
use super::screen::Screen;
|
||||||
@ -20,8 +19,8 @@ impl Screen for MainMenuScreen {
|
|||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
draw_handle: &mut RaylibDrawHandle,
|
draw_handle: &mut RaylibDrawHandle,
|
||||||
thread: &RaylibThread,
|
_thread: &RaylibThread,
|
||||||
audio_system: &mut AudioPlayer,
|
_audio_system: &mut AudioPlayer,
|
||||||
game_core: &mut GameCore,
|
game_core: &mut GameCore,
|
||||||
) -> Option<GameState> {
|
) -> Option<GameState> {
|
||||||
// Window dimensions
|
// Window dimensions
|
||||||
@ -35,8 +34,8 @@ impl Screen for MainMenuScreen {
|
|||||||
|
|
||||||
// Render title
|
// Render title
|
||||||
draw_handle.draw_text(
|
draw_handle.draw_text(
|
||||||
"PINK MAN SWIM",
|
"ONE BREATH",
|
||||||
(win_height / 2) - 120,
|
(win_height / 2) - 80,
|
||||||
win_width / 8,
|
win_width / 8,
|
||||||
80,
|
80,
|
||||||
Color::BLACK,
|
Color::BLACK,
|
||||||
@ -55,7 +54,7 @@ impl Screen for MainMenuScreen {
|
|||||||
draw_handle.draw_text(
|
draw_handle.draw_text(
|
||||||
"Play",
|
"Play",
|
||||||
(win_height / 2) + 120,
|
(win_height / 2) + 120,
|
||||||
(win_width / 4),
|
win_width / 4,
|
||||||
60,
|
60,
|
||||||
match hovering_play_button {
|
match hovering_play_button {
|
||||||
true => Color::BLUE,
|
true => Color::BLUE,
|
||||||
@ -96,7 +95,7 @@ impl Screen for MainMenuScreen {
|
|||||||
return Some(GameState::InGame);
|
return Some(GameState::InGame);
|
||||||
} else if hovering_shop_button {
|
} else if hovering_shop_button {
|
||||||
return Some(GameState::InShop);
|
return Some(GameState::InShop);
|
||||||
}else if hovering_quit_button {
|
} else if hovering_quit_button {
|
||||||
return Some(GameState::GameQuit);
|
return Some(GameState::GameQuit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use raylib::prelude::*;
|
|
||||||
|
|
||||||
use crate::{items::ItemBase, player::Player, world::World};
|
|
||||||
|
|
||||||
use super::itemui::ShopItemUi;
|
use super::itemui::ShopItemUi;
|
||||||
|
use crate::{items::ItemBase, player::Player};
|
||||||
|
use raylib::prelude::*;
|
||||||
|
|
||||||
pub struct ShopItemWrapper<T: ItemBase + Clone> {
|
pub struct ShopItemWrapper<T: ItemBase + Clone> {
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
@ -17,7 +13,7 @@ impl<T: ItemBase + Clone> ShopItemWrapper<T> {
|
|||||||
item: T,
|
item: T,
|
||||||
from_inventory: &Option<T>,
|
from_inventory: &Option<T>,
|
||||||
first_item_bounds: Rectangle,
|
first_item_bounds: Rectangle,
|
||||||
index: u8
|
index: u8,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Build new bounds for the UI row
|
// Build new bounds for the UI row
|
||||||
let new_bounds = Rectangle {
|
let new_bounds = Rectangle {
|
||||||
@ -47,7 +43,9 @@ impl<T: ItemBase + Clone> ShopItemWrapper<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_player_afford(&self, player: &Player, players_item: &Option<T>) -> bool {
|
pub fn can_player_afford(&self, player: &Player, players_item: &Option<T>) -> bool {
|
||||||
return player.coins >= self.item.get_cost() && ((players_item.is_some() && players_item.as_ref().unwrap().get_level() < 3) || players_item.is_none());
|
return player.coins >= self.item.get_cost()
|
||||||
|
&& ((players_item.is_some() && players_item.as_ref().unwrap().get_level() < 3)
|
||||||
|
|| players_item.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn purchase(&self, player: &mut Player) -> T {
|
pub fn purchase(&self, player: &mut Player) -> T {
|
||||||
@ -59,14 +57,26 @@ impl<T: ItemBase + Clone> ShopItemWrapper<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn user_clicked_buy(&self, draw_handle: &mut RaylibDrawHandle) -> bool {
|
pub fn user_clicked_buy(&self, draw_handle: &mut RaylibDrawHandle) -> bool {
|
||||||
return self.ui.buy_button_hovered && draw_handle.is_mouse_button_pressed(MouseButton::MOUSE_LEFT_BUTTON);
|
return self.ui.buy_button_hovered
|
||||||
|
&& draw_handle.is_mouse_button_pressed(MouseButton::MOUSE_LEFT_BUTTON);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn user_hovering_row(&self, draw_handle: &mut RaylibDrawHandle) -> bool {
|
pub fn user_hovering_row(&self, draw_handle: &mut RaylibDrawHandle) -> bool {
|
||||||
return self.bounds.check_collision_point_rec(draw_handle.get_mouse_position());
|
return self
|
||||||
|
.bounds
|
||||||
|
.check_collision_point_rec(draw_handle.get_mouse_position());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self, draw_handle: &mut RaylibDrawHandle, player: &Player, players_item: &Option<T>) {
|
pub fn render(
|
||||||
self.ui.render(draw_handle, self.bounds, self.can_player_afford(player, players_item));
|
&mut self,
|
||||||
|
draw_handle: &mut RaylibDrawHandle,
|
||||||
|
player: &Player,
|
||||||
|
players_item: &Option<T>,
|
||||||
|
) {
|
||||||
|
self.ui.render(
|
||||||
|
draw_handle,
|
||||||
|
self.bounds,
|
||||||
|
self.can_player_afford(player, players_item),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
use raylib::prelude::*;
|
use super::item::ShopItemWrapper;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gamecore::{GameCore, GameState},
|
gamecore::{GameCore, GameState},
|
||||||
items::{AirBag, Flashlight, Flippers, ItemBase, StunGun},
|
items::{AirBag, Flashlight, Flippers, ItemBase, StunGun},
|
||||||
lib::{utils::button::OnScreenButton, wrappers::audio::player::AudioPlayer},
|
lib::{utils::button::OnScreenButton, wrappers::audio::player::AudioPlayer},
|
||||||
};
|
};
|
||||||
|
use raylib::prelude::*;
|
||||||
use super::{item::ShopItemWrapper, itemui::ShopItemUi};
|
|
||||||
|
|
||||||
pub fn render_shop(
|
pub fn render_shop(
|
||||||
draw_handle: &mut RaylibDrawHandle,
|
draw_handle: &mut RaylibDrawHandle,
|
||||||
_thread: &RaylibThread,
|
_thread: &RaylibThread,
|
||||||
audio_system: &mut AudioPlayer,
|
_audio_system: &mut AudioPlayer,
|
||||||
game_core: &mut GameCore,
|
game_core: &mut GameCore,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
) -> Option<GameState> {
|
) -> Option<GameState> {
|
||||||
// Render background
|
// Render background
|
||||||
draw_handle.draw_rectangle_rec(bounds, Color::WHITE);
|
draw_handle.draw_rectangle_rec(bounds, Color::new(255, 255, 255, 125));
|
||||||
draw_handle.draw_rectangle_lines_ex(bounds, 3, Color::BLACK);
|
draw_handle.draw_rectangle_lines_ex(bounds, 3, Color::BLACK);
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
@ -87,10 +85,26 @@ pub fn render_shop(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Render items
|
// Render items
|
||||||
stun_gun_buy_ui.render(draw_handle, &game_core.player, &game_core.player.inventory.stun_gun);
|
stun_gun_buy_ui.render(
|
||||||
air_bag_buy_ui.render(draw_handle, &game_core.player, &game_core.player.inventory.air_bag);
|
draw_handle,
|
||||||
flashlight_buy_ui.render(draw_handle, &game_core.player, &game_core.player.inventory.flashlight);
|
&game_core.player,
|
||||||
flippers_buy_ui.render(draw_handle, &game_core.player, &game_core.player.inventory.flippers);
|
&game_core.player.inventory.stun_gun,
|
||||||
|
);
|
||||||
|
air_bag_buy_ui.render(
|
||||||
|
draw_handle,
|
||||||
|
&game_core.player,
|
||||||
|
&game_core.player.inventory.air_bag,
|
||||||
|
);
|
||||||
|
flashlight_buy_ui.render(
|
||||||
|
draw_handle,
|
||||||
|
&game_core.player,
|
||||||
|
&game_core.player.inventory.flashlight,
|
||||||
|
);
|
||||||
|
flippers_buy_ui.render(
|
||||||
|
draw_handle,
|
||||||
|
&game_core.player,
|
||||||
|
&game_core.player.inventory.flippers,
|
||||||
|
);
|
||||||
|
|
||||||
// Handle buying items
|
// Handle buying items
|
||||||
if stun_gun_buy_ui.can_player_afford(&game_core.player, &game_core.player.inventory.stun_gun)
|
if stun_gun_buy_ui.can_player_afford(&game_core.player, &game_core.player.inventory.stun_gun)
|
||||||
@ -105,7 +119,8 @@ pub fn render_shop(
|
|||||||
let item = air_bag_buy_ui.purchase(&mut game_core.player);
|
let item = air_bag_buy_ui.purchase(&mut game_core.player);
|
||||||
game_core.player.inventory.air_bag = Some(item);
|
game_core.player.inventory.air_bag = Some(item);
|
||||||
}
|
}
|
||||||
if flashlight_buy_ui.can_player_afford(&game_core.player, &game_core.player.inventory.flashlight)
|
if flashlight_buy_ui
|
||||||
|
.can_player_afford(&game_core.player, &game_core.player.inventory.flashlight)
|
||||||
&& flashlight_buy_ui.user_clicked_buy(draw_handle)
|
&& flashlight_buy_ui.user_clicked_buy(draw_handle)
|
||||||
{
|
{
|
||||||
let item = flashlight_buy_ui.purchase(&mut game_core.player);
|
let item = flashlight_buy_ui.purchase(&mut game_core.player);
|
||||||
@ -151,8 +166,7 @@ pub fn render_shop(
|
|||||||
draw_handle.draw_rectangle_rec(box_bounds, Color::WHITE);
|
draw_handle.draw_rectangle_rec(box_bounds, Color::WHITE);
|
||||||
draw_handle.draw_rectangle_lines_ex(box_bounds, 3, Color::BLACK);
|
draw_handle.draw_rectangle_lines_ex(box_bounds, 3, Color::BLACK);
|
||||||
|
|
||||||
|
hovered_item.get_texture(
|
||||||
hovered_item.get_texture(
|
|
||||||
draw_handle,
|
draw_handle,
|
||||||
&game_core.resources,
|
&game_core.resources,
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@ -160,9 +174,8 @@ pub fn render_shop(
|
|||||||
y: box_bounds.y + 10.0,
|
y: box_bounds.y + 10.0,
|
||||||
width: (80.0),
|
width: (80.0),
|
||||||
height: (80.0),
|
height: (80.0),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Render item description
|
// Render item description
|
||||||
draw_handle.draw_text(
|
draw_handle.draw_text(
|
||||||
|
@ -2,22 +2,16 @@ mod item;
|
|||||||
mod itemui;
|
mod itemui;
|
||||||
mod mainui;
|
mod mainui;
|
||||||
|
|
||||||
use raylib::prelude::*;
|
use self::mainui::{render_shop, render_stats};
|
||||||
|
use super::screen::Screen;
|
||||||
use crate::{
|
use crate::{
|
||||||
gamecore::{GameCore, GameState},
|
gamecore::{GameCore, GameState},
|
||||||
lib::wrappers::audio::player::AudioPlayer,
|
lib::wrappers::audio::player::AudioPlayer,
|
||||||
};
|
};
|
||||||
|
use raylib::prelude::*;
|
||||||
use self::mainui::{render_shop, render_stats};
|
|
||||||
|
|
||||||
use super::screen::Screen;
|
|
||||||
|
|
||||||
const SCREEN_PANEL_SIZE: Vector2 = Vector2 { x: 300.0, y: 380.0 };
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ShopScreen {
|
pub struct ShopScreen {
|
||||||
// shop_items: Vec<Item>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShopScreen {
|
impl ShopScreen {
|
||||||
@ -36,8 +30,6 @@ impl Screen for ShopScreen {
|
|||||||
audio_system: &mut AudioPlayer,
|
audio_system: &mut AudioPlayer,
|
||||||
game_core: &mut GameCore,
|
game_core: &mut GameCore,
|
||||||
) -> Option<GameState> {
|
) -> Option<GameState> {
|
||||||
let mouse_position = draw_handle.get_mouse_position();
|
|
||||||
|
|
||||||
// Render the background
|
// Render the background
|
||||||
draw_handle.draw_texture(&game_core.resources.shop_background, 0, 0, Color::WHITE);
|
draw_handle.draw_texture(&game_core.resources.shop_background, 0, 0, Color::WHITE);
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ impl Screen for WinScreen {
|
|||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
draw_handle: &mut RaylibDrawHandle,
|
draw_handle: &mut RaylibDrawHandle,
|
||||||
thread: &RaylibThread,
|
_thread: &RaylibThread,
|
||||||
audio_system: &mut AudioPlayer,
|
_audio_system: &mut AudioPlayer,
|
||||||
game_core: &mut GameCore,
|
game_core: &mut GameCore,
|
||||||
) -> Option<GameState> {
|
) -> Option<GameState> {
|
||||||
let win_height = draw_handle.get_screen_height();
|
let win_height = draw_handle.get_screen_height();
|
||||||
@ -57,7 +57,8 @@ impl Screen for WinScreen {
|
|||||||
// Render message
|
// Render message
|
||||||
draw_handle.draw_text(
|
draw_handle.draw_text(
|
||||||
"You can use the transponder to \ncontact help!",
|
"You can use the transponder to \ncontact help!",
|
||||||
((win_width / 2) - ((SCREEN_PANEL_SIZE.x as i32 + 6) / 2)) + (0.15 * SCREEN_PANEL_SIZE.x)as i32,
|
((win_width / 2) - ((SCREEN_PANEL_SIZE.x as i32 + 6) / 2))
|
||||||
|
+ (0.15 * SCREEN_PANEL_SIZE.x) as i32,
|
||||||
(win_height / 2) - (SCREEN_PANEL_SIZE.y as i32 / 2) + 80,
|
(win_height / 2) - (SCREEN_PANEL_SIZE.y as i32 / 2) + 80,
|
||||||
15,
|
15,
|
||||||
Color::BLACK,
|
Color::BLACK,
|
||||||
@ -87,7 +88,7 @@ impl Screen for WinScreen {
|
|||||||
{
|
{
|
||||||
game_core.switch_state(GameState::MainMenu, Some(draw_handle));
|
game_core.switch_state(GameState::MainMenu, Some(draw_handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
src/main.rs
23
src/main.rs
@ -10,16 +10,10 @@ mod world;
|
|||||||
|
|
||||||
use gamecore::{GameCore, GameProgress, GameState};
|
use gamecore::{GameCore, GameProgress, GameState};
|
||||||
use lib::{utils::profiler::GameProfiler, wrappers::audio::player::AudioPlayer};
|
use lib::{utils::profiler::GameProfiler, wrappers::audio::player::AudioPlayer};
|
||||||
use log::info;
|
|
||||||
use logic::{
|
use logic::{
|
||||||
gameend::GameEndScreen,
|
gameend::GameEndScreen, ingame::InGameScreen, loadingscreen::LoadingScreen,
|
||||||
ingame::InGameScreen,
|
mainmenu::MainMenuScreen, pausemenu::PauseMenuScreen, screen::Screen, shop::ShopScreen,
|
||||||
loadingscreen::LoadingScreen,
|
winscreen::WinScreen,
|
||||||
mainmenu::MainMenuScreen,
|
|
||||||
pausemenu::PauseMenuScreen,
|
|
||||||
screen::Screen,
|
|
||||||
shop::ShopScreen,
|
|
||||||
winscreen::{self, WinScreen},
|
|
||||||
};
|
};
|
||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
use world::{load_world_colliders, World};
|
use world::{load_world_colliders, World};
|
||||||
@ -33,9 +27,6 @@ const WINDOW_TITLE: &str = r"One Breath";
|
|||||||
const MAX_FPS: u32 = 60;
|
const MAX_FPS: u32 = 60;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Configure the logger
|
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
// Configure a window
|
// Configure a window
|
||||||
let (mut raylib, raylib_thread) = raylib::init()
|
let (mut raylib, raylib_thread) = raylib::init()
|
||||||
.size(
|
.size(
|
||||||
@ -149,12 +140,8 @@ fn main() {
|
|||||||
.create_statistics(&game_core, draw_handle.get_time());
|
.create_statistics(&game_core, draw_handle.get_time());
|
||||||
game_core.progress.update(&new_progress);
|
game_core.progress.update(&new_progress);
|
||||||
|
|
||||||
// For now, just quit
|
// Break the render loop
|
||||||
// This also throws a SEGFAULT.. yay for unsafe code..
|
break;
|
||||||
info!("User quit game");
|
|
||||||
unsafe {
|
|
||||||
raylib::ffi::CloseWindow();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
game_core.switch_state(new_state, Some(&draw_handle));
|
game_core.switch_state(new_state, Some(&draw_handle));
|
||||||
|
@ -21,27 +21,6 @@ pub const TRANSLUCENT_WHITE_64: Color = Color {
|
|||||||
a: 64,
|
a: 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SKY: Color = Color {
|
|
||||||
r: 15,
|
|
||||||
g: 193,
|
|
||||||
b: 217,
|
|
||||||
a: 255
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const WATER: Color = Color {
|
|
||||||
r: 24,
|
|
||||||
g: 66,
|
|
||||||
b: 143,
|
|
||||||
a: 255
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const WATER_DARK: Color = Color {
|
|
||||||
r: 8,
|
|
||||||
g: 24,
|
|
||||||
b: 54,
|
|
||||||
a: 255
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const TRANSLUCENT_RED_64: Color = Color {
|
pub const TRANSLUCENT_RED_64: Color = Color {
|
||||||
r: 230,
|
r: 230,
|
||||||
g: 41,
|
g: 41,
|
||||||
|
@ -10,9 +10,6 @@ use crate::{
|
|||||||
use raylib::prelude::*;
|
use raylib::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
const AOE_RING_MAX_RADIUS: f32 = 60.0;
|
|
||||||
const STUN_ATTACK_TIME: f64 = 0.75;
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
||||||
pub struct PlayerInventory {
|
pub struct PlayerInventory {
|
||||||
pub stun_gun: Option<StunGun>,
|
pub stun_gun: Option<StunGun>,
|
||||||
@ -35,6 +32,7 @@ impl PlayerInventory {
|
|||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub position: Vector2,
|
pub position: Vector2,
|
||||||
pub direction: Vector2,
|
pub direction: Vector2,
|
||||||
|
pub additional_vel: Vector2,
|
||||||
pub size: Vector2,
|
pub size: Vector2,
|
||||||
pub radius: f32,
|
pub radius: f32,
|
||||||
pub coins: u32,
|
pub coins: u32,
|
||||||
@ -51,6 +49,7 @@ pub struct Player {
|
|||||||
impl Player {
|
impl Player {
|
||||||
pub fn new(spawn: &Vector2) -> Self {
|
pub fn new(spawn: &Vector2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
additional_vel: Vector2::zero(),
|
||||||
boost_percent: 1.0,
|
boost_percent: 1.0,
|
||||||
size: Vector2 { x: 11.0, y: 21.0 },
|
size: Vector2 { x: 11.0, y: 21.0 },
|
||||||
breath_percent: 1.0,
|
breath_percent: 1.0,
|
||||||
@ -74,33 +73,6 @@ impl Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn collides_with_rec(&self, rectangle: &Rectangle) -> bool {
|
pub fn collides_with_rec(&self, rectangle: &Rectangle) -> bool {
|
||||||
// // Build a bounding box of the player by their corners
|
|
||||||
// let top_left_corner = self.position - (self.size / 2.0);
|
|
||||||
// let bottom_right_corner = self.position + (self.size / 2.0);
|
|
||||||
// let top_right_corner = Vector2 {
|
|
||||||
// x: bottom_right_corner.x,
|
|
||||||
// y: top_left_corner.y,
|
|
||||||
// };
|
|
||||||
// let bottom_left_corner = Vector2 {
|
|
||||||
// x: top_left_corner.x,
|
|
||||||
// y: bottom_right_corner.y,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Get the rotation
|
|
||||||
// let rotation = Vector2::zero().angle_to(self.direction);
|
|
||||||
|
|
||||||
// // Rotate the bounds
|
|
||||||
// let top_left_corner = rotate_vector(top_left_corner, rotation);
|
|
||||||
// let bottom_right_corner = rotate_vector(bottom_right_corner, rotation);
|
|
||||||
// let top_right_corner = rotate_vector(top_right_corner, rotation);
|
|
||||||
// let bottom_left_corner = rotate_vector(bottom_left_corner, rotation);
|
|
||||||
|
|
||||||
// // Check for collisions
|
|
||||||
// return rectangle.check_collision_point_rec(top_left_corner)
|
|
||||||
// || rectangle.check_collision_point_rec(bottom_right_corner)
|
|
||||||
// || rectangle.check_collision_point_rec(top_right_corner)
|
|
||||||
// || rectangle.check_collision_point_rec(bottom_left_corner);
|
|
||||||
|
|
||||||
return rectangle.check_collision_circle_rec(self.position, self.radius);
|
return rectangle.check_collision_circle_rec(self.position, self.radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +98,11 @@ impl Player {
|
|||||||
if octopus.current_position.distance_to(self.position).abs() <= stun_reach {
|
if octopus.current_position.distance_to(self.position).abs() <= stun_reach {
|
||||||
octopus.handle_getting_attacked(self.attacking_timer, current_time);
|
octopus.handle_getting_attacked(self.attacking_timer, current_time);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for whirlpool in world.whirlpool.iter_mut() {
|
||||||
|
if whirlpool.position.distance_to(self.position).abs() <= stun_reach {
|
||||||
|
whirlpool.handle_getting_attacked(self.attacking_timer, current_time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
use failure::Error;
|
use raylib::{
|
||||||
use raylib::{RaylibHandle, RaylibThread, math::Vector2, shaders::Shader, texture::{Image, RenderTexture2D, Texture2D}};
|
math::Vector2,
|
||||||
|
shaders::Shader,
|
||||||
|
texture::{Image, RenderTexture2D, Texture2D},
|
||||||
|
RaylibHandle, RaylibThread,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::lib::wrappers::animation::FrameAnimationWrapper;
|
use crate::lib::wrappers::animation::FrameAnimationWrapper;
|
||||||
|
|
||||||
@ -13,7 +17,7 @@ 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
|
// Fish
|
||||||
pub fish_animation_idle: FrameAnimationWrapper,
|
pub fish_animation_idle: FrameAnimationWrapper,
|
||||||
pub fish_animation_swim: FrameAnimationWrapper,
|
pub fish_animation_swim: FrameAnimationWrapper,
|
||||||
@ -28,10 +32,11 @@ pub struct GlobalResources {
|
|||||||
pub jellyfish_animation_attack: FrameAnimationWrapper,
|
pub jellyfish_animation_attack: FrameAnimationWrapper,
|
||||||
pub octopus_animation_regular: FrameAnimationWrapper,
|
pub octopus_animation_regular: FrameAnimationWrapper,
|
||||||
pub octopus_animation_attack: FrameAnimationWrapper,
|
pub octopus_animation_attack: FrameAnimationWrapper,
|
||||||
|
pub whirlpool: FrameAnimationWrapper,
|
||||||
|
|
||||||
// Darkness layer
|
// Darkness layer
|
||||||
pub darkness_overlay: Texture2D,
|
pub darkness_overlay: Texture2D,
|
||||||
|
|
||||||
// Backgrounds
|
// Backgrounds
|
||||||
pub background_front: Texture2D,
|
pub background_front: Texture2D,
|
||||||
pub background_back: Texture2D,
|
pub background_back: Texture2D,
|
||||||
@ -39,25 +44,24 @@ pub struct GlobalResources {
|
|||||||
// Shop & items
|
// Shop & items
|
||||||
pub shop_background: Texture2D,
|
pub shop_background: Texture2D,
|
||||||
|
|
||||||
pub flashlight_one: Texture2D,
|
pub flashlight_one: Texture2D,
|
||||||
pub flashlight_two: Texture2D,
|
pub flashlight_two: Texture2D,
|
||||||
pub flashlight_three: Texture2D,
|
pub flashlight_three: Texture2D,
|
||||||
|
|
||||||
pub stun_gun_one: Texture2D,
|
pub stun_gun_one: Texture2D,
|
||||||
pub stun_gun_two: Texture2D,
|
pub stun_gun_two: Texture2D,
|
||||||
pub stun_gun_three: Texture2D,
|
pub stun_gun_three: Texture2D,
|
||||||
|
|
||||||
pub air_one: Texture2D,
|
pub air_one: Texture2D,
|
||||||
pub air_two: Texture2D,
|
pub air_two: Texture2D,
|
||||||
pub air_three: Texture2D,
|
pub air_three: Texture2D,
|
||||||
|
|
||||||
pub flippers_one: Texture2D,
|
pub flippers_one: Texture2D,
|
||||||
pub flippers_two: Texture2D,
|
pub flippers_two: Texture2D,
|
||||||
pub flippers_three: Texture2D,
|
pub flippers_three: Texture2D,
|
||||||
|
|
||||||
// Treasure
|
// Treasure
|
||||||
pub transponder: FrameAnimationWrapper,
|
pub transponder: FrameAnimationWrapper,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalResources {
|
impl GlobalResources {
|
||||||
@ -130,7 +134,11 @@ impl GlobalResources {
|
|||||||
&Image::load_image("./assets/img/map/cave.png")?,
|
&Image::load_image("./assets/img/map/cave.png")?,
|
||||||
)?,
|
)?,
|
||||||
pixel_shader: raylib.load_shader(&thread, None, Some("./assets/shaders/pixel.fs"))?,
|
pixel_shader: raylib.load_shader(&thread, None, Some("./assets/shaders/pixel.fs"))?,
|
||||||
shader_texture: raylib.load_render_texture(&thread, raylib.get_screen_width() as u32, raylib.get_screen_height() as u32)?,
|
shader_texture: raylib.load_render_texture(
|
||||||
|
&thread,
|
||||||
|
raylib.get_screen_width() as u32,
|
||||||
|
raylib.get_screen_height() as u32,
|
||||||
|
)?,
|
||||||
jellyfish_animation_regular: FrameAnimationWrapper::new(
|
jellyfish_animation_regular: FrameAnimationWrapper::new(
|
||||||
raylib.load_texture_from_image(
|
raylib.load_texture_from_image(
|
||||||
&thread,
|
&thread,
|
||||||
@ -240,7 +248,15 @@ impl GlobalResources {
|
|||||||
6,
|
6,
|
||||||
2,
|
2,
|
||||||
),
|
),
|
||||||
|
whirlpool: FrameAnimationWrapper::new(
|
||||||
|
raylib.load_texture_from_image(
|
||||||
|
&thread,
|
||||||
|
&Image::load_image("./assets/img/enemies/whirlpool.png")?,
|
||||||
|
)?,
|
||||||
|
Vector2 { x: 20.0, y: 20.0 },
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
src/world.rs
21
src/world.rs
@ -1,11 +1,17 @@
|
|||||||
use std::{fs::File, io::BufReader};
|
use std::{fs::File, io::BufReader};
|
||||||
|
|
||||||
|
use failure::Error;
|
||||||
use raylib::math::{Rectangle, Vector2};
|
use raylib::math::{Rectangle, Vector2};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::io::Read;
|
|
||||||
use failure::Error;
|
|
||||||
|
|
||||||
use crate::{entities::{enemy::{jellyfish::JellyFish, octopus::Octopus}, fish::FishEntity}, player::Player};
|
use crate::{
|
||||||
|
entities::{
|
||||||
|
enemy::{jellyfish::JellyFish, octopus::Octopus, whirlpool::Whirlpool,},
|
||||||
|
fish::FishEntity,
|
||||||
|
|
||||||
|
},
|
||||||
|
player::Player,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct World {
|
pub struct World {
|
||||||
@ -21,8 +27,10 @@ pub struct World {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub colliders: Vec<Rectangle>,
|
pub colliders: Vec<Rectangle>,
|
||||||
|
|
||||||
|
// Mobs
|
||||||
pub jellyfish: Vec<JellyFish>,
|
pub jellyfish: Vec<JellyFish>,
|
||||||
pub octopus: Vec<Octopus>,
|
pub octopus: Vec<Octopus>,
|
||||||
|
pub whirlpool: Vec<Whirlpool>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +48,7 @@ impl World {
|
|||||||
|
|
||||||
// Init colliders
|
// Init colliders
|
||||||
result.colliders = Vec::new();
|
result.colliders = Vec::new();
|
||||||
for collider in colliders.iter(){
|
for collider in colliders.iter() {
|
||||||
result.colliders.push(Rectangle {
|
result.colliders.push(Rectangle {
|
||||||
x: collider.x - (collider.width / 2.0),
|
x: collider.x - (collider.width / 2.0),
|
||||||
y: collider.y - (collider.height / 2.0),
|
y: collider.y - (collider.height / 2.0),
|
||||||
@ -49,6 +57,8 @@ impl World {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +77,6 @@ impl World {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn load_world_colliders(file: String) -> Result<Vec<Rectangle>, Error> {
|
pub fn load_world_colliders(file: String) -> Result<Vec<Rectangle>, Error> {
|
||||||
// Load the file
|
// Load the file
|
||||||
let file = File::open(file)?;
|
let file = File::open(file)?;
|
||||||
@ -75,4 +84,4 @@ pub fn load_world_colliders(file: String) -> Result<Vec<Rectangle>, Error> {
|
|||||||
|
|
||||||
// Deserialize
|
// Deserialize
|
||||||
Ok(serde_json::from_reader(reader)?)
|
Ok(serde_json::from_reader(reader)?)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user