Skip to content
This repository has been archived by the owner on Nov 15, 2022. It is now read-only.

Klasa Weapon

Antek Bizon edited this page Mar 5, 2022 · 1 revision

Klasa Weapon

Odpowiada za broń, z której korzysta Player. Wyróżnia się cztery typy broni. Tekstura oraz wielkości obiektu są ustalane na podstawie jej typu. Obiekt przesuwany jest co 4 klatki. Rysowanie podobnie jak w przypadku Blocku odbywa się za pomocą małych tekstur powielonych na całej długości obiektu (wyjątkiem jest laser i mina). Po zderzeniu z przeszkodą niszczy się lub w przypadku trzeciej broni rozkłada się i pozostaje przyczepiona na parę sekund.

class Weapon : public Sprite {
public:
    enum Kind {
        WEAPON1,
        WEAPON2,
        WEAPON3,
        WEAPON4
    };

    Weapon(Game* game, float x, float y, Kind kind);
    Weapon(Game* game, std::ifstream&);
    virtual void Draw();
    virtual void Move();
    virtual void Collision(Sprite*);
    virtual void Save(std::ofstream&);
    void timeLeft();

private:
    Kind kind;
    Texture2D* texture[2] = { nullptr , nullptr };
    Rectangle moveTexture;
    Color color = WHITE;
    int numElements = 0;
    const float speedY = 21;
    int cooldown = 0;
    bool stopMoving = false;
    int overlap;
    int frameCounter;
    Sprite* block;
};

Weapon::Weapon(Game *game, float x, float y, Kind kind)
    : Sprite(game, Position(x, y, 0, 0), Type::WEAPON), kind(kind) {
        
    switch (kind) {
    case Kind::WEAPON2:
        texture[0] = &game->textures[WEAPON_SHOT];
        position.rectangle.width = texture[0]->width;
        position.rectangle.height = texture[0]->height;
        position.rectangle.x -= position.rectangle.width / 2;
        break;
    case Kind::WEAPON4:
        texture[0] = &game->textures[WEAPON_MINE];
        texture[1] = &game->textures[MINE_EXPLOSION];
        position.rectangle.width = texture[0]->width;
        position.rectangle.height = texture[0]->height;
        position.rectangle.y -= position.rectangle.height;
        moveTexture = { 0.0f, 0.0f, 40, 40 };
        break;
    default:
        texture[0] = &game->textures[WEAPON_ENDING];
        texture[1] = &game->textures[LINE_WIGGLED];
        position.rectangle.width = texture[1]->width;
        moveTexture = { 0.0f, 0.0f, position.rectangle.width, speedY };
        break;
    }
    position.hbRectangle.width = position.rectangle.width;
    position.hbRectangle.height = position.rectangle.height;
    frameCounter = 0;
}

Weapon::Weapon(Game *game, std::ifstream& s)
    : Sprite(game, s, Type::WEAPON) {
    Read(s, &kind);
    Read(s, &state);
    Read(s, &numElements);
    Read(s, &cooldown);
    Read(s, &stopMoving);
    Read(s, &frameCounter);
    Read(s, &block);

    switch (kind) {
    case Kind::WEAPON2:
        texture[0] = &game->textures[WEAPON_SHOT];
        position.rectangle.width = texture[0]->width;
        position.rectangle.height = texture[0]->height;
        position.rectangle.x -= position.rectangle.width / 2;
        break;
    case Kind::WEAPON4:
        texture[0] = &game->textures[WEAPON_MINE];
        texture[1] = &game->textures[MINE_EXPLOSION];
        position.rectangle.width = texture[0]->width;
        position.rectangle.height = texture[0]->height;
        position.rectangle.y -= position.rectangle.height;
        moveTexture = { 0.0f, 0.0f, 40, 40 };
        break;
    default:
        texture[0] = &game->textures[WEAPON_ENDING];
        texture[1] = &game->textures[LINE_WIGGLED];
        position.rectangle.width = texture[1]->width;
        moveTexture = { 0.0f, 0.0f, position.rectangle.width, speedY };
        break;
    }
    position.hbRectangle.width = position.rectangle.width;
    position.hbRectangle.height = position.rectangle.height;
}

void Weapon::Draw() {
    if (state == State::ACTIVE) {
        DrawTexture(*texture[0], position.rectangle.x, position.rectangle.y, WHITE);
        if (texture[1]) {
            if (!stopMoving) {
                int resetFrame = 1;
                int offset = 0;
                for (int i = 1; i < numElements; i++) {
                    moveTexture.height = speedY * resetFrame;
                    DrawTextureRec(*texture[1], moveTexture, { position.rectangle.x, position.rectangle.y + offset + texture[0]->height}, WHITE);

                    if (resetFrame % 3 == 0) {
                        resetFrame = 1;
                        offset += texture[1]->height;
                    } else
                        resetFrame++;
                }
            } else {
                texture[1] = &game->textures[LINE_STRAIGHT];
                DrawTextureTiled(*texture[1], { 0, 0, 20, 20 }, { position.rectangle.x, position.rectangle.y, position.rectangle.width, position.rectangle.height - texture[0]->height }, { 0, texture[0]->height * -1.0f }, 0, 1, color);
            }
        }
    } else if (state == State::FINISHING) {
        if (kind == Kind::WEAPON4) {
            DrawTextureRec(*texture[1], moveTexture, { position.rectangle.x, position.rectangle.y + position.rectangle.height - texture[1]->height }, WHITE);
            if (cooldown++ % 5 == 0)
                moveTexture.x += moveTexture.width;

            if (moveTexture.x >= texture[1]->width)
                state = State::FINISHED;
        }
    }
}

void Weapon::Move() {
    if (state == State::ACTIVE && cooldown++ % 4 == 0) {
        if (!stopMoving) {
            switch (kind) {
            case Kind::WEAPON1:
                position.rectangle.height += speedY;
                position.hbRectangle.height += speedY;
                position.rectangle.y -= speedY;
                numElements++;
                break;
            case Kind::WEAPON2:
                if (position.rectangle.height < 30) {
                    position.rectangle.height += speedY + 20;
                    position.hbRectangle.height += speedY + 20;
                }
                position.rectangle.y -= speedY;
                break;
            case Kind::WEAPON3:
                position.rectangle.height += speedY;
                position.hbRectangle.height += speedY;
                position.rectangle.y -= speedY;
                numElements++;
                break;
            default:
                break;
            }
        } else {
            timeLeft();
            if (!block || block->state == Sprite::State::FINISHED) {
                state = State::FINISHED;
                game->shootingLeft++;
            }
        }
    }
}

void Weapon::Collision(Sprite *sprite) {
    if (sprite->type == Sprite::Type::BLOCK) {
        if (kind == Kind::WEAPON3) {
            stopMoving = true;
            overlap = sprite->position.rectangle.y + sprite->position.rectangle.height - position.rectangle.y;
            position.rectangle.y += overlap;
            position.rectangle.height -= overlap;
            position.hbRectangle.height -= overlap;
            block = sprite;
        } else {
            state = State::FINISHED;
            if (kind == Kind::WEAPON1 && game->shootingLeft < 0)
                game->shootingLeft++;
        }
    } else if (sprite->type == Sprite::Type::ENEMY || sprite->type == Sprite::Type::CRAB) {
        state = State::FINISHING;
        if (kind == Kind::WEAPON4) {
            PlaySound(game->audio[MINE_EXP_SOUND]);
        } else if (kind == Kind::WEAPON1 && game->shootingLeft < 0) {
            game->shootingLeft++;
        } else if (kind == Kind::WEAPON3 && game->shootingLeft < 0) {
            game->shootingLeft++;
        }
    }
}

void Weapon::Save(std::ofstream& s) {
    Write(s, &type);
    position.Save(s);
    Write(s, &kind);
    Write(s, &state);
    Write(s, &numElements);
    Write(s, &cooldown);
    Write(s, &stopMoving);
    Write(s, &frameCounter);
    Write(s, &block);
}

void Weapon::timeLeft() {
    if (frameCounter > 12 * 4) {
        state = State::FINISHED;
        game->shootingLeft++;
    } else if (frameCounter > 12 * 3)
        color = RED;
    else if (frameCounter > 12 * 2)
        color = YELLOW;

    frameCounter++;
}
Clone this wiki locally