-
Notifications
You must be signed in to change notification settings - Fork 0
/
explodingSprite.cpp
86 lines (79 loc) · 2.85 KB
/
explodingSprite.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <cmath>
#include "explodingSprite.h"
#include "extractSurface.h"
ExplodingSprite::ExplodingSprite(const Sprite& s) :
Sprite(s),
chunks(),
freeList(),
surfaces(),
frames() {
makeChunks(
Gamedata::getInstance().getXmlInt(s.getName()+"/chunk/size")
);
}
ExplodingSprite::~ExplodingSprite() {
for ( unsigned int i = 0; i < frames.size(); ++i ) {
SDL_FreeSurface( surfaces[i] );
delete frames[i]; // ExplodingSprite made them, so it deletes them
}
chunks.clear(); // clearing a vector is a waste of time, but ...
freeList.clear(); // still ...
}
void ExplodingSprite::draw() const {
// Override draw; use the draw in Chunk, which derives from Sprite.
// So the draw we're using is actually in Sprite
std::list<Chunk>::const_iterator ptr = chunks.begin();
while (ptr != chunks.end()) {
ptr->draw();
++ptr;
}
}
void ExplodingSprite::update(Uint32 ticks) {
std::list<Chunk>::iterator ptr = chunks.begin();
while (ptr != chunks.end()) {
ptr->update(ticks);
if (ptr->goneTooFar()) { // Check to see if we should free a chunk
freeList.push_back(*ptr);
ptr = chunks.erase(ptr);
}
else ++ptr;
}
}
void ExplodingSprite::makeChunks(unsigned int n) {
// Break the SDL_Surface into n*n squares; where each square
// has width and height of frameWidth/n and frameHeight/n
unsigned int chunk_width = std::max(1u, getFrame()->getWidth()/n);
unsigned int chunk_height = std::max(1u, getFrame()->getHeight()/n);
int speedx = static_cast<int>(velocityX()); // Wanna test for zero...
int speedy = static_cast<int>(velocityY()); // Make sure it's an int.
if (speedx == 0) speedx = 1; // Make sure it's not 0;
if (speedy == 0) speedy = 1; // Make sure it's not 0;
// Get the SDL_Surface so we can chunk it:
SDL_Surface* spriteSurface = getFrame()->getSurface();
Sint16 source_y = 0;
while (source_y < getFrame()->getHeight() ) {
Sint16 source_x = 0;
while ( source_x < getFrame()->getWidth() ) {
// Give each chunk it's own speed/direction:
float sx = (rand() % speedx + 40) * (rand()%2?-1:1); // 'cause %0 is
float sy = (rand() % speedy + 40) * (rand()%2?-1:1); // float except
SDL_Surface* surf = ExtractSurface::getInstance().
get(spriteSurface, chunk_width, chunk_height, source_x, source_y);
Frame* frame = new Frame(surf);
Chunk chunk(
Vector2f(X()+source_x, // x coord of destination
Y()+source_y), // y coord of destination
Vector2f(sx, sy),
getName()+"/chunk",
frame);
// chunks uses value semantics, as does frames, but there's
// a big difference:
chunks.push_back(chunk);
frames.push_back(frame);
surfaces.push_back(surf);
source_x += chunk_width;
}
source_y += chunk_height;
}
}