refactor(player): divideix update en tick+applyMovement i exposa velocitat intencionada
This commit is contained in:
1 parent
820b9f2d21
commit
1cc2e28b1b
2 files changed
+88
-23
No files matched your search
@@ -5,6 +5,7 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "core/rendering/sprite/animated_sprite.hpp"
|
||||
#include "game/map/map.hpp"
|
||||
@@ -44,14 +45,48 @@ class Player : public AnimatedSprite {
|
||||
|
||||
Player(const std::string& anim_key, int id, float x, float y, const Controls& controls, const Map::Info& map_info, int paint_tile_index = -1);
|
||||
|
||||
// Update en una sola crida: manté l'API anterior per als tests i
|
||||
// escenaris amb un sol jugador. Internament és equivalent a cridar
|
||||
// `tick(dt)` seguit d'`applyMovement(dt)`.
|
||||
void update(float delta_time) override;
|
||||
|
||||
// Fase 1: llig l'input d'aquest frame i emmagatzema la velocitat
|
||||
// intencionada a `intended_vx_` / `intended_vy_`. No mou el jugador.
|
||||
// Separada d'`applyMovement` perquè el GameScene puga resoldre
|
||||
// interaccions entre jugadors (empentes, neutralitzacions head-on)
|
||||
// abans que ningú consume la posició.
|
||||
void tick(float delta_time);
|
||||
|
||||
// Fase 2: consumeix `intended_vx_`/`intended_vy_` (possiblement
|
||||
// modificats pel resolver), crida `tryMove` contra el mapa i els
|
||||
// altres jugadors, fa snap al passadís, clamp al playfield, avança
|
||||
// l'animació i publica `on_tile_entered` si ha canviat de tile.
|
||||
void applyMovement(float delta_time);
|
||||
|
||||
// Identificador local (0 = P1, 1 = P2…). S'usa als events del bus
|
||||
// perquè els consumidors (HUD, futures regles de puntuació) sàpiguen
|
||||
// quin jugador ha originat l'event. No té cap vinculació amb la
|
||||
// xarxa — és únic per dins del procés.
|
||||
[[nodiscard]] auto getId() const -> int { return id_; }
|
||||
|
||||
// Accés i mutació de la velocitat intencionada d'aquest frame. El
|
||||
// GameScene els toca entre `tick` i `applyMovement` per implementar
|
||||
// col·lisions jugador↔jugador (escalar a push_factor, anul·lar en
|
||||
// head-on). Expressades en píxels/segon, no en píxels/frame.
|
||||
[[nodiscard]] auto getIntendedVX() const -> float { return intended_vx_; }
|
||||
[[nodiscard]] auto getIntendedVY() const -> float { return intended_vy_; }
|
||||
void setIntendedVelocity(float vx, float vy) {
|
||||
intended_vx_ = vx;
|
||||
intended_vy_ = vy;
|
||||
}
|
||||
|
||||
// Llista de tots els jugadors del nivell (incloent-se ell mateix —
|
||||
// la callback ignora `this`). La caixa del jugador es considera un
|
||||
// sòlid a la callback de col·lisió: així `tryMove` no permet que un
|
||||
// jugador travesse l'altre, i els desplaçaments parcials (push
|
||||
// contra mur) s'emparen automàticament.
|
||||
void setOtherPlayers(const std::vector<Player*>* all) { all_players_ = all; }
|
||||
|
||||
// Y de la base del jugador (cara inferior de la caixa de colisió). Usada
|
||||
// per al Z-order contra els sarcs: peus per sobre d'un sarc → darrere;
|
||||
// per sota → davant.
|
||||
@@ -87,6 +122,11 @@ class Player : public AnimatedSprite {
|
||||
// (snapToLane, clamp). Els consumidors externs usen `getBaseBox()`.
|
||||
[[nodiscard]] auto baseBox() const -> SDL_FRect { return getBaseBox(); }
|
||||
|
||||
// Callback de col·lisió per a `tryMove`: true si la caixa proposada
|
||||
// xoca amb el mapa o amb un altre jugador. Membre per mantenir la
|
||||
// complexitat cognitiva d'`applyMovement` sota el llindar.
|
||||
[[nodiscard]] auto collidesWithWorld(const SDL_FRect& box) const -> bool;
|
||||
|
||||
// Clamp de la caixa de col·lisió al playfield (no al sprite sencer:
|
||||
// el cap pot sobresortir pel mur superior sense afectar el joc).
|
||||
void clampToPlayfield();
|
||||
@@ -112,6 +152,16 @@ class Player : public AnimatedSprite {
|
||||
|
||||
int id_{-1};
|
||||
Controls controls_;
|
||||
|
||||
// Velocitat intencionada calculada a `tick` i aplicada a
|
||||
// `applyMovement`. El GameScene pot sobreescriure-la entremig per
|
||||
// resoldre interaccions jugador↔jugador (empentes, head-on).
|
||||
float intended_vx_{0.0F};
|
||||
float intended_vy_{0.0F};
|
||||
|
||||
// Punter a la llista de tots els jugadors del nivell (propietat del
|
||||
// GameScene). `nullptr` = jugador aïllat, sense col·lisió inter-P.
|
||||
const std::vector<Player*>* all_players_{nullptr};
|
||||
// Còpia plana de la geometria del mapa + punters a `collides`/
|
||||
// `inside_playfield`. POD trivial; copiada al ctor i no muta durant
|
||||
// la vida del Player. Vol dir que aquest Player només és vàlid per
|
||||
|
||||
Reference in new issue
Block a user