#include "const.h" #include "item.h" #include // Constructor Item::Item() { mSprite = new AnimatedSprite(); mClass = NO_KIND; } // Destructor Item::~Item() { delete mSprite; mSprite = nullptr; } // Iniciador void Item::init(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *renderer) { mClass = value; mEnabled = true; mTimeToLive = 600; mPosX = x; mPosY = y; mWidth = 16; mHeight = 16; mVelX = -1.0f + ((rand() % 5) * 0.5f); mVelY = -4.0f; mAccelX = 0.0f; mAccelY = 0.2f; mFloorCollision = false; mCollider.r = mWidth / 2; shiftColliders(); mSprite->init(texture, renderer); mSprite->setAnimationFrames(0, 0, 0, 48, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 0, 64, mWidth, mHeight); mSprite->setCurrentFrame(0); mSprite->setAnimationCounter(0); mSprite->setAnimationNumFrames(0, 2); mSprite->setAnimationSpeed(0, 10); mSprite->setAnimationLoop(0, true); mSprite->setSpriteClip(mSprite->getAnimationClip(0, 0)); mSprite->setPosX(mPosX); mSprite->setPosY(mPosY); switch (value) { case NO_KIND: mEnabled = false; mTimeToLive = 0; mPosX = 0; mPosY = 0; mWidth = 0; mHeight = 0; mVelX = 0; mVelY = 0; break; case ITEM_POINTS_1_DISK: mSprite->setAnimationFrames(0, 0, 16 * 0, 16 * 0, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 16 * 0, 16 * 1, mWidth, mHeight); break; case ITEM_POINTS_2_GAVINA: mSprite->setAnimationFrames(0, 0, 16 * 1, 16 * 0, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 16 * 1, 16 * 1, mWidth, mHeight); break; case ITEM_POINTS_3_PACMAR: mSprite->setAnimationFrames(0, 0, 16 * 2, 16 * 0, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 16 * 2, 16 * 1, mWidth, mHeight); break; case ITEM_CLOCK: mSprite->setAnimationFrames(0, 0, 16 * 3, 16 * 0, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 16 * 3, 16 * 1, mWidth, mHeight); break; case ITEM_COFFEE: mSprite->setAnimationFrames(0, 0, 16 * 5, 16 * 0, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 16 * 5, 16 * 1, mWidth, mHeight); break; case ITEM_COFFEE_MACHINE: mWidth = 32; mHeight = 32; mPosX = (((int)x + (PLAY_AREA_WIDTH / 2)) % (PLAY_AREA_WIDTH - mWidth - 5)) + 2; mPosY = PLAY_AREA_TOP - mHeight; mVelX = 0.0f; mVelY = -0.1f; mAccelY = 0.1f; mSprite->setAnimationNumFrames(0, 4); mSprite->setAnimationFrames(0, 0, 32 * 0, 16 * 2, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 32 * 1, 16 * 2, mWidth, mHeight); mSprite->setAnimationFrames(0, 2, 32 * 2, 16 * 2, mWidth, mHeight); mSprite->setAnimationFrames(0, 3, 32 * 3, 16 * 2, mWidth, mHeight); mSprite->setPosX(mPosX); mSprite->setPosY(mPosY); mCollider.r = 10; shiftColliders(); break; default: break; } } // Centra el objeto en la posición X void Item::allignTo(int x) { mPosX = float(x - (mWidth / 2)); if (mPosX < PLAY_AREA_LEFT) { mPosX = PLAY_AREA_LEFT + 1; } else if ((mPosX + mWidth) > PLAY_AREA_RIGHT) { mPosX = float(PLAY_AREA_RIGHT - mWidth - 1); } // Posición X,Y del sprite mSprite->setPosX(int(mPosX)); mSprite->setPosY(int(mPosY)); // Alinea el circulo de colisión con el objeto shiftColliders(); } // Pinta el objeto en la pantalla void Item::render() { if (mEnabled) { if (mTimeToLive > 200) { mSprite->render(); } else if (mTimeToLive % 20 > 10) { mSprite->render(); } } } // Actualiza la posición y estados del objeto void Item::move() { mFloorCollision = false; // Calcula la nueva posición mPosX += mVelX; mPosY += mVelY; // Aplica las aceleraciones a la velocidad mVelX += mAccelX; mVelY += mAccelY; // Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido if ((mPosX < PLAY_AREA_LEFT) || (mPosX + mWidth > PLAY_AREA_RIGHT)) { // Corregir posición mPosX -= mVelX; // Invertir sentido mVelX = -mVelX; } // Si se sale por arriba rebota (excepto la maquina de café) if ((mPosY < PLAY_AREA_TOP) && !(mClass == ITEM_COFFEE_MACHINE)) { // Corrige mPosY = PLAY_AREA_TOP; // Invierte el sentido mVelY = -mVelY; } // Si el objeto se sale por la parte inferior if (mPosY + mHeight > PLAY_AREA_BOTTOM) { // Corrige mPosY -= mVelY; // Detiene el objeto mVelY = 0; mVelX = 0; mAccelX = 0; mAccelY = 0; mPosY = PLAY_AREA_BOTTOM - mHeight; if (mClass == ITEM_COFFEE_MACHINE) mFloorCollision = true; } // Actualiza la posición del sprite mSprite->setPosX(int(mPosX)); mSprite->setPosY(int(mPosY)); } // Pone a cero todos los valores del objeto void Item::erase() { init(NO_KIND, 0, 0, nullptr, nullptr); } // Actualiza el objeto a su posicion, animación y controla los contadores void Item::update() { if (mEnabled) { move(); shiftColliders(); mSprite->animate(0); updateTimeToLive(); checkTimeToLive(); } } // Actualiza el contador void Item::updateTimeToLive() { if (mTimeToLive > 0) { mTimeToLive--; } } // Comprueba si el objeto sigue vivo void Item::checkTimeToLive() { if (mTimeToLive == 0) erase(); } // Obtiene del valor de la variable float Item::getPosX() { return mPosX; } // Obtiene del valor de la variable float Item::getPosY() { return mPosY; } // Obtiene del valor de la variable int Item::getWidth() { return mWidth; } // Obtiene del valor de la variable int Item::getHeight() { return mHeight; } // Obtiene del valor de la variable int Item::getClass() { return mClass; } // Obtiene el valor de la variable bool Item::isEnabled() { return mEnabled; } // Establece el valor de la variable void Item::setEnabled(bool value) { mEnabled = value; } // Obtiene el circulo de colisión circle_t &Item::getCollider() { return mCollider; } // Alinea el circulo de colisión con la posición del objeto void Item::shiftColliders() { //mCollider.x = int(mPosX + mCollider.r); //mCollider.y = int(mPosY + mCollider.r); mCollider.x = int(mPosX + (mWidth / 2)); mCollider.y = int(mPosY + (mHeight / 2)); } // Informa si el objeto ha colisionado con el suelo bool Item::floorCollision() { return mFloorCollision; }