vector, private objektvariablen werden überschrieben?!
-
soo das problem erfordert leider etwas mehr quelltext und erklärung, aber was solls:
Dies ist ein teil der mainfunktion meines programms:
SDL_Surface *testParticle = createEmptyFromScreen(2,2,screen); put_pixel32((Uint32 *)testParticle->pixels,testParticle,0,0,white); put_pixel32((Uint32 *)testParticle->pixels,testParticle,1,0,white); put_pixel32((Uint32 *)testParticle->pixels,testParticle,0,1,white); put_pixel32((Uint32 *)testParticle->pixels,testParticle,1,1,white); Vektor grav(0,0.01); // // 1) ich erstelle eine object von fadeStruct, das ist eine klasse, welche informationen enthält, wie sich die // farbe des Partikels im laufe seines lebens ändern soll. // fadeStruct myFade; myRGB start; start.r = 255; start.g = 255; start.b = 0; myRGB mid; mid.r = 255; mid.g = 0; mid.b = 0; myRGB end1; end1.r = 0; end1.g = 0; end1.b = 255; myRGB end2; end2.r = 255; end2.g = 255; end2.b = 255; myFade.addKeyframe(start, 255, 0); //(farbe, alpha, zeitpunkt) myFade.addKeyframe(mid, 255, 125); myFade.addKeyframe(end1, 255, 200); myFade.addKeyframe(end2, 255, 201); myFade.addKeyframe(end2, 0, 255); // // 2) Hier erstelle ich 2 vectoren, der erste wird ALLE partikel enhalten, der zweite die partkelspawner // std::vector<Particle> pList; std::vector<PSpawner> spawnList; // // 3) Hier erstelle ich den ersten spawner, er hat keine fadeStruct, die farbe soll sich also nicht ändern, // sondern der originalfarbe des oben erstellten partikels (testParticle) entsprechen. // PSpawner ps1 = PSpawner(); ps1.setParticle(testParticle, &grav, black, 400, &pList, 0); // // 4) der zweite spawner erhält den oben erstellten fadeStruct: // PSpawner ps2 = PSpawner(); ps2.setParticle(testParticle, &grav, black, 350, &pList, 1); ps2.addFade(myFade); Vektor vp, vm, add; vp.x = 300; vp.y = 550; vm.x = 0; vm.y = -2.5; add.x = 0; add.y = 0; // // 5) nur der erste spawner wird in den Vector gepackt: // spawnList.push_back(ps1); for(int k = 0; k < spawnList.size(); k++) spawnList.at(k).start(100,1200,vp,vm, add, 1, 20, 200); while( quit == false ) { //############################################################### // // 6) für alle spawner die im vector sind wird frame() aufgerufem // for(k = 0; k < spawnList.size(); k++) spawnList.at(k).frame(); int downC = 0; int pls = pList.size(); Uint32 cTime = SDL_GetTicks(); for(int i = 0; i-downC < pls-downC ; i++) { pList.at(i-downC).move(screen, cTime); if(!pList.at(i-downC).alive) { if(pList.at(i-downC).type == 0) { vp.x = pList.at(i-downC).position.x; vp.y = pList.at(i-downC).position.y; vm.x = 0; vm.y = -0.1; // // 7) wenn ein partikel vom ersten spawner stirbt, wird an der stelle eine kopie von zweiten spawner erstellt und /// in den vector gepackt. // PSpawner tmp = PSpawner(ps2); tmp.start(0, 15, vp,vm, pList.at(i-downC).velocity, 0.2,360,200); spawnList.push_back(tmp); } pList.at(i-downC).~Particle(); pList.erase( pList.begin( ) + (i-downC)); downC++; } } char deb[255]; sprintf(deb, "%i", pList.size()); debug = TTF_RenderText_Solid( font, deb, textColor ); SDL_Rect t; t.x = 10; t.y = 10; t.w = 100; t.h = 20; SDL_FillRect(screen, &t, black); apply_surface( 10, 10, debug, screen ); if( SDL_Flip( screen ) == -1 ) { return 1; } [...]Jetzt kommen wir zum spawner selbst... genauer zur frame funktion:
void PSpawner::frame() { if(cInterval < sAmount) { int cDif; if(sInterval == 0) { cDif = sAmount; } else { Uint32 cTime = SDL_GetTicks() - startTime; cDif = (int)(cTime/(float)sInterval) - cInterval ; } cInterval += cDif; while(cDif > 0) { SDL_Surface *t; t = sprite; t->refcount++; int pLifetime = lifetime + (irand(0,randLifetime)-(randLifetime/2)); if(pLifetime < 1) pLifetime = 1; double pSpeed = direction.getLength() + (irand(0,randSpeed)-(randSpeed/2)); if(pSpeed < 0) pSpeed = 0; Vektor pDirection = direction; pDirection.setLength(pSpeed); int pAngle = direction.angle() + (irand(0,randAngle)-(randAngle/2)); pDirection.setAngle(pAngle); pDirection = pDirection + velMp; // // Hier kommt der wichtige teil, ein temporärer partikel wird erstellt, und in die partikelListe gepusht: // Particle pt = Particle(t, gravity, replaceColor, type, pLifetime, pos.x, pos.y, pDirection.x, pDirection.y); if(hasFade) { pt.addFadeStruct(fadeS); } pList->push_back(pt); cDif--; } } } //hier der copy cton: PSpawner::PSpawner(const PSpawner &p) { type = p.type; // // Aus dem offiziellen SDL wiki entnommen, so erstellt man eine kopie einer surface: // sprite = p.sprite; sprite->refcount++; gravity = p.gravity; replaceColor = p.replaceColor; lifetime = p.lifetime; pList = p.pList; randSpeed = p.randSpeed; randAngle = p.randAngle; randLifetime = p.randLifetime; cInterval = p.cInterval; startTime = p.startTime; sAmount = p.sAmount; sInterval = p.sInterval; pos = p.pos; direction = p.direction; velMp = p.velMp; hasFade = p.hasFade; if(hasFade) fadeS = p.fadeS; }Un jetzt noch move() und der copy cton vom Partikel selbst:
Particle::Particle(const Particle &p) { gravity = p.gravity; // // Auch hier kopiere ich die Surface auf diese weise: // sprite = p.sprite; sprite->refcount++; type = p.type; position = p.position; velocity = p.velocity; alive = true; spawntime = p.spawntime; lifetime = p.lifetime; replaceColor = p.replaceColor; hasFadeStruct = p.hasFadeStruct; sprPixels = (Uint32 *)sprite->pixels; if(hasFadeStruct) fade = p.fade; } const Particle& Particle::operator=(const Particle &right) { if(this != &right) { type = right.type; gravity = right.gravity; gravity = right.gravity; sprite = right.sprite; sprite->refcount++; position = right.position; velocity = right.velocity; alive = true; spawntime = right.spawntime; lifetime = right.lifetime; replaceColor = right.replaceColor; hasFadeStruct = right.hasFadeStruct; sprPixels = (Uint32 *)sprite->pixels; if(hasFadeStruct) fade = right.fade; } return *this; } void Particle::move(SDL_Surface *surf, Uint32 cTicks) { SDL_Rect offset; if(alive) { offset.x = position.x; offset.y = position.y; offset.w = sprite->w; offset.h = sprite->h; SDL_FillRect(surf, &offset, replaceColor); } if(cTicks > spawntime+lifetime && lifetime > 0 && alive) alive = false; if(alive) { // // Hier wird geguckt ob der partikel ein fadeStruct hat, wenn ja, dann wird es angewendet (die fadeStruct klasse // enhält keine pointer, hat also keinen überladedenen copy cton) // if(hasFadeStruct) { double timeFactor = 255.0/lifetime; Uint32 currentTime = cTicks-spawntime; if(lastCTime > timeFactor*currentTime) { Uint32 test = timeFactor*currentTime; cTicks = cTicks; currentTime = currentTime; timeFactor = timeFactor; spawntime = spawntime; } lastCTime = timeFactor*currentTime; myRGB crgb = fade.getRGB(timeFactor*currentTime); for(int i = 0; i < sprite->w; i++) { for(int j = 0; j < sprite->h; j++) { sprPixels[i + j*sprite->w] = SDL_MapRGB( sprite->format, crgb.r, crgb.g, crgb.b); } } SDL_SetAlpha( sprite, SDL_SRCALPHA | SDL_RLEACCEL, fade.getAlpha(timeFactor*currentTime) ); } velocity = velocity+*gravity; position = position+velocity; offset; offset.x = (int)position.x; offset.y = (int)position.y; SDL_BlitSurface( sprite, NULL, surf, &offset ); } }Jetzt zu meinem problem:
Sobald ein partikel von meiner ersten partikelspawner stirbt, und dadurch eine kopie vom zweiten partikelspawner aktiviert wird, bekommen die partikel von ersten partikelspawner das fadestruct vom zweiten verpasst! wie kann denn das sein!? wenn ihr weitere fragen habt, stellt sie, ich kann euch auch den ganzen quellcode oder die exe schicken. Ich verzweifle hier echt gerade

-
pixartist schrieb:
wie kann denn das sein!?
Vermutlich ist dein fadeStruct kaputt. Den entscheidenden Code hast du irgendwie nicht gezeigt.
fadeStruct selbst wäre interessant gewesen, sowie PSpawner::addFade und Particle::addFadeStruct.Schreib doch mal einen Wrapper für SDL_Surface, damit du dir die ganzen Copykonstruktoren, Zuweisungoperatoren und Destruktoren schenken kannst.
Lustig ist auch der Teil:
cTicks = cTicks; currentTime = currentTime; timeFactor = timeFactor; spawntime = spawntime;Und du rufst immer noch explizit einen Destruktor auf

-
MFK schrieb:
pixartist schrieb:
wie kann denn das sein!?
Vermutlich ist dein fadeStruct kaputt. Den entscheidenden Code hast du irgendwie nicht gezeigt.
fadeStruct selbst wäre interessant gewesen, sowie PSpawner::addFade und Particle::addFadeStruct.Schreib doch mal einen Wrapper für SDL_Surface, damit du dir die ganzen Copykonstruktoren, Zuweisungoperatoren und Destruktoren schenken kannst.
Lustig ist auch der Teil:
cTicks = cTicks; currentTime = currentTime; timeFactor = timeFactor; spawntime = spawntime;Und du rufst immer noch explizit einen Destruktor auf

ups stimmt.. das mit dem destruktor hab ich jetzt mal rausgenommen, das mit den variablen hab ich gemacht, damit ich sie im debugger in der zeile sehen kann.
hier mal fadeStruct:
#include "fadeStruct.h" void fadeStruct::addKeyframe(myRGB aRGB, Uint8 aAlpha, Uint8 aTime) { RGB.push_back(aRGB); alpha.push_back(aAlpha); time.push_back(aTime); } int fadeStruct::getKeyframeNum() { return RGB.size(); } myRGB fadeStruct::getRGB(int at) { for(int i = 0; i < RGB.size(); i++) { if(RGB.size() > i+1) { if(time.at(i) <= at && time.at(i+1) >= at) { myRGB *prev = &RGB.at(i); myRGB *next = &RGB.at(i+1); myRGB now; int prevDif = at - time.at(i); int nextDif = time.at(i+1) - at; int totalDif = prevDif + nextDif; if(totalDif > 0) { double factor = 1./totalDif; now.r = (prev->r*(factor*nextDif))+(next->r*(factor*prevDif)); now.g = (prev->g*(factor*nextDif))+(next->g*(factor*prevDif)); now.b = (prev->b*(factor*nextDif))+(next->b*(factor*prevDif)); return now; } return RGB.at(i); } } } if(at > time.at(time.size()-1)) return RGB.at(RGB.size()-1); else return RGB.at(0); myRGB t; return t; } Uint8 fadeStruct::getAlpha(int at) { for(int i = 0; i < RGB.size(); i++) { if(RGB.size() > i+1) { if(time.at(i) <= at && time.at(i+1) >= at) { Uint8 prev = alpha.at(i); Uint8 next = alpha.at(i+1); Uint8 now; int prevDif = at - time.at(i); int nextDif = time.at(i+1) - at; int totalDif = prevDif + nextDif; if(totalDif > 0) { double factor = 1.0/totalDif; now = (prev*(factor*nextDif))+(next*(factor*prevDif)); return now; } return alpha.at(i); } } } if(at > time.at(time.size()-1)) return alpha.at(alpha.size()-1); else return alpha.at(0); return 0; }void PSpawner::addFade(fadeStruct fade) { fadeS = fade; hasFade = true; }void Particle::addFadeStruct(fadeStruct fs) { fade = fs; hasFadeStruct = true; }
-
pixartist schrieb:
Sobald ein partikel von meiner ersten partikelspawner stirbt, und dadurch eine kopie vom zweiten partikelspawner aktiviert wird, bekommen die partikel von ersten partikelspawner das fadestruct vom zweiten verpasst!
Ich kann's mir grad nicht erklären. Wie sieht denn das beobachtete Verhalten genau aus, ohne deine Interpretation?
-
MFK schrieb:
pixartist schrieb:
Sobald ein partikel von meiner ersten partikelspawner stirbt, und dadurch eine kopie vom zweiten partikelspawner aktiviert wird, bekommen die partikel von ersten partikelspawner das fadestruct vom zweiten verpasst!
Ich kann's mir grad nicht erklären. Wie sieht denn das beobachtete Verhalten genau aus, ohne deine Interpretation?
Einstellung 1 (Die partikel vom 1. spawner haben eine kürzere lebenszeit als ihr spawninterval ist)
ein partikel vom 1. spawner wird erstellt, fliegt nach oben(farbe: weiß, so wie es soll). "explodiert" -> sprich die partkel vom 2ten spawner entstehen, fliegen rum( mit dem korrekten farbverlauf).
von nun an haben die partikel vom 1. spawner (sprich die raketen die nach oben fliegen) immer die farbe vom letzten keyframe des fadeStruct vom 2tem spawner.Einstellung 2 (Die partikel vom 1. spawner haben einen kürzeren spawninterval als ihre lebensdauer, es sind also partikel vom 1 und 2ten spawner gleichzeitig vorhanden)
In diesem Fall haben die Partikel den gleichen farbverlauf, als hätte ich ihnen das fadeStruct vom zweiten spawner zugewiesen.echt komisch das ganze oO
-
pixartist schrieb:
echt komisch das ganze oO
Vermutlich musst du für die Partikel, die kein fadeStruct habe, das Sprite wieder auf weiß zurücksetzen, bevor du es blittest, sonst übernimmst du die zuletzt gesetzten Farbeinstellungen. Ich kenne mich aber nicht genug mit SDL aus, dass ich mir dessen sicher wäre.
-
ok, es sieht so aus, als würde die methode zum kopieren von sprites nicht wirklich funktionieren
irgendwie greift der erste spawner auf die gleiche surface wie der zweite zu (anders kann ich mir nicht erklären, wieso die partikel vom ersten spawner die farben von partikeln des zweiten spawners übernehmen)
ich schreib mal ne mail an die leute von sdl
verdammt!
-
pixartist schrieb:
irgendwie greift der erste spawner auf die gleiche surface wie der zweite zu (anders kann ich mir nicht erklären, wieso die partikel vom ersten spawner die farben von partikeln des zweiten spawners übernehmen)
Du hast das Surface nicht kopiert. Du hast doch offensichtlich nur den Referenzzähler erhöht.
ich schreib mal ne mail an die leute von sdl

Wenn du denen unbedingt zeigen willst, dass du nicht weißt, was Reference Counting ist, bitte

-
MFK schrieb:
pixartist schrieb:
irgendwie greift der erste spawner auf die gleiche surface wie der zweite zu (anders kann ich mir nicht erklären, wieso die partikel vom ersten spawner die farben von partikeln des zweiten spawners übernehmen)
Du hast das Surface nicht kopiert. Du hast doch offensichtlich nur den Referenzzähler erhöht.
ich schreib mal ne mail an die leute von sdl

Wenn du denen unbedingt zeigen willst, dass du nicht weißt, was Reference Counting ist, bitte

jau sry, aber ich kann ja nicht alles wissen

Aus dem SDL Wiki:The proper way to duplicate a surface is
SDL_Surface *Srfc1, *Srfc2;
Srfc1= IMG_Load("foo.png");
Srfc2= Srfc1;
Srfc2->refcount++;
..
SDL_FreeSurface(Srfc1);
SDL_FreeSurface(Srfc2);naja ich blitte die jetzt ... das geht, thx für die hilfe
