Skip to content

Commit

Permalink
Merge pull request #11 from jmatthewgriffis/multi-row
Browse files Browse the repository at this point in the history
Seamless support for multi-row animation
  • Loading branch information
stfj committed Dec 2, 2014
2 parents ed00bb4 + eeebf3b commit f76b97d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 10 deletions.
52 changes: 42 additions & 10 deletions src/ofxSpriteSheetRenderer.cpp
Expand Up @@ -337,9 +337,9 @@ bool ofxSpriteSheetRenderer::addTile(int tile_name, int frame, float x, float y,

getFrameXandY(tile_name, frameX, frameY);

frameX += frame*w*tileSize_f;
ofPoint framePos = getFramePosOnSheet(frameX, frameY, frame, w);

addTexCoords(f, frameX, frameY, layer, w, h);
addTexCoords(f, framePos.x, framePos.y, layer, w, h);

w*=tileSize;
h*=tileSize;
Expand Down Expand Up @@ -443,10 +443,9 @@ bool ofxSpriteSheetRenderer::addRotatedTile(int tile_name, int frame, float x, f

getFrameXandY(tile_name, frameX, frameY);

frameX += frame*w*tileSize_f;
//add a check here to make animations wrap around
ofPoint framePos = getFramePosOnSheet(frameX, frameY, frame, w);

addTexCoords(f, frameX, frameY, layer, w, h);
addTexCoords(f, framePos.x, framePos.y, layer, w, h);

w*=scale*tileSize;
h*=scale*tileSize;
Expand Down Expand Up @@ -562,9 +561,9 @@ bool ofxSpriteSheetRenderer::addCenteredTile(int tile_name, int frame, float x,

getFrameXandY(tile_name, frameX, frameY);

frameX += frame*w*tileSize_f;
ofPoint framePos = getFramePosOnSheet(frameX, frameY, frame, w);

addTexCoords(f, frameX, frameY, layer, w, h);
addTexCoords(f, framePos.x, framePos.y, layer, w, h);

//rot*=2;

Expand Down Expand Up @@ -672,10 +671,9 @@ bool ofxSpriteSheetRenderer::addCenterRotatedTile(int tile_name, int frame, floa

getFrameXandY(tile_name, frameX, frameY);

frameX += frame*w*tileSize_f;
//add a check here to make animations wrap around
ofPoint framePos = getFramePosOnSheet(frameX, frameY, frame, w);

addTexCoords(f, frameX, frameY, layer, w, h);
addTexCoords(f, framePos.x, framePos.y, layer, w, h);


//these two should never be called
Expand Down Expand Up @@ -1650,6 +1648,40 @@ void ofxSpriteSheetRenderer::getFrameXandY(int tile_position, float &x, float &y
y*=tileSize_f;
}

ofPoint ofxSpriteSheetRenderer::getFramePosOnSheet(float _frameX, float _frameY, int _frame, float _w) {
/*
Added by J. Matthew Griffis to support multi-row animation.
Note that this assumes your sprite sheet fits as many frames in a single row as possible. That is, if for some reason you have a multi-row animation but you chose to start the next row before you ran out of space for frames on the current row, this won't work.
If you really want to have that though, you could handle it like this: Simply add this line:
float spriteSheetWidthUsed = spriteSheetWidth * [whatever fraction of total sheet width you are using];
Then replace spriteSheetWidth below with spriteSheetWidthUsed. (Don't just change spriteSheetWidth's value. It's used for other things.)
OR...you could, when using the "loadTexture" function to load your sprite sheet, simply not put the true file width, but instead put the width that you are actually using. That works, too.
*/

ofPoint framePos;
framePos.set(_frameX, _frameY); // These get passed in externally and are probably zero, but maybe not, so we'll use them.

/*
Whether the animation is a single row or multiple rows, let's figure out what row the current frame is on, using a simple calculation. We divide the frame number by the number of frames per row, and use the "floor" function to round down to the nearest integer.
*/
int rowNum = floor(_frame / spriteSheetWidth);
/*
Why does that work? Remember that the frame numbering starts at 0. So, in a 4-frame-wide sheet, frame 3 will be the last frame in the first row. 3/4 = 0.75; floor(0.75) = 0; therefore frame 3 is in the first row (numbered 0). What about frame 4? 4/4 = 1; floor(1) = 1; therefore frame 4 is in the second row (numbered 1).
Now we can use that row number to calculate the frame's position. If the frame is not in the first row, we need to offset the x position by however many row widths (sheet widths) we've already gone through, and the y position by however many row heights (frame heights) we've already gone through.
*/
framePos.x += (_frame - spriteSheetWidth * rowNum) * _w * tileSize_f;
framePos.y += tileSize_f * rowNum;

// Now we just have to return the frame's position!
return framePos;
}

float ofxSpriteSheetRenderer::getX(int x, int y, int angle){
angle = CLAMP(angle,0,359);
return (float)x*_cos[angle] - (float)y*_sin[angle];
Expand Down
2 changes: 2 additions & 0 deletions src/ofxSpriteSheetRenderer.h
Expand Up @@ -155,6 +155,8 @@ class ofxSpriteSheetRenderer
protected:

void getFrameXandY(int tile_position, float &x, float &y);

ofPoint getFramePosOnSheet(float _frameX, float _frameY, int _frame, float _w); // Added by J. Matthew Griffis to support multi-row animation. Returns the x and y of the frame as a point.

float getX(int x, int y, int angle);
float getY(int x, int y, int angle);
Expand Down

0 comments on commit f76b97d

Please sign in to comment.