我想生成一组精灵,每个精灵大小为32x32。如何使用C ++执行此操作,不使用库。 纹理类:
class Texture
{
protected:
// We cannot create or copy base class texture objects
// We will only ever have pointers or references to base
// class texture objects used in our program (and these
// will refer to derived class textures
Texture() = default;
Texture(Texture const &) = default;
Texture & operator=(Texture const &) = default;
virtual void LoadFromFile(std::string const & strFileName) = 0;
virtual void LoadFromResource(unsigned int rid) = 0;
public:
virtual ~Texture(){}
// virtual Rect const & GetBounds() const = 0;
virtual int Width() const = 0;
virtual int Height() const = 0;
};
using TEXTURE_PTR = std::shared_ptr<Texture>;
Sprite类:
class Sprite
{
private:
virtual void draw_impl(Canvas & c) = 0;
TEXTURE_PTR m_pTexture;
protected:
// Ensure that Sprite objects can only be constructed by derived classes
explicit Sprite(TEXTURE_PTR pt = nullptr,POINT2f const & p = { 0, 0 });
// All Sprite objects have a position state variable
POINT2f m_position;
// Sprite objects can only be copied by derived class objects
Sprite(const Sprite&) = default;
Sprite& operator=(const Sprite&) = default;
public:
virtual ~Sprite(){}
void OnDraw(Canvas & c);
void SetPosition(POINT2f const & pos);
POINT2f const & GetPosition() const;
void SetTexture(TEXTURE_PTR pt);
};
我以这种方式创建精灵:
TEXTURE_PTR pLightning = std::make_shared<Texture>("resource//Lightning.bmp", RGB(255, 0, 255));
std::shared_ptr<Sprite> pSpark = std::make_shared<Sprite>(pLightning);
如何使用此方法从上面的图像生成9个精灵?
修改 我想出了这些代码,但仍然没有工作
class WinTexture : public Texture
{
protected:
HBITMAP m_hbmImage;
HBITMAP m_hbmMask;
BITMAP m_bmParam;
virtual void LoadFromResource(UINT rid);
virtual void LoadFromFile(std::string const & strFileName);
void CreateMask(DWORD dwTransparent);
public:
// Construct from Windows Resource
WinTexture(UINT uid, COLORREF dwTransparent);
// Constructor from file load
WinTexture(std::string const & strFilename, COLORREF dwTransparent);
//Contruct from other Texture
WinTexture(std::shared_ptr<WinTexture> wt, int xStart,int yStart, int w, int h);
virtual ~WinTexture();
// Inherited interface
// virtual Rect const & GetBounds() const;
virtual int Width() const;
virtual int Height() const;
HBITMAP ImageHandle() const;
HBITMAP MaskHandle() const;
};
有了这个,我想创建一个构造函数来创建其他WinTexture:
WinTexture::WinTexture(std::shared_ptr<WinTexture> wt, int xStart, int yStart, int w, int h)
: Texture(), // as above
m_hbmImage(NULL),
m_hbmMask(NULL) {
HDC hdcMem1 = CreateCompatibleDC(0);
HDC hdcMem2 = CreateCompatibleDC(0);
m_hbmImage = CreateBitmap(w, h, 1, 1, NULL);
//m_hbmImage = CreateCompatibleBitmap(hdcMem2, 1, 1);
SelectObject(hdcMem1, wt->ImageHandle());
SelectObject(hdcMem2, m_hbmImage);
BitBlt(hdcMem2, xStart, yStart, w, h,hdcMem1, 0, 0, SRCCOPY);
BitBlt(hdcMem1, xStart, yStart, w, h, hdcMem2, 0, 0, SRCINVERT);
//SaveDC(hdcMem2);
DeleteDC(hdcMem1);
DeleteDC(hdcMem2);
CreateMask(RGB(0, 0, 0));
}
修改 目前,我已经从Sprite创建了这个类:
class TexturedSprite : public Sprite
{
private:
TEXTURE_PTR m_pTexture;
virtual void draw_impl(Canvas & c);
protected:
public:
explicit TexturedSprite(TEXTURE_PTR pt = nullptr, POINT2f pos = { 32, 32});
explicit TexturedSprite(int xStart,int yStart, int w, int h,TEXTURE_PTR pt = nullptr, POINT2f pos = { 32, 32 });
virtual ~TexturedSprite(){}
void SetTexture(TEXTURE_PTR pt);
};
我无法弄清楚如何实现第二个构造函数,复制输入纹理的一部分(pt):
TexturedSprite::TexturedSprite(int xStart, int yStart, int w, int h, TEXTURE_PTR pt , POINT2f pos )
:Sprite(pos)
{
HDC hdcMem1 = CreateCompatibleDC(0);
HDC hdcMem2 = CreateCompatibleDC(0);
//How to assign values to DC?
BitBlt(hdcMem1, 32, 32, w, h, hdcMem2, xStart, yStart, SRCCOPY);
DeleteDC(hdcMem1);
DeleteDC(hdcMem2);
}
答案 0 :(得分:2)
至少在我现在阅读的时候,你的基本意图是加载纹理,然后通过将纹理的32x32像素块复制到各个精灵中来创建单个精灵。除非你打算从单独的线程中操纵精灵(这让我觉得不太可能),否则我会避免这样做。
相反,我注意到你提供给BitBlt的几个最后一个参数:
var pipeline = [
{
"$group": {
"_id": "$beatmapset_id",
"count": { "$sum": 1 },
"uniqueIds": { "$addToSet": "$_id" },
"maxRating": { "$max": "$difficultyrating" }
}
},
{
"$match": {
"count": { "$gte": 2 }
}
},
{
"$sort" : { "count" : -1 }
}
],
counter = 0,
bulk = db.collection.initializeOrderedBulkOp();
db.collection.aggregate(pipeline).forEach(function(doc) {
bulk.find({
"_id": { "$in": doc.uniqueIds },
"difficultyrating": { "$lt": doc.maxRating }
}).remove();
counter++;
if ( counter % 500 == 0 ) {
// Execute per 500 operations and re-init.
bulk.execute();
bulk = db.mycollection.initializeOrderedBulkOp();
}
});
// Catch any under or over the 500's and clean up queues
if (counter % 500 != 0)
bulk.execute();
BitBlt(hdcMem2, xStart, yStart, w, h,hdcMem1, 0, 0, SRCCOPY);
之前的0, 0
指定源位图中的位置,以用作SRCCOPY
的起点。
这使您可以加载纹理一次,并将该单个纹理用于它包含的所有精灵。在特定位置绘制单个精灵只需要在源位图(特别是该精灵的左上角)中指定该精灵的X,Y坐标,并从那里开始绘制一个32x32块。如果你想定义单独的精灵对象,你当然可以这样做,但每个只需要将BitBlt
这样的东西存储到加载的纹理,以及它的纹理片段的X,Y坐标。
shared_ptr
答案 1 :(得分:0)
如果您真的不想使用任何库,则需要手动解码BMP文件。查看this Wikipedia条目,了解有关BMP文件格式结构的更多信息。