271 lines
6.1 KiB
C++
271 lines
6.1 KiB
C++
#include "core/rendering/movingsprite.h"
|
|
|
|
#include "core/rendering/texture.h" // for Texture
|
|
|
|
// Constructor
|
|
MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, Texture *texture, SDL_Renderer *renderer)
|
|
: Sprite(0, 0, w, h, texture, renderer),
|
|
x_(x),
|
|
y_(y),
|
|
x_prev_(x),
|
|
y_prev_(y),
|
|
vx_(velx),
|
|
vy_(vely),
|
|
ax_(accelx),
|
|
ay_(accely) {
|
|
}
|
|
|
|
// Reinicia todas las variables
|
|
void MovingSprite::clear() {
|
|
x_ = 0.0F;
|
|
y_ = 0.0F;
|
|
|
|
vx_ = 0.0F;
|
|
vy_ = 0.0F;
|
|
|
|
ax_ = 0.0F;
|
|
ay_ = 0.0F;
|
|
|
|
zoom_w_ = 1.0F;
|
|
zoom_h_ = 1.0F;
|
|
|
|
angle_ = 0.0;
|
|
rotate_enabled_ = false;
|
|
center_ = nullptr;
|
|
rotate_speed_ = 0;
|
|
rotate_amount_ = 0.0;
|
|
|
|
current_flip_ = SDL_FLIP_NONE;
|
|
}
|
|
|
|
// Mueve el sprite. vx_/vy_ en px/s, ax_/ay_ en px/s². Integració d'Euler
|
|
// senzilla — suficient per a moviments sense col·lisions sensibles.
|
|
void MovingSprite::move(float dt_s) {
|
|
if (enabled_) {
|
|
x_prev_ = x_;
|
|
y_prev_ = y_;
|
|
|
|
x_ += vx_ * dt_s;
|
|
y_ += vy_ * dt_s;
|
|
|
|
vx_ += ax_ * dt_s;
|
|
vy_ += ay_ * dt_s;
|
|
}
|
|
}
|
|
|
|
// Muestra el sprite por pantalla
|
|
void MovingSprite::render() {
|
|
if (enabled_) {
|
|
texture_->render(renderer_, (int)x_, (int)y_, &sprite_clip_, zoom_w_, zoom_h_, angle_, center_, current_flip_);
|
|
}
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
// cppcheck-suppress duplInheritedMember ; shadow intencional: vegeu movingsprite.h
|
|
auto MovingSprite::getPosX() const -> float {
|
|
return x_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
// cppcheck-suppress duplInheritedMember ; shadow intencional: vegeu movingsprite.h
|
|
auto MovingSprite::getPosY() const -> float {
|
|
return y_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getVelX() const -> float {
|
|
return vx_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getVelY() const -> float {
|
|
return vy_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getAccelX() const -> float {
|
|
return ax_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getAccelY() const -> float {
|
|
return ay_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getZoomW() const -> float {
|
|
return zoom_w_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getZoomH() const -> float {
|
|
return zoom_h_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getAngle() const -> double {
|
|
return angle_;
|
|
}
|
|
|
|
// Establece la posición y el tamaño del objeto
|
|
void MovingSprite::setRect(SDL_Rect rect) {
|
|
x_ = (float)rect.x;
|
|
y_ = (float)rect.y;
|
|
w_ = rect.w;
|
|
h_ = rect.h;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setPosX(float value) {
|
|
x_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setPosY(float value) {
|
|
y_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setVelX(float value) {
|
|
vx_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setVelY(float value) {
|
|
vy_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setAccelX(float value) {
|
|
ax_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setAccelY(float value) {
|
|
ay_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setZoomW(float value) {
|
|
zoom_w_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setZoomH(float value) {
|
|
zoom_h_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setAngle(double value) {
|
|
angle_ = value;
|
|
}
|
|
|
|
// Incrementa el valor de la variable
|
|
void MovingSprite::incAngle(double value) {
|
|
angle_ += value;
|
|
}
|
|
|
|
// Decrementa el valor de la variable
|
|
void MovingSprite::decAngle(double value) {
|
|
angle_ -= value;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getRotate() const -> bool {
|
|
return rotate_enabled_;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getRotateSpeed() const -> Uint16 {
|
|
return rotate_speed_;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setRotate(bool value) {
|
|
rotate_enabled_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setRotateSpeed(int value) {
|
|
if (value < 1) {
|
|
rotate_speed_ = 1;
|
|
} else {
|
|
rotate_speed_ = value;
|
|
}
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setRotateAmount(double value) {
|
|
rotate_amount_ = value;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::disableRotate() {
|
|
rotate_enabled_ = false;
|
|
angle_ = (double)0;
|
|
}
|
|
|
|
// Actualiza les variables internes (move + rotació integrada). La rotació
|
|
// frame-based original era `incAngle(rotate_amount_)` cada `rotate_speed_`
|
|
// frames a 60Hz, equivalent a velocitat angular constant
|
|
// = rotate_amount_ * 60 / rotate_speed_ graus/s.
|
|
void MovingSprite::update(float dt_s) {
|
|
move(dt_s);
|
|
if (enabled_ && rotate_enabled_) {
|
|
const double ANGULAR_VELOCITY_DEG_PER_S = rotate_amount_ * 60.0 / static_cast<double>(rotate_speed_);
|
|
incAngle(ANGULAR_VELOCITY_DEG_PER_S * dt_s);
|
|
}
|
|
}
|
|
|
|
// Cambia el sentido de la rotación
|
|
void MovingSprite::switchRotate() {
|
|
rotate_amount_ *= -1;
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void MovingSprite::setFlip(SDL_FlipMode flip) {
|
|
current_flip_ = flip;
|
|
}
|
|
|
|
// Gira el sprite horizontalmente
|
|
void MovingSprite::flip() {
|
|
current_flip_ = (current_flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL;
|
|
}
|
|
|
|
// Obtiene el valor de la variable
|
|
auto MovingSprite::getFlip() -> SDL_FlipMode {
|
|
return current_flip_;
|
|
}
|
|
|
|
// Devuelve el rectangulo donde está el sprite
|
|
auto MovingSprite::getRect() -> SDL_Rect {
|
|
const SDL_Rect RECT = {(int)x_, (int)y_, w_, h_};
|
|
return RECT;
|
|
}
|
|
|
|
// Deshace el último movimiento
|
|
void MovingSprite::undoMove() {
|
|
x_ = x_prev_;
|
|
y_ = y_prev_;
|
|
}
|
|
|
|
// Deshace el último movimiento en el eje X
|
|
void MovingSprite::undoMoveX() {
|
|
x_ = x_prev_;
|
|
}
|
|
|
|
// Deshace el último movimiento en el eje Y
|
|
void MovingSprite::undoMoveY() {
|
|
y_ = y_prev_;
|
|
}
|
|
|
|
// Pone a cero las velocidades de desplacamiento
|
|
void MovingSprite::clearVel() {
|
|
vx_ = vy_ = 0.0F;
|
|
}
|
|
|
|
// Devuelve el incremento en el eje X en pixels
|
|
auto MovingSprite::getIncX() const -> int {
|
|
return (int)x_ - (int)x_prev_;
|
|
}
|