统一 Image 和 Sprite 语义到目前的 Image/Sprite 结构体而非之前的类定义
This commit is contained in:
@@ -146,7 +146,7 @@ int main(int argc, char* argv[])
|
||||
test_sprite_width,
|
||||
test_sprite_height,
|
||||
RenderData::PixelFormat::RGBA5551);
|
||||
RenderData::SpriteRegion sprite_region(&sprite_img, 0, 0, sprite_img.width, sprite_img.height);
|
||||
RenderData::Sprite sprite(&sprite_img, 0, 0, sprite_img.width, sprite_img.height);
|
||||
|
||||
const std::array<uint16_t, 8 * 4> tileIds = {
|
||||
0, RenderData::Tilemap::EmptyTile, 0, RenderData::Tilemap::EmptyTile, 0, RenderData::Tilemap::EmptyTile, 0, RenderData::Tilemap::EmptyTile,
|
||||
@@ -179,9 +179,9 @@ int main(int argc, char* argv[])
|
||||
ctx.clear_color(clearColor);
|
||||
|
||||
// sprite 测试
|
||||
ctx.draw_sprite(10, 10, sprite_img);
|
||||
ctx.draw_sprite_region_ex(30, 10, sprite_region, 2, false, false);
|
||||
ctx.draw_sprite_region_ex(10, 30, sprite_region, 3, true, false);
|
||||
ctx.draw_sprite(10, 10, sprite);
|
||||
ctx.draw_sprite_ex(30, 10, sprite, 2, false, false);
|
||||
ctx.draw_sprite_ex(10, 30, sprite, 3, true, false);
|
||||
ctx.draw_tilemap(testTilemap, 650, 500, 96, 48, static_cast<int32_t>(frame_start_ms / 20u) % 32, 0);
|
||||
|
||||
// FPS 计数
|
||||
|
||||
+166687
-166687
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
#include "Color.h"
|
||||
#include "DrawContext.h"
|
||||
#include "PointerInput.h"
|
||||
#include "SpriteRegion.h"
|
||||
#include "Sprite.h"
|
||||
#include "tom_atlas.h"
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
@@ -19,7 +19,7 @@ namespace
|
||||
const int32_t TomBottomPadding = 72;
|
||||
const int32_t ButtonBottomPadding = 16;
|
||||
|
||||
const RenderData::SpriteRegion* const SpeakingFrames[] = {
|
||||
const RenderData::Sprite* const SpeakingFrames[] = {
|
||||
&TomAtlas::tom_say1,
|
||||
&TomAtlas::tom_say2,
|
||||
&TomAtlas::tom_say3,
|
||||
@@ -28,7 +28,7 @@ namespace
|
||||
&TomAtlas::tom_say2
|
||||
};
|
||||
|
||||
static const RenderData::SpriteRegion& SelectSpeakingFrame(uint32_t animationMs)
|
||||
static const RenderData::Sprite& SelectSpeakingFrame(uint32_t animationMs)
|
||||
{
|
||||
const size_t frameCount = sizeof(SpeakingFrames) / sizeof(SpeakingFrames[0]);
|
||||
const size_t frameIndex = (animationMs / SpeakingFrameMs) % frameCount;
|
||||
@@ -113,9 +113,9 @@ namespace Game
|
||||
void TomGameApp::draw(Core::DrawContext& ctx)
|
||||
{
|
||||
ctx.clear_color(RenderData::Color(18, 18, 24, 255));
|
||||
ctx.draw_sprite_region(0, 0, TomAtlas::background);
|
||||
ctx.draw_sprite(0, 0, TomAtlas::background);
|
||||
|
||||
const RenderData::SpriteRegion* tom = &TomAtlas::tom_stand;
|
||||
const RenderData::Sprite* tom = &TomAtlas::tom_stand;
|
||||
if (state == TomGameState::Recording)
|
||||
{
|
||||
tom = &TomAtlas::tom_listhen;
|
||||
@@ -132,8 +132,8 @@ namespace Game
|
||||
tomY = 0;
|
||||
}
|
||||
|
||||
ctx.draw_sprite_region(tomX, tomY, *tom);
|
||||
ctx.draw_sprite_region(buttonX, buttonY, TomAtlas::ui_record);
|
||||
ctx.draw_sprite(tomX, tomY, *tom);
|
||||
ctx.draw_sprite(buttonX, buttonY, TomAtlas::ui_record);
|
||||
}
|
||||
|
||||
void TomGameApp::update_input(bool& recordTrigger)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "AnimationSystem.h"
|
||||
#include "SpriteRasterizer.h"
|
||||
#include "DrawContext.h"
|
||||
|
||||
namespace Game
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationSystem::draw(Rasterizer::SpriteRasterizer& spriteRasterizer) const
|
||||
void AnimationSystem::draw(Core::DrawContext& drawContext) const
|
||||
{
|
||||
for (size_t i = 0; i < objects.size(); ++i)
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace Game
|
||||
const RenderData::Sprite* sprite = object.animator->get_current_sprite();
|
||||
if (sprite != nullptr)
|
||||
{
|
||||
spriteRasterizer.DrawSprite(*sprite, object.x, object.y);
|
||||
drawContext.draw_sprite(object.x, object.y, *sprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#include <vector>
|
||||
#include "../components/SpriteAnimator.h"
|
||||
|
||||
namespace Rasterizer
|
||||
namespace Core
|
||||
{
|
||||
class SpriteRasterizer;
|
||||
class DrawContext;
|
||||
}
|
||||
|
||||
namespace Game
|
||||
@@ -38,7 +38,7 @@ namespace Game
|
||||
void clear();
|
||||
|
||||
void update(float deltaTime);
|
||||
void draw(Rasterizer::SpriteRasterizer& spriteRasterizer) const;
|
||||
void draw(Core::DrawContext& drawContext) const;
|
||||
|
||||
void set_position(size_t index, int32_t x, int32_t y);
|
||||
void set_visible(size_t index, bool visible);
|
||||
|
||||
@@ -331,7 +331,7 @@ namespace
|
||||
const std::vector<uint16_t>& atlas_pixels,
|
||||
int32_t atlas_height)
|
||||
{
|
||||
std::ofstream file(OutputHeaderPath);
|
||||
std::ofstream file(OutputHeaderPath, std::ios::binary);
|
||||
if (!file.good())
|
||||
{
|
||||
std::cerr << "Open output header failed: " << OutputHeaderPath << std::endl;
|
||||
@@ -342,7 +342,7 @@ namespace
|
||||
file << "#pragma once\n";
|
||||
file << "#include <cstdint>\n";
|
||||
file << "#include \"Image.h\"\n";
|
||||
file << "#include \"SpriteRegion.h\"\n\n";
|
||||
file << "#include \"Sprite.h\"\n\n";
|
||||
file << "namespace TomAtlas\n";
|
||||
file << "{\n";
|
||||
file << "\tstatic const int32_t tom_atlas_width = " << AtlasWidth << ";\n";
|
||||
@@ -355,8 +355,15 @@ namespace
|
||||
const size_t end = std::min(i + 12, atlas_pixels.size());
|
||||
for (size_t j = i; j < end; ++j)
|
||||
{
|
||||
if (j > i)
|
||||
{
|
||||
file << " ";
|
||||
}
|
||||
WritePixel5551(file, atlas_pixels[j]);
|
||||
file << ", ";
|
||||
if (j + 1 < atlas_pixels.size())
|
||||
{
|
||||
file << ",";
|
||||
}
|
||||
}
|
||||
file << "\n";
|
||||
}
|
||||
@@ -369,7 +376,7 @@ namespace
|
||||
for (size_t i = 0; i < regions.size(); ++i)
|
||||
{
|
||||
const AtlasRegion& region = regions[i];
|
||||
file << "\tstatic const RenderData::SpriteRegion "
|
||||
file << "\tstatic const RenderData::Sprite "
|
||||
<< region.source->region_name
|
||||
<< "(&image, "
|
||||
<< region.x << ", "
|
||||
|
||||
@@ -60,53 +60,39 @@ namespace Core
|
||||
triangleRasterizer->DrawTriangle2D(triangle, color);
|
||||
}
|
||||
|
||||
void DrawContext::draw_sprite(int32_t dst_x, int32_t dst_y, const RenderData::Image& img)
|
||||
void DrawContext::draw_sprite(int32_t dst_x, int32_t dst_y, const RenderData::Sprite& sprite)
|
||||
{
|
||||
draw_sprite_region(dst_x, dst_y, img, 0, 0, img.width, img.height);
|
||||
draw_sprite_ex(dst_x, dst_y, sprite, 1, false, false);
|
||||
}
|
||||
|
||||
void DrawContext::draw_sprite(int32_t dst_x, int32_t dst_y, const RenderData::SpriteRegion& region)
|
||||
void DrawContext::draw_sprite_ex(int32_t dst_x, int32_t dst_y, const RenderData::Sprite& sprite,
|
||||
int32_t scale, bool flip_h, bool flip_v)
|
||||
{
|
||||
draw_sprite_region(dst_x, dst_y, region);
|
||||
}
|
||||
if (!sprite.atlas) return;
|
||||
|
||||
void DrawContext::draw_sprite_region(int32_t dst_x, int32_t dst_y, const RenderData::Image& img,
|
||||
int32_t src_x, int32_t src_y, int32_t src_w, int32_t src_h)
|
||||
{
|
||||
draw_sprite_ex(dst_x, dst_y, img, src_x, src_y, src_w, src_h, 1, false, false);
|
||||
}
|
||||
|
||||
void DrawContext::draw_sprite_region(int32_t dst_x, int32_t dst_y, const RenderData::SpriteRegion& region)
|
||||
{
|
||||
draw_sprite_region_ex(dst_x, dst_y, region, 1, false, false);
|
||||
}
|
||||
|
||||
void DrawContext::draw_sprite_region_ex(int32_t dst_x, int32_t dst_y, const RenderData::SpriteRegion& region,
|
||||
int32_t scale, bool flip_h, bool flip_v)
|
||||
{
|
||||
if (!region.atlas) return;
|
||||
|
||||
draw_sprite_ex(
|
||||
blit_sprite_pixels(
|
||||
dst_x,
|
||||
dst_y,
|
||||
*region.atlas,
|
||||
region.x,
|
||||
region.y,
|
||||
region.width,
|
||||
region.height,
|
||||
*sprite.atlas,
|
||||
sprite.x,
|
||||
sprite.y,
|
||||
sprite.width,
|
||||
sprite.height,
|
||||
scale,
|
||||
flip_h,
|
||||
flip_v);
|
||||
}
|
||||
|
||||
void DrawContext::draw_sprite_ex(int32_t dst_x, int32_t dst_y, const RenderData::Image& img,
|
||||
int32_t src_x, int32_t src_y, int32_t src_w, int32_t src_h,
|
||||
int32_t scale, bool flip_h, bool flip_v)
|
||||
void DrawContext::blit_sprite_pixels(int32_t dst_x, int32_t dst_y,
|
||||
const RenderData::Image& image,
|
||||
int32_t src_x, int32_t src_y,
|
||||
int32_t src_w, int32_t src_h,
|
||||
int32_t scale, bool flip_h, bool flip_v)
|
||||
{
|
||||
if (scale < 1 || !img.pixels || src_w <= 0 || src_h <= 0) return;
|
||||
if (src_x < 0 || src_y < 0 || src_x + src_w > img.width || src_y + src_h > img.height) return;
|
||||
if (scale < 1 || !image.pixels || src_w <= 0 || src_h <= 0) return;
|
||||
if (src_x < 0 || src_y < 0 || src_x + src_w > image.width || src_y + src_h > image.height) return;
|
||||
|
||||
const int32_t img_w = img.width;
|
||||
const int32_t img_w = image.width;
|
||||
const int32_t screen_w = frameBuffer->get_width();
|
||||
const int32_t screen_h = frameBuffer->get_height();
|
||||
const int32_t draw_w = src_w * scale;
|
||||
@@ -126,7 +112,7 @@ namespace Core
|
||||
|
||||
Core::FramePixel* dst = static_cast<Core::FramePixel*>(frameBuffer->get_buffer());
|
||||
const int32_t fb_w = frameBuffer->get_width();
|
||||
const uint16_t* src = static_cast<const uint16_t*>(img.pixels);
|
||||
const uint16_t* src = static_cast<const uint16_t*>(image.pixels);
|
||||
|
||||
if (scale == 1)
|
||||
{
|
||||
@@ -249,9 +235,9 @@ namespace Core
|
||||
const int32_t clipped_w = clipped_right - clipped_left;
|
||||
const int32_t clipped_h = clipped_bottom - clipped_top;
|
||||
|
||||
draw_sprite_ex(clipped_left, clipped_top, *tilemap.atlas,
|
||||
clipped_src_x, clipped_src_y, clipped_w, clipped_h,
|
||||
1, false, false);
|
||||
blit_sprite_pixels(clipped_left, clipped_top, *tilemap.atlas,
|
||||
clipped_src_x, clipped_src_y, clipped_w, clipped_h,
|
||||
1, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "Vector2.h"
|
||||
#include "Triangle.h"
|
||||
#include "Image.h"
|
||||
#include "SpriteRegion.h"
|
||||
#include "Sprite.h"
|
||||
#include "Tilemap.h"
|
||||
#include "BitmapFont.h"
|
||||
#include <cstdint>
|
||||
@@ -41,6 +41,12 @@ namespace Core
|
||||
int32_t dst_x, int32_t dst_y,
|
||||
uint16_t pixel);
|
||||
|
||||
void blit_sprite_pixels(int32_t dst_x, int32_t dst_y,
|
||||
const RenderData::Image& image,
|
||||
int32_t src_x, int32_t src_y,
|
||||
int32_t src_w, int32_t src_h,
|
||||
int32_t scale, bool flip_h, bool flip_v);
|
||||
|
||||
public:
|
||||
DrawContext(int32_t width, int32_t height);
|
||||
~DrawContext();
|
||||
@@ -58,15 +64,8 @@ namespace Core
|
||||
void draw_line(const Math::Vector2Int& from, const Math::Vector2Int& to, const RenderData::Color& color);
|
||||
void draw_triangle(const RenderData::Triangle& triangle, const RenderData::Color& color);
|
||||
|
||||
void draw_sprite(int32_t dst_x, int32_t dst_y, const RenderData::Image& img);
|
||||
void draw_sprite(int32_t dst_x, int32_t dst_y, const RenderData::SpriteRegion& region);
|
||||
void draw_sprite_region(int32_t dst_x, int32_t dst_y, const RenderData::Image& img,
|
||||
int32_t src_x, int32_t src_y, int32_t src_w, int32_t src_h);
|
||||
void draw_sprite_region(int32_t dst_x, int32_t dst_y, const RenderData::SpriteRegion& region);
|
||||
void draw_sprite_region_ex(int32_t dst_x, int32_t dst_y, const RenderData::SpriteRegion& region,
|
||||
int32_t scale, bool flip_h, bool flip_v);
|
||||
void draw_sprite_ex(int32_t dst_x, int32_t dst_y, const RenderData::Image& img,
|
||||
int32_t src_x, int32_t src_y, int32_t src_w, int32_t src_h,
|
||||
void draw_sprite(int32_t dst_x, int32_t dst_y, const RenderData::Sprite& sprite);
|
||||
void draw_sprite_ex(int32_t dst_x, int32_t dst_y, const RenderData::Sprite& sprite,
|
||||
int32_t scale, bool flip_h, bool flip_v);
|
||||
void draw_tilemap(const RenderData::Tilemap& tilemap,
|
||||
int32_t screen_x, int32_t screen_y,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace RenderData
|
||||
{
|
||||
struct SpriteRegion
|
||||
struct Sprite
|
||||
{
|
||||
const Image* atlas;
|
||||
int32_t x;
|
||||
@@ -12,10 +12,10 @@ namespace RenderData
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
|
||||
SpriteRegion()
|
||||
Sprite()
|
||||
: atlas(nullptr), x(0), y(0), width(0), height(0) {}
|
||||
|
||||
SpriteRegion(const Image* atlas, int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
Sprite(const Image* atlas, int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
: atlas(atlas), x(x), y(y), width(width), height(height) {}
|
||||
};
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#include "SpriteRasterizer.h"
|
||||
#include "FrameBuffer.h"
|
||||
#include "../RenderData/Image.h"
|
||||
#include "../RenderData/Sprite.h"
|
||||
|
||||
namespace Rasterizer
|
||||
{
|
||||
namespace
|
||||
{
|
||||
inline uint16_t rgba5551_to_rgb565(uint16_t c)
|
||||
{
|
||||
const uint16_t r = static_cast<uint16_t>((c >> 11) & 0x1Fu);
|
||||
const uint16_t g = static_cast<uint16_t>((c >> 6) & 0x1Fu);
|
||||
const uint16_t b = static_cast<uint16_t>((c >> 1) & 0x1Fu);
|
||||
const uint16_t g6 = static_cast<uint16_t>((g << 1) | (g >> 4));
|
||||
return static_cast<uint16_t>((r << 11) | (g6 << 5) | b);
|
||||
}
|
||||
|
||||
inline bool rgba5551_is_opaque(uint16_t c)
|
||||
{
|
||||
return (c & 0x1u) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteRasterizer::DrawImage(const RenderData::Image& image, int32_t x, int32_t y)
|
||||
{
|
||||
DrawSprite(RenderData::Sprite(&image), x, y);
|
||||
}
|
||||
|
||||
void SpriteRasterizer::DrawSprite(const RenderData::Sprite& sprite, int32_t x, int32_t y)
|
||||
{
|
||||
if (frameBuffer == nullptr || !sprite.is_valid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int32_t minX = x < 0 ? -x : 0;
|
||||
const int32_t minY = y < 0 ? -y : 0;
|
||||
const int32_t maxX = x + sprite.width > frameBuffer->get_width() ? frameBuffer->get_width() - x : sprite.width;
|
||||
const int32_t maxY = y + sprite.height > frameBuffer->get_height() ? frameBuffer->get_height() - y : sprite.height;
|
||||
|
||||
if (minX >= maxX || minY >= maxY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Core::FramePixel* dst = static_cast<Core::FramePixel*>(frameBuffer->get_buffer());
|
||||
const int32_t fb_w = frameBuffer->get_width();
|
||||
|
||||
for (int32_t sy = minY; sy < maxY; ++sy)
|
||||
{
|
||||
Core::FramePixel* dst_row = dst + (y + sy) * fb_w;
|
||||
for (int32_t sx = minX; sx < maxX; ++sx)
|
||||
{
|
||||
const uint16_t color = sprite.get_pixel_fast(sx, sy);
|
||||
if (!rgba5551_is_opaque(color))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dst_row[x + sx] = rgba5551_to_rgb565(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class FrameBuffer;
|
||||
}
|
||||
|
||||
namespace RenderData
|
||||
{
|
||||
class Image;
|
||||
struct Sprite;
|
||||
}
|
||||
|
||||
namespace Rasterizer
|
||||
{
|
||||
class SpriteRasterizer
|
||||
{
|
||||
private:
|
||||
Core::FrameBuffer* frameBuffer;
|
||||
|
||||
public:
|
||||
explicit SpriteRasterizer(Core::FrameBuffer* frameBuffer) : frameBuffer(frameBuffer) {}
|
||||
|
||||
void DrawImage(const RenderData::Image& image, int32_t x, int32_t y);
|
||||
void DrawSprite(const RenderData::Sprite& sprite, int32_t x, int32_t y);
|
||||
};
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
namespace RenderData
|
||||
{
|
||||
class Image
|
||||
{
|
||||
private:
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
std::vector<uint16_t> pixels;
|
||||
|
||||
static bool calculate_pixel_count(int32_t width, int32_t height, size_t& count)
|
||||
{
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
count = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t safeWidth = static_cast<size_t>(width);
|
||||
const size_t safeHeight = static_cast<size_t>(height);
|
||||
if (safeWidth > std::numeric_limits<size_t>::max() / safeHeight)
|
||||
{
|
||||
count = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
count = safeWidth * safeHeight;
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
Image() : width(0), height(0) {}
|
||||
|
||||
Image(int32_t width, int32_t height) : width(0), height(0)
|
||||
{
|
||||
size_t pixelCount = 0;
|
||||
if (calculate_pixel_count(width, height, pixelCount))
|
||||
{
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
pixels.assign(pixelCount, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Image(int32_t width, int32_t height, const std::vector<uint16_t>& pixels) : width(0), height(0)
|
||||
{
|
||||
size_t pixelCount = 0;
|
||||
if (calculate_pixel_count(width, height, pixelCount) && pixels.size() == pixelCount)
|
||||
{
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->pixels = pixels;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t get_width() const { return width; }
|
||||
|
||||
int32_t get_height() const { return height; }
|
||||
|
||||
size_t total_pixels() const { return pixels.size(); }
|
||||
|
||||
const uint16_t* data() const { return pixels.data(); }
|
||||
|
||||
uint16_t* data() { return pixels.data(); }
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
size_t pixelCount = 0;
|
||||
return calculate_pixel_count(width, height, pixelCount) && pixels.size() == pixelCount;
|
||||
}
|
||||
|
||||
uint16_t get_pixel(int32_t x, int32_t y) const
|
||||
{
|
||||
if (x < 0 || x >= width || y < 0 || y >= height)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t index = static_cast<size_t>(y) * width + x;
|
||||
return pixels[index];
|
||||
}
|
||||
|
||||
uint16_t get_pixel_fast(int32_t x, int32_t y) const
|
||||
{
|
||||
size_t index = static_cast<size_t>(y) * width + x;
|
||||
return pixels[index];
|
||||
}
|
||||
|
||||
void set_pixel(int32_t x, int32_t y, uint16_t color)
|
||||
{
|
||||
if (x < 0 || x >= width || y < 0 || y >= height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
size_t index = static_cast<size_t>(y) * width + x;
|
||||
pixels.at(index) = color;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include "Image.h"
|
||||
|
||||
namespace RenderData
|
||||
{
|
||||
struct Sprite
|
||||
{
|
||||
const Image* image;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
|
||||
Sprite() : image(nullptr), x(0), y(0), width(0), height(0) {}
|
||||
|
||||
Sprite(const Image* image) :
|
||||
image(image),
|
||||
x(0),
|
||||
y(0),
|
||||
width(image ? image->get_width() : 0),
|
||||
height(image ? image->get_height() : 0)
|
||||
{}
|
||||
|
||||
Sprite(const Image* image, int32_t x, int32_t y, int32_t width, int32_t height) :
|
||||
image(image),
|
||||
x(x),
|
||||
y(y),
|
||||
width(width),
|
||||
height(height)
|
||||
{}
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
if (image == nullptr || !image->is_valid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x < 0 || y < 0 || width <= 0 || height <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return x + width <= image->get_width() && y + height <= image->get_height();
|
||||
}
|
||||
|
||||
uint16_t get_pixel(int32_t localX, int32_t localY) const
|
||||
{
|
||||
if (!is_valid() || localX < 0 || localX >= width || localY < 0 || localY >= height)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return image->get_pixel(x + localX, y + localY);
|
||||
}
|
||||
|
||||
uint16_t get_pixel_fast(int32_t localX, int32_t localY) const
|
||||
{
|
||||
return image->get_pixel_fast(x + localX, y + localY);
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user