Here’s the Code from my spriteImage class:
#ifndef TEXTURE
#define TEXTURE
class spriteImage {
private:
//the texture
SDL_Texture* texture;
//texture dimensions
int w;
int h;
//texture coordinates
int x;
int y;
//depth (bigger number is further away / rendered first while lower number rendered later)
int depth;
//REMEMBER! x and y coordinates are from base object class!
public:
//default constructor
spriteImage();
//argument constructor isn't necessary unless you want to create and render the object immediately! (Which is 99% of cases we don't lol).
//loads image at specified path
bool loadFromFile(std::string path);
//deallocates texture
void free();
//Renders texture at a given point
void displaySprite(int tempX, int tempY);
//Getter Functions
int getW();
int getH();
int getX();
int getY();
SDL_Texture* getSprite();
//Setter Functions
void setW(int temp);
void setH(int temp);
void setX(int temp);
void setY(int temp);
void setSprite(SDL_Texture* newSprite);
//Tile the Sprite
void tileSprite(int tempW, int tempH);
//Stretch the sprite
//void stretchSprite(int tempX, int tempY, float stretchW, float stretchH);
void stretchSprite(int stretchW, int stretchH);
//deconstructor
~spriteImage();
};
//default constructor
spriteImage::spriteImage() {
texture = NULL;
w = 0;
h = 0;
x = 0;
y = 0;
depth = 0;
}
//loads image at specified path
bool spriteImage::loadFromFile(std::string path) {
free();
//The final texture
SDL_Texture* newTexture = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError());
}
else
{
//Color key image
SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, 0, 0xFF, 0xFF));
//Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if (newTexture == NULL)
{
printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
}
else
{
//Get image dimensions
w = loadedSurface->w;
h = loadedSurface->h;
}
//Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
}
//Return success
texture = newTexture;
return texture != NULL;
}
//deallocates texture
void spriteImage::free() {
if (texture != NULL) {
SDL_DestroyTexture(texture);
texture = NULL;
w = 0;
h = 0;
x = 0;
y = 0;
}
}
//render / display the sprite on the screen at given coordinates
void spriteImage::displaySprite(int tempX, int tempY) {
x = tempX;
y = tempY;
//set rendering space and render to the screen
SDL_Rect renderTexture = { x, y, w, h };
SDL_RenderCopy(renderer, texture, NULL, &renderTexture);
//renderQuad is turning the texture into a rectangle and then doing stuff with it.
}
//Getter Functions
int spriteImage::getW() { return w; }
int spriteImage::getH() { return h; }
int spriteImage::getX() { return x; }
int spriteImage::getY() { return y; }
SDL_Texture* spriteImage::getSprite() { return texture; }
//Setter Functions
void spriteImage::setW(int temp) { w = temp; }
void spriteImage::setH(int temp) { h = temp; }
void spriteImage::setX(int temp) { x = temp; }
void spriteImage::setY(int temp) { y = temp; }
void spriteImage::setSprite(SDL_Texture* newSprite) { texture = newSprite; }
//Tile the Sprite
void spriteImage::tileSprite(int tempW, int tempH) {
//assumes you want to do it from top left. We can fix this.
int xCoordCounter = 0;
int yCoordCounter = 0;
for (int i = 0; i < tempH; i++) {
for (int j = 0; j < tempW; j++) {
SDL_Rect renderTexture = { xCoordCounter, yCoordCounter, w, h };
SDL_RenderCopy(renderer, texture, NULL, &renderTexture);
//add to x coordinate
xCoordCounter += w;
}
//reset x and add to y coordinates
xCoordCounter = 0;
yCoordCounter += h;
}
}
//Stretch the sprite
void spriteImage::stretchSprite(int stretchW, int stretchH) {
//void objTexture::stretchSprite(int tempX, int tempY, float stretchW, float stretchH) {
//set rendering space and render to the screen
//SDL_Rect renderTexture = { tempX, tempY, (w * stretchW), (h * stretchH) };
//SDL_RenderCopy(renderer, textureImage, NULL, &renderTexture);
w *= stretchW;
h *= stretchH;
//the only problem with this is doing anything below 0 doesn't invert it. It just doesn't show.
}
//deconstructor
spriteImage::~spriteImage() {
free();
}
#endif
And here’s the code from my spriteAnimation class:
#ifndef SPRITE_ANIMATION
#define SPRITE_ANIMATION
//base class
#include “spriteImage.h”
#include
//testing animation using a texture vector
//later make a function to convert sprite into texture vector?
spriteImage sprite1;
spriteImage sprite2;
class spriteAnimation : private spriteImage {
private:
//int frameW;
//int frameH;
std::vector<spriteImage> frames;
//the number of frames in the animation
int numberOfFrames;
//what frame is currently displayed on screen
int currentFrame;
//Duration of each frame in milliseconds
int frameDuration;
//Timestamp of the last frame
Uint32 lastFrameTime; //universal across all platforms not just Windows.
public:
/*
showFrame
pause animation
add stuff to reset to free
*/
//constructor
spriteAnimation(int tempW, int tempH, int tempFrameDuration);
//loads image at specified path
bool loadFromFile(std::string path) { spriteImage::loadFromFile(path); return false; }
//deallocates texture
void free() { spriteImage::free(); }
//Renders texture at a given point
//void displaySprite(int tempX, int tempY) { spriteImage::displaySprite(tempX, tempY); }
void displaySprite(int tempX, int tempY);
//Getter Functions (from spriteImage)
int getW() { return spriteImage::getW(); }
int getH() { return spriteImage::getH(); }
int getX() { return spriteImage::getX(); }
int getY() { return spriteImage::getY(); }
SDL_Texture* getSprite() { return spriteImage::getSprite(); }
//Getter Functions (Unique to this class)
int getCurrentFrame() { return currentFrame; }
int getFrameDuration() { return frameDuration; }
Uint32 getLastFrameTime() { return lastFrameTime; }
int getNumberOfFrames() { return numberOfFrames; }
//Setter Functions (from spriteImage)
void setW(int temp) { spriteImage::setW(temp); }
void setH(int temp) { spriteImage::setH(temp); }
void setX(int temp) { spriteImage::setX(temp); }
void setY(int temp) { spriteImage::setY(temp); }
void setSprite(SDL_Texture* newSprite) { spriteImage::setSprite(newSprite); }
//Setter Functions (Unique to this class)
void setCurrentFrame(int temp) { currentFrame = temp; }
void setFrameDuration(int temp) { frameDuration = temp; }
void setLastFrameTime(int temp) { lastFrameTime = temp; }
//Tile the Sprite
void tileSprite(int tempW, int tempH) { spriteImage::tileSprite(tempW, tempH); }
//Stretch the sprite
//void stretchSprite(int tempX, int tempY, float stretchW, float stretchH);
void stretchSprite(int stretchW, int stretchH) { spriteImage::stretchSprite(stretchW, stretchH); }
//destructor
~spriteAnimation();
};
//constructor
spriteAnimation::spriteAnimation(int tempW, int tempH, int tempFrameDuration) {
/*
There's no need to initialize the texture, depth, w, h, and alpha in
the derived class's constructor because the base constructor is also
called during creation of derived class object.
However, it's mandatory we set the frame width and height in order
to animate correctly.
add in a loop that determines the size by dividing if you can get the
width of the entire texture.
*/
//adding frames temporarily
frames.push_back(sprite1);
frames.push_back(sprite2);
//number of frames derived from the items in frames vector
//numberOfFrames = (frames.size());
numberOfFrames = 2;
//frameDuration = tempFrameDuration; //milliseconds
frameDuration = 100; //milliseconds
lastFrameTime = 0;
//used to get frames from single linear sprite
//frameW = tempW;
//frameH = tempH;
//setting the default frame as the first one
currentFrame = 0;
}
//spriteAnimation specific functions
void spriteAnimation::displaySprite(int tempX, int tempY) {
Uint32 currentTime = SDL_GetTicks();
Uint32 elapsedTime = currentTime - lastFrameTime;
//SDL_Rect renderTexture = { tempX, tempY, 64, 64 };
//Check to see if it's time to advance to the next frame
if (elapsedTime >= frameDuration) {
currentFrame = (currentFrame + 1) % numberOfFrames;
lastFrameTime = currentTime;
}
frames[currentFrame].spriteImage::displaySprite(tempX, tempY);
//SDL_RenderCopy(renderer, frames[currentFrame].spriteImage::getSprite(), NULL, &renderTexture);
}
//destructor
spriteAnimation::~spriteAnimation() {}
#endif