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

View File

@@ -1,6 +1,7 @@
#pragma once
#include <memory>
#include <vector>
#include "game/bola.hpp"
#include "game/info.hpp"
@@ -57,6 +58,6 @@ class ModuleGame : public scenes::Scene {
std::unique_ptr<Mapa> mapa;
std::unique_ptr<Prota> sam;
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;
};

View File

@@ -40,7 +40,6 @@ Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
this->cur_frame = 0;
this->o = rand() % 4;
this->cycles_per_frame = 4;
this->next = nullptr;
if (this->dimoni) {
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() {
if (this->engendro) {
this->engendro->draw();
@@ -83,7 +77,6 @@ void Momia::draw() {
}
}
}
if (this->next != nullptr) this->next->draw();
}
bool Momia::update() {
@@ -93,84 +86,68 @@ bool Momia::update() {
if (this->engendro->update()) {
this->engendro.reset();
}
} else {
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;
}
}
}
return morta;
}
if (this->next != nullptr) {
if (this->next->update()) {
Momia* seguent = this->next->next;
delete this->next;
this->next = seguent;
info::ctx.momies--;
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;
}
}
}
return morta;
}
void Momia::insertar(Momia* momia) {
if (this->next != nullptr) {
this->next->insertar(momia);
} else {
this->next = momia;
}
}

View File

@@ -1,25 +1,22 @@
#pragma once
#include <memory>
#include "game/engendro.hpp"
#include "game/info.hpp"
#include "game/prota.hpp"
#include "game/sprite.hpp"
class Momia : public Sprite {
public:
explicit Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam);
void clear();
void draw() override;
bool update();
void insertar(Momia* momia);
bool dimoni;
Momia* next;
protected:
Prota* sam;
std::unique_ptr<Engendro> engendro;
};
#pragma once
#include <memory>
#include "game/engendro.hpp"
#include "game/info.hpp"
#include "game/prota.hpp"
#include "game/sprite.hpp"
class Momia : public Sprite {
public:
explicit Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam);
void draw() override;
bool update();
bool dimoni;
protected:
Prota* sam;
std::unique_ptr<Engendro> engendro;
};