Skip to content
Snippets Groups Projects
Commit f37c1a18 authored by PierreEVEN's avatar PierreEVEN
Browse files

fixed terrain reset on death and added some comments

parent e08d2a69
Branches
No related merge requests found
......@@ -5,6 +5,13 @@
#include <optional>
#include <engine/format.hpp>
// Multiplateform logger utility
// Helper macro - Usages examples :
// INFO("my log");
// WARNING("this is a warning of {}", value);
// FATAL("Program termination");
#if defined(_MSC_VER)
#define DEBUG(format_str, ...) ::pm::Logger::get().message(::pm::ELogLevel::DEBUG, std::format_2(format_str, __VA_ARGS__), __FILE__, ##__FUNCTION__, __LINE__)
#define INFO(format_str, ...) ::pm::Logger::get().message(::pm::ELogLevel::INFO, std::format_2(format_str, __VA_ARGS__), __FILE__, ##__FUNCTION__, __LINE__)
......@@ -45,9 +52,11 @@ class Logger
public:
static Logger& get();
// Add a new log message
void message(const ELogLevel level, const std::string& text, const std::optional<std::string>& file= {}, const std::optional<std::string>& function = {}, const std::optional<size_t>& line= {});
private:
// Safety for parallel printing
std::mutex print_lock;
};
}
......@@ -9,18 +9,21 @@ namespace pm
{
class Terrain;
// Utility class used to find path on given terrain using A* algorithm (// not used anymore in current program)
class PathFinder
{
public:
PathFinder(const std::shared_ptr<Terrain>& in_terrain);
// Update path (only heavy if from and to have changed)
bool find_path(const Vector2I& from, Vector2I to);
// Advance in computed path and get direction to next path point
// Return Direction::NONE when complete
Direction direction_to_next_point(const Vector2I& current_location);
private:
std::vector<Vector2I> actual_path;
std::shared_ptr<Terrain> terrain;
};
}
\ No newline at end of file
......@@ -8,6 +8,10 @@
#include "format.hpp"
#include "vector2.hpp"
/*
* Sprite system : sprite containers and handles
*/
struct SDL_Surface;
namespace pm
......@@ -15,6 +19,9 @@ namespace pm
class SpriteHandle;
class SpriteSheet;
/*
* Contains all runtime information about a sprite. There can be multiple instances of SpriteInfo for the same texture. (if it requires separated behaviors)
*/
class SpriteInfo
{
friend SpriteSheet;
......@@ -26,16 +33,24 @@ public:
private:
double animation_speed;
// Coordinates of the image on the sprite sheet
SDL_Rect sprite_base_pos;
// The animation system cycle through the different offset in the sprite sheet (in addition of default sprite location)
std::vector<Vector2I> sprite_offsets;
// Should we pause animation
bool paused = false;
// Internal animation time. Can be reset using SpriteHandle::reset_timer();
double internal_time = 0.0;
// Used to compute time delta between draw calls and update internal time.
std::chrono::steady_clock::time_point last_time;
};
} // namespace pm
namespace pm
{
/*
* Abstract representation of SpriteInfo. It's like a smart pointer (without internal reference counter)
*/
class SpriteHandle
{
friend std::stringstream& operator<<(std::stringstream& stream, const SpriteHandle& s);
......@@ -46,6 +61,7 @@ public:
{
}
// Always produce a null handle until it's owner have been set
SpriteHandle(std::string handle_name)
: handle(std::move(handle_name)), owner(nullptr)
{
......@@ -56,20 +72,23 @@ public:
{
}
// Draw onto given surface (or default surface if null). pos is the offset, (0,0) is top left corner.
void draw(const Vector2I& pos, double scale_x = 1.0, double scale_y = 1.0, SDL_Surface* surface_override = nullptr) const;
// Pause animation cycle
SpriteHandle& set_paused(bool paused);
[[nodiscard]] bool is_paused() const;
// Reset animation timer to initial state
void reset_timer() const;
// Copy / affectation / comparison...
SpriteHandle& operator=(const SpriteHandle& other) = default;
SpriteHandle(const SpriteHandle& other) = default;
SpriteHandle(SpriteHandle&& other) = default;
bool operator==(const SpriteHandle& other) const { return handle == other.handle; }
bool operator==(const SpriteHandle& other) const
{
return handle == other.handle;
}
// test if handle is valid. Ex : if (my_handle) // should be valid there
operator bool() const
{
return owner;
......@@ -80,6 +99,7 @@ private:
SpriteSheet* owner;
};
// Used for debug purposes
inline std::stringstream& operator<<(std::stringstream& stream, const SpriteHandle& s)
{
stream << s.handle.c_str();
......@@ -87,6 +107,7 @@ inline std::stringstream& operator<<(std::stringstream& stream, const SpriteHand
}
} // namespace pm
// Hash
template <>
struct std::hash<::pm::SpriteHandle>
{
......@@ -96,6 +117,10 @@ struct std::hash<::pm::SpriteHandle>
}
};
// Use a given texture as a sprite sheet.
// Don't create multiple sprite sheet for the same textures.
// Generating sprite does not copy texture data. Having multiple sprites for the same image doesn't affect performances.
// WARNING : Sprite sheets are not meant to be destroyed before program completion.
namespace pm
{
class SpriteSheet
......@@ -103,18 +128,25 @@ class SpriteSheet
public:
SpriteSheet(const std::filesystem::path& sprite_sheet);
SpriteHandle new_sprite(const std::string& name, SDL_Rect base_transform, double animation_speed = 1.0, const std::vector<Vector2I>& offsets = {});
// Create a sprite from this sprite sheet. See SpriteInfos for more information.
// Return a sprite handle referencing this sprite.
// Sprite name should always be unique among all the game.
// Creating a new sprite with a name already in use will update all sprites using this name. Be careful, it's not an intended behavior.
SpriteHandle new_sprite(const std::string& name, SDL_Rect base_transform, double animation_speed = 1.0, const std::vector<Vector2I>& offsets = {});
[[nodiscard]] static std::optional<SpriteHandle> find_sprite_by_name(const std::string& name);
// Draw sprite at location
void render_sprite(const SpriteHandle& sprite, Vector2I pos, double scale_x = 1.0, double scale_y = 1.0, SDL_Surface* surface_override = nullptr) const;
[[nodiscard]] static std::optional<SpriteHandle> find_sprite_by_name(const std::string& name);
// Pause sprite animation
void set_paused(SpriteHandle sprite, bool in_paused) const;
[[nodiscard]] bool is_paused(SpriteHandle sprite) const;
// Reset sprite internal time
void reset_timer(SpriteHandle sprite) const;
private:
// Sprite sheet image
SDL_Surface* sprite_sheet_handle;
};
}
......@@ -2,7 +2,9 @@
#include <cstdint>
#include <cmath>
#include <iosfwd>
// Helper to define vector2 operators
#define VECTOR_2_LINEAR_OPERATOR_VECTOR(OP) Vector2 operator##OP(const Vector2& other) const { return {pos_x OP other.pos_x, pos_y OP other.pos_y}; }
#define VECTOR_2_LINEAR_OPERATOR_SCALAR(OP) Vector2 operator##OP(const T& other) const { return {pos_x OP other, pos_y OP other}; }
......@@ -11,6 +13,7 @@
namespace pm
{
// Template class to define a 2 dimension vector of any numeric type.
template <typename T>
class Vector2
{
......@@ -27,12 +30,14 @@ public:
{
}
// Accessors
T& x() { return pos_x; }
T& y() { return pos_y; }
[[nodiscard]] const T& x() const { return pos_x; }
[[nodiscard]] const T& y() const { return pos_y; }
// Operators
VECTOR_2_LINEAR_OPERATOR_VECTOR(+)
VECTOR_2_LINEAR_OPERATOR_VECTOR(-)
VECTOR_2_LINEAR_OPERATOR_VECTOR(/)
......@@ -62,6 +67,7 @@ public:
return pos_x == other.pos_x && pos_y == other.pos_y;
}
// Utilities
[[nodiscard]] T length() const { return static_cast<T>(std::sqrt(static_cast<double>(pos_x * pos_x + pos_y * pos_y))); }
[[nodiscard]] T l1_length() const { return std::max(std::abs(pos_x), std::abs(pos_y)); }
[[nodiscard]] Vector2 normalized() const { return *this / length(); }
......@@ -70,6 +76,7 @@ public:
using InternalType = T;
// Cast this vector2 into another kind vector2
template <typename U>
[[nodiscard]] Vector2<typename U::InternalType> cast() const
{
......@@ -80,10 +87,21 @@ private:
T pos_x = T(0), pos_y = T(0);
};
// Common vector2 usages
using Vector2D = Vector2<double>;
using Vector2I = Vector2<int32_t>;
// Used for printing and debug purpose
template<typename T>
std::stringstream& operator<<(std::stringstream& stream, const Vector2<T>& s)
{
stream << s.x() << ", " << s.y();
return stream;
}
}
// Hash operators
namespace std
{
template <> struct hash<pm::Vector2D>
......
......@@ -4,12 +4,11 @@
#include "engine/direction.hpp"
#include "engine/engine.hpp"
#include "engine/logger.hpp"
#include "engine/pathfinding.hpp"
namespace pm
{
GhostBase::GhostBase(const std::shared_ptr<Terrain>& terrain, std::shared_ptr<Character> in_target)
: Character(terrain), pathfinder(std::make_shared<PathFinder>(terrain)), target(std::move(in_target)), mode(AiMode::Spawned)
: Character(terrain), target(std::move(in_target)), mode(AiMode::Spawned)
{
frightened_sprite = *SpriteSheet::find_sprite_by_name("frightened_ghost");
frightened_sprite_flash = *SpriteSheet::find_sprite_by_name("frightened_ghost_flash");
......
......@@ -41,7 +41,6 @@ protected:
return in_dir.is_up() ? Vector2I{-1, -1} : *in_dir;
}
const std::shared_ptr<PathFinder> pathfinder;
std::shared_ptr<Character> target;
AiMode mode;
Vector2I last_cell = {};
......
......@@ -235,9 +235,7 @@ void PacmanGamemode::reset_positions()
scatter_chase_timer = 0;
is_chase = true;
cycle = 0;
terrain->reset();
for (const auto& entity : entities)
entity->reset();
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment