Implement Sprite class
This commit is contained in:
parent
d4c91450d9
commit
bb9d108102
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
|
|
@ -0,0 +1,84 @@
|
|||
module;
|
||||
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
export module core.drawing.sprite;
|
||||
|
||||
import core.render_server;
|
||||
import wrappers.sdl;
|
||||
|
||||
export namespace core
|
||||
{
|
||||
class Sprite
|
||||
{
|
||||
// Texture ID (managed by TextureManager in RenderServer)
|
||||
TextureID texture_id_;
|
||||
|
||||
// Texture source boundaries: which part of the texture to render
|
||||
sdl::FRect texture_boundaries_;
|
||||
|
||||
// Texture offset: static offset that is added to the render position (BEFORE scale is applied)
|
||||
sdl::FPoint texture_offset_{0, 0};
|
||||
|
||||
// Texture scale: factors applied to width/height (AFTER offset is applied)
|
||||
// TODO: Proper vector class?
|
||||
sdl::FPoint texture_scale_{1, 1};
|
||||
|
||||
// Sprite position: where to render the sprite (world coordinates)
|
||||
sdl::FPoint position_{0, 0};
|
||||
|
||||
public:
|
||||
explicit Sprite(
|
||||
const TextureID texture_id,
|
||||
const sdl::FRect texture_boundaries,
|
||||
const sdl::FPoint position,
|
||||
const sdl::FPoint texture_offset = {0, 0},
|
||||
const sdl::FPoint texture_scale = {1, 1}
|
||||
)
|
||||
: texture_id_{texture_id},
|
||||
texture_boundaries_{texture_boundaries},
|
||||
texture_offset_{texture_offset},
|
||||
texture_scale_{texture_scale},
|
||||
position_{position}
|
||||
{
|
||||
assert(texture_boundaries_.w > 0 && texture_boundaries_.h > 0);
|
||||
}
|
||||
|
||||
static Sprite create_with_texture(
|
||||
RenderServer& render_server,
|
||||
const std::string& filename,
|
||||
std::optional<sdl::FRect> texture_boundaries,
|
||||
auto... args
|
||||
)
|
||||
{
|
||||
const TextureID texture_id = render_server.load_texture(filename);
|
||||
|
||||
if (!texture_boundaries.has_value()) {
|
||||
const sdl::Texture& texture = render_server.get_texture(texture_id);
|
||||
texture_boundaries = texture.get_boundaries();
|
||||
}
|
||||
|
||||
return Sprite(texture_id, texture_boundaries.value(), args...);
|
||||
}
|
||||
|
||||
void set_position(const sdl::FPoint new_position)
|
||||
{
|
||||
position_ = new_position;
|
||||
}
|
||||
|
||||
void draw(const RenderServer& render_server) const
|
||||
{
|
||||
const sdl::FRect dest_rect{
|
||||
position_.x + (texture_scale_.x * texture_offset_.x),
|
||||
position_.y + (texture_scale_.y * texture_offset_.y),
|
||||
texture_scale_.x * texture_boundaries_.w,
|
||||
texture_scale_.y * texture_boundaries_.h,
|
||||
};
|
||||
|
||||
render_server.render_texture(texture_id_, &texture_boundaries_, &dest_rect);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -43,13 +43,21 @@ export namespace core
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads a texture from a file (if not loaded yet) and returns its texture ID.
|
||||
* Load a texture from a file (if not loaded yet) and return its texture ID.
|
||||
*/
|
||||
constexpr TextureID load_texture(const std::string& filename)
|
||||
{
|
||||
return texture_manager_.load_resource_by_name(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to a texture by its texture ID.
|
||||
*/
|
||||
constexpr const sdl::Texture& get_texture(const TextureID texture_id) const
|
||||
{
|
||||
return texture_manager_.get_resource(texture_id);
|
||||
}
|
||||
|
||||
void start_frame() const
|
||||
{
|
||||
renderer_.clear();
|
||||
|
|
@ -60,16 +68,16 @@ export namespace core
|
|||
renderer_.present();
|
||||
}
|
||||
|
||||
constexpr void render_texture(
|
||||
void render_texture(
|
||||
const TextureID texture_id,
|
||||
const sdl::FRect* src_rect,
|
||||
const sdl::FRect* dest_rect
|
||||
) const
|
||||
{
|
||||
render_texture(texture_manager_.get_resource(texture_id), src_rect, dest_rect);
|
||||
render_texture(get_texture(texture_id), src_rect, dest_rect);
|
||||
}
|
||||
|
||||
void render_texture(
|
||||
constexpr void render_texture(
|
||||
const sdl::Texture& texture,
|
||||
const sdl::FRect* src_rect,
|
||||
const sdl::FRect* dest_rect
|
||||
|
|
|
|||
|
|
@ -2,14 +2,15 @@ module;
|
|||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
export module game.game;
|
||||
|
||||
import core.drawing.sprite;
|
||||
import core.engine;
|
||||
import core.render_server;
|
||||
import game.sprite;
|
||||
import wrappers.sdl;
|
||||
import wrappers.sdl_image;
|
||||
|
||||
|
|
@ -24,15 +25,20 @@ export namespace game
|
|||
core::Engine& engine_;
|
||||
|
||||
// Sprites for testing
|
||||
Sprite player_sprite_;
|
||||
std::vector<Sprite> sprites_;
|
||||
core::Sprite player_sprite_;
|
||||
std::vector<core::Sprite> sprites_;
|
||||
|
||||
// Private constructor
|
||||
explicit Game(core::Engine& engine)
|
||||
: engine_(engine),
|
||||
player_sprite_{
|
||||
engine_.get_render_server().load_texture("assets/neocat.png"),
|
||||
sdl::FRect{0, 0, 100, 100}
|
||||
core::Sprite::create_with_texture(
|
||||
engine_.get_render_server(),
|
||||
"assets/sprites/neocat_64.png",
|
||||
std::nullopt,
|
||||
sdl::FPoint{0, 0},
|
||||
sdl::FPoint{-32, -32}
|
||||
)
|
||||
}
|
||||
{}
|
||||
|
||||
|
|
@ -63,21 +69,19 @@ export namespace game
|
|||
bool handle_event(const sdl::Event* event)
|
||||
{
|
||||
if (event->type == sdl::EventType::MouseMotion) {
|
||||
player_sprite_.move(
|
||||
event->motion.x - 50,
|
||||
event->motion.y - 50
|
||||
);
|
||||
player_sprite_.set_position({event->motion.x, event->motion.y});
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event->type == sdl::EventType::MouseButtonUp) {
|
||||
sprites_.emplace_back(
|
||||
engine_.get_render_server().load_texture("assets/neofox.png"),
|
||||
sdl::FRect{
|
||||
event->motion.x - 50,
|
||||
event->motion.y - 50,
|
||||
100, 100
|
||||
}
|
||||
sprites_.push_back(
|
||||
core::Sprite::create_with_texture(
|
||||
engine_.get_render_server(),
|
||||
"assets/sprites/neofox_64.png",
|
||||
std::nullopt,
|
||||
sdl::FPoint{event->motion.x, event->motion.y},
|
||||
sdl::FPoint{-32, -32}
|
||||
)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -94,7 +98,7 @@ export namespace game
|
|||
const auto& render_server = engine_.get_render_server();
|
||||
render_server.start_frame();
|
||||
|
||||
for (const Sprite& sprite : sprites_) {
|
||||
for (const core::Sprite& sprite : sprites_) {
|
||||
sprite.draw(render_server);
|
||||
}
|
||||
player_sprite_.draw(render_server);
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
module;
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
export module game.sprite;
|
||||
|
||||
import core.render_server;
|
||||
import wrappers.sdl;
|
||||
|
||||
// TODO: Move this to a different namespace (core, drawing, ...?)
|
||||
export namespace game
|
||||
{
|
||||
class Sprite
|
||||
{
|
||||
core::TextureID texture_id_;
|
||||
sdl::FRect dest_rect_{0, 0, 0, 0};
|
||||
|
||||
public:
|
||||
explicit Sprite(const core::TextureID texture_id, const sdl::FRect dest_rect)
|
||||
: texture_id_{texture_id},
|
||||
dest_rect_{dest_rect}
|
||||
{}
|
||||
|
||||
void move(const float x, const float y)
|
||||
{
|
||||
dest_rect_.x = x;
|
||||
dest_rect_.y = y;
|
||||
}
|
||||
|
||||
void draw(const core::RenderServer& render_server) const
|
||||
{
|
||||
render_server.render_texture(texture_id_, nullptr, &dest_rect_);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -35,6 +35,21 @@ export namespace sdl
|
|||
assert(raw_texture_);
|
||||
return raw_texture_.get();
|
||||
}
|
||||
|
||||
constexpr int get_width() const
|
||||
{
|
||||
return raw_texture_->w;
|
||||
}
|
||||
|
||||
constexpr int get_height() const
|
||||
{
|
||||
return raw_texture_->h;
|
||||
}
|
||||
|
||||
constexpr FRect get_boundaries() const
|
||||
{
|
||||
return {0, 0, static_cast<float>(raw_texture_->w), static_cast<float>(raw_texture_->h)};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue