Получение позиции игрока, не может передать экземпляр объекта из-за цикла включения - PullRequest
0 голосов
/ 07 апреля 2020

В настоящее время я работаю над клоном Space Invaders в C ++ и SFML и, похоже, у меня проблемы с позицией игроков.

В настоящее время, когда захватчики стреляют, поле удара игрока продолжается. быть начальной позицией игрока, записанной как 900, 500. Этот хит-бокс не перемещает игрока. Я не уверен, почему и как это исправить. Я знаю, что не могу включить game.h в invaders.h, так как game.h включает invaders.h, поэтому вызывает включение l oop. Мне нужно взять экземпляр игрока, созданный в game.h, и передать его в invaders.h для передачи хит-бокса игрока.

Этот код относится к к выстрелам захватчиков и позиции игроков.

Game.h

#include "Player.h"
#include "invaders.h"
class Game
{
private:
Player* player;
vector<Invaders*> vInvaders;
public:
void updateInputs();
};

Game. cpp

#include "Game.h"
void Game::updateInputs()
{
    //Updates player movement.
    player->updateInputs();

    //Creating bullets.
    if ((Keyboard::isKeyPressed(Keyboard::Space)) && (this->player->bCanAttack()))
    {
        this->vBullets.push_back(new Bullet(this->textures["BULLET"], this->player->getPos().x, this->player->getPos().y, 0.f, -1.f, 5.f));
        SoundEngine::playShot();
    }
//Move player.
    if (Keyboard::isKeyPressed(Keyboard::Left))
    {
        move(-1.f, 0);
        getBounds();
        //cout << player->getBounds().left << " " << player->getBounds().top << endl;
    }
    if (Keyboard::isKeyPressed(Keyboard::Right))
    {
        move(1.f, 0);
        getBounds();
        //cout << player->getBounds().left << " " << player->getBounds().top << endl;
    }
}

Player.h

class Player
{
public:
const FloatRect getBounds() const;
void move(const float kfDirX, const float kfDirY);
};

Player. cpp

#include "Player.h"
const FloatRect Player::getBounds() const
{
    return this->sprite.getGlobalBounds(); //Returns the bounding box of player.
}

void Player::move(const float kfDirX, const float kfDirY)
{
    this->sprite.move(this->fSpeed * kfDirX, 0); //Moves player across screen.
}

Invaders.h

#include "Player.h" //It is not needed, but doesn't work without it.
class Invaders
{
private:
Player player; //It is not needed, but does't work without it. Need the instance from Game.h, don't need to make a new instance here.
public:
void updateBullets();
};

Invaders. cpp

#include "Invaders.h"
void Invaders::updateBullets()
{
    unsigned int iCounter = 0;
    for (auto* invaderBullet : this->vInvaderBullets)
    {
        invaderBullet->update();

        for (size_t k = 0; k < this->vInvaderBullets.size(); k++)
        {
            //THIS DOES NOT WORK!!!!
            if (this->vInvaderBullets[k]->getBounds().intersects(player.getBounds()))
            {
                cout << player.getBounds().left << " " << player.getBounds().top << endl;
                this->vInvaderBullets.erase(this->vInvaderBullets.begin() + k);
                this->player.isDead(true);
                Variables::iLives--;
            }
            else
            {
                this->player.isDead(false);
            }
        }

        //Bullet culling at bottom of screen.
        if ((invaderBullet->getBounds().top + invaderBullet->getBounds().height) > 1100.f)
        {
            //std::cout << this->invaderBullets.size() << std::endl;
            delete this->vInvaderBullets.at(iCounter);
            this->vInvaderBullets.erase(this->vInvaderBullets.begin() + iCounter);
            iCounter--;
            //Check to see if bullets are deleted.
            //std::cout << this->invaderBullets.size() << std::endl;
        }
        iCounter++;

        for (size_t k = 0; k < this->vInvaderBullets.size(); k++)
        {
            if (this->vInvaderBullets[k]->getBounds().intersects(this->barrier.getBounds(1)))
            {
                SoundEngine::playBarrierHit();
                this->vInvaderBullets.erase(this->vInvaderBullets.begin() + k);
                this->barrier.barrierHit(1);
            }
            else if (this->vInvaderBullets[k]->getBounds().intersects(this->barrier.getBounds(2)))
            {
                SoundEngine::playBarrierHit();
                this->vInvaderBullets.erase(this->vInvaderBullets.begin() + k);
                this->barrier.barrierHit(2);
            }
            else if (this->vInvaderBullets[k]->getBounds().intersects(this->barrier.getBounds(3)))
            {
                SoundEngine::playBarrierHit();
                this->vInvaderBullets.erase(this->vInvaderBullets.begin() + k);
                this->barrier.barrierHit(3);
            }
            else if (this->vInvaderBullets[k]->getBounds().intersects(this->barrier.getBounds(4)))
            {
                SoundEngine::playBarrierHit();
                this->vInvaderBullets.erase(this->vInvaderBullets.begin() + k);
                this->barrier.barrierHit(4);
            }
        }
    }
}

1 Ответ

1 голос
/ 07 апреля 2020

Помещение элемента типа Player в Invaders означает, что это отдельный объект и, вероятно, не тот же Player, используемый Game. Таким образом, наиболее вероятное движение игрока происходит с Game Player, но захватчики нацеливаются на свои собственные Player, которые не двигались.

, поскольку Invaders::updateBullets() нужен объект Player Есть несколько вариантов:

  • Передать Player& или Game& в функцию updateBullets.
  • Сделать Game одиночным, с общедоступным c способом чтобы получить объект Game и, следовательно, его объект Player из любого контекста.
  • Сохранить указатель Player* или Game* в классе Invaders - но если эти объекты когда-либо могут быть уничтожены раньше Invaders объектов, имеющих дело с этим будет сложно. И это может быть немного «расточительно».

И вообще, помните, что определение класса не нужно, если вы просто имеете дело с указателями или ссылками на этот класс, и это может помочь уменьшить необходимые #include директивы. Например, вы можете изменить Game.h и Game. cpp:

// Game.h
#ifndef GAME_H
#define GAME_H

#include <vector>

class Player;
class Invaders;

class Game
{
private:
    Player* player;
    std::vector<Invaders*> vInvaders;
public:
    void updateInputs();
};

#endif

// Game.cpp
#include "Game.h"
#include "Player.h"
#include "Invaders.h"

// ...
...