refactor: fase 4 — llista enllaçada de Momia a std::vector<unique_ptr>

Eliminada completament la recursivitat per next-pointer:
- Momia::next, clear(), insertar() desapareixen
- update()/draw() no recursen: operen només sobre la instància pròpia
- ModuleGame::momies: Momia* (head de llista) → std::vector<std::unique_ptr<Momia>>
  - Destructor simplificat (vector s'autodestrueix)
  - Draw: range-for sobre el vector
  - Update: std::erase_if + decrement sincronitzat de info::ctx.momies
  - Cheat "alone": momies.clear()
  - iniciarMomies i nova_momia: emplace_back(std::make_unique<Momia>(...))

Zero new/delete manuals al cicle de vida de les momies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-18 13:56:05 +02:00
parent 2a8fbbb095
commit 5e57034a38
4 changed files with 92 additions and 137 deletions

View File

@@ -1,5 +1,7 @@
#include "game/modulegame.hpp" #include "game/modulegame.hpp"
#include <algorithm>
#include "core/audio/audio.hpp" #include "core/audio/audio.hpp"
#include "core/jail/jdraw8.hpp" #include "core/jail/jdraw8.hpp"
#include "core/jail/jgame.hpp" #include "core/jail/jgame.hpp"
@@ -20,11 +22,6 @@ ModuleGame::ModuleGame() {
} }
ModuleGame::~ModuleGame() { ModuleGame::~ModuleGame() {
if (this->momies != nullptr) {
this->momies->clear();
delete this->momies;
}
JD8_FreeSurface(this->gfx); JD8_FreeSurface(this->gfx);
} }
@@ -115,7 +112,7 @@ void ModuleGame::Draw() {
this->mapa->draw(); this->mapa->draw();
this->marcador->draw(); this->marcador->draw();
this->sam->draw(); this->sam->draw();
if (this->momies != nullptr) this->momies->draw(); for (auto& m : this->momies) m->draw();
if (this->bola) this->bola->draw(); if (this->bola) this->bola->draw();
} }
@@ -124,32 +121,19 @@ void ModuleGame::Update() {
JI_Update(); JI_Update();
this->final_ = this->sam->update(); this->final_ = this->sam->update();
if (this->momies != nullptr && this->momies->update()) { const auto erased = std::erase_if(this->momies, [](auto& m) { return m->update(); });
Momia* seguent = this->momies->next; info::ctx.momies -= static_cast<int>(erased);
delete this->momies;
this->momies = seguent;
info::ctx.momies--;
}
if (this->bola) this->bola->update(); if (this->bola) this->bola->update();
this->mapa->update(); this->mapa->update();
if (this->mapa->novaMomia()) { if (this->mapa->novaMomia()) {
if (this->momies != nullptr) { this->momies.emplace_back(std::make_unique<Momia>(this->gfx, true, 0, 0, this->sam.get()));
this->momies->insertar(new Momia(this->gfx, true, 0, 0, this->sam.get())); info::ctx.momies++;
info::ctx.momies++;
} else {
this->momies = new Momia(this->gfx, true, 0, 0, this->sam.get());
info::ctx.momies++;
}
} }
if (JI_CheatActivated("reviu")) info::ctx.vida = 5; if (JI_CheatActivated("reviu")) info::ctx.vida = 5;
if (JI_CheatActivated("alone")) { if (JI_CheatActivated("alone")) {
if (this->momies != nullptr) { this->momies.clear();
this->momies->clear(); info::ctx.momies = 0;
delete this->momies;
this->momies = nullptr;
info::ctx.momies = 0;
}
} }
if (JI_CheatActivated("obert")) { if (JI_CheatActivated("obert")) {
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
@@ -179,11 +163,7 @@ void ModuleGame::iniciarMomies() {
int y = 170; int y = 170;
bool dimonis = info::ctx.num_piramide == 6; bool dimonis = info::ctx.num_piramide == 6;
for (int i = 0; i < info::ctx.momies; i++) { for (int i = 0; i < info::ctx.momies; i++) {
if (this->momies == nullptr) { this->momies.emplace_back(std::make_unique<Momia>(this->gfx, dimonis, x, y, this->sam.get()));
this->momies = new Momia(this->gfx, dimonis, x, y, this->sam.get());
} else {
this->momies->insertar(new Momia(this->gfx, dimonis, x, y, this->sam.get()));
}
x += 65; x += 65;
if (x == 345) { if (x == 345) {
x = 20; x = 20;

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <vector>
#include "game/bola.hpp" #include "game/bola.hpp"
#include "game/info.hpp" #include "game/info.hpp"
@@ -57,6 +58,6 @@ class ModuleGame : public scenes::Scene {
std::unique_ptr<Mapa> mapa; std::unique_ptr<Mapa> mapa;
std::unique_ptr<Prota> sam; std::unique_ptr<Prota> sam;
std::unique_ptr<Marcador> marcador; std::unique_ptr<Marcador> marcador;
Momia* momies{nullptr}; // llista enllaçada, ownership enredat amb `next` std::vector<std::unique_ptr<Momia>> momies;
std::unique_ptr<Bola> bola; std::unique_ptr<Bola> bola;
}; };

View File

@@ -40,7 +40,6 @@ Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
this->cur_frame = 0; this->cur_frame = 0;
this->o = rand() % 4; this->o = rand() % 4;
this->cycles_per_frame = 4; this->cycles_per_frame = 4;
this->next = nullptr;
if (this->dimoni) { if (this->dimoni) {
if (x == 0) { if (x == 0) {
@@ -64,11 +63,6 @@ Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
} }
} }
void Momia::clear() {
if (this->next != nullptr) this->next->clear();
delete this->next;
}
void Momia::draw() { void Momia::draw() {
if (this->engendro) { if (this->engendro) {
this->engendro->draw(); this->engendro->draw();
@@ -83,7 +77,6 @@ void Momia::draw() {
} }
} }
} }
if (this->next != nullptr) this->next->draw();
} }
bool Momia::update() { bool Momia::update() {
@@ -93,84 +86,68 @@ bool Momia::update() {
if (this->engendro->update()) { if (this->engendro->update()) {
this->engendro.reset(); this->engendro.reset();
} }
} else { return morta;
if (this->sam->o < 4 && (this->dimoni || info::ctx.num_piramide == 5 || JG_GetCycleCounter() % 2 == 0)) {
if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) {
if (this->dimoni) {
if (rand() % 2 == 0) {
if (this->x > this->sam->x) {
this->o = 3;
} else if (this->x < this->sam->x) {
this->o = 2;
} else if (this->y < this->sam->y) {
this->o = 0;
} else if (this->y > this->sam->y) {
this->o = 1;
}
} else {
if (this->y < this->sam->y) {
this->o = 0;
} else if (this->y > this->sam->y) {
this->o = 1;
} else if (this->x > this->sam->x) {
this->o = 3;
} else if (this->x < this->sam->x) {
this->o = 2;
}
}
} else {
this->o = rand() % 4;
}
}
switch (this->o) {
case 0:
if (y < 170) this->y++;
break;
case 1:
if (y > 30) this->y--;
break;
case 2:
if (x < 280) this->x++;
break;
case 3:
if (x > 20) this->x--;
break;
}
if (JG_GetCycleCounter() % this->cycles_per_frame == 0) {
this->cur_frame++;
if (this->cur_frame == entitat.animacions[this->o].frames.size()) this->cur_frame = 0;
}
if (this->x > (this->sam->x - 7) && this->x < (this->sam->x + 7) && this->y > (this->sam->y - 7) && this->y < (this->sam->y + 7)) {
morta = true;
if (this->sam->pergami) {
this->sam->pergami = false;
} else {
info::ctx.vida--;
if (info::ctx.vida == 0) this->sam->o = 5;
}
}
}
} }
if (this->next != nullptr) { if (this->sam->o < 4 && (this->dimoni || info::ctx.num_piramide == 5 || JG_GetCycleCounter() % 2 == 0)) {
if (this->next->update()) { if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) {
Momia* seguent = this->next->next; if (this->dimoni) {
delete this->next; if (rand() % 2 == 0) {
this->next = seguent; if (this->x > this->sam->x) {
info::ctx.momies--; this->o = 3;
} else if (this->x < this->sam->x) {
this->o = 2;
} else if (this->y < this->sam->y) {
this->o = 0;
} else if (this->y > this->sam->y) {
this->o = 1;
}
} else {
if (this->y < this->sam->y) {
this->o = 0;
} else if (this->y > this->sam->y) {
this->o = 1;
} else if (this->x > this->sam->x) {
this->o = 3;
} else if (this->x < this->sam->x) {
this->o = 2;
}
}
} else {
this->o = rand() % 4;
}
}
switch (this->o) {
case 0:
if (y < 170) this->y++;
break;
case 1:
if (y > 30) this->y--;
break;
case 2:
if (x < 280) this->x++;
break;
case 3:
if (x > 20) this->x--;
break;
}
if (JG_GetCycleCounter() % this->cycles_per_frame == 0) {
this->cur_frame++;
if (this->cur_frame == entitat.animacions[this->o].frames.size()) this->cur_frame = 0;
}
if (this->x > (this->sam->x - 7) && this->x < (this->sam->x + 7) && this->y > (this->sam->y - 7) && this->y < (this->sam->y + 7)) {
morta = true;
if (this->sam->pergami) {
this->sam->pergami = false;
} else {
info::ctx.vida--;
if (info::ctx.vida == 0) this->sam->o = 5;
}
} }
} }
return morta; return morta;
} }
void Momia::insertar(Momia* momia) {
if (this->next != nullptr) {
this->next->insertar(momia);
} else {
this->next = momia;
}
}

View File

@@ -11,13 +11,10 @@ class Momia : public Sprite {
public: public:
explicit Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam); explicit Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam);
void clear();
void draw() override; void draw() override;
bool update(); bool update();
void insertar(Momia* momia);
bool dimoni; bool dimoni;
Momia* next;
protected: protected:
Prota* sam; Prota* sam;