我正在处理SFML中的第一个小项目。我做了一个在屏幕上弹跳的球(弹丸)和一个可移动的球员。但是,当我尝试为对象创建对象处理程序时,发生了问题。在让管理者控制绘图和对象更新之后,球员和球才停下来变得不动。我的问题是为什么?
球:

#ifndef PROJECTILE_H
#define PROJECTILE_H
#include <SFML\Graphics.hpp>
using namespace std;

class Projectile : public sf::Drawable {

private:
    sf::Texture texture;
    sf::Sprite sprite;
public:
    Projectile();
    virtual ~Projectile();
    sf::Sprite getSprite() const;
    virtual void draw(sf::RenderTarget &target, sf::RenderStates states) const;
};

#endif //PROJECTILE_H

#include "Projectile.h"
#include <iostream>

Projectile::Projectile() {

    if (!this->texture.loadFromFile("../Resources/projectile.png")) {
        cout << "Error! Projectile sprite could not be loaded!" << endl;
    }
    this->sprite.setPosition(sf::Vector2f(0.0f, 0.0f));
    this->sprite.setTexture(this->texture);
    sf::FloatRect boundingBoxProjectile = this->sprite.getGlobalBounds();
}

Projectile::~Projectile() {
}

sf::Sprite Projectile::getSprite() const{
    return this->sprite;
}

void Projectile::draw(sf::RenderTarget & target, sf::RenderStates states) const {
    target.draw(sprite, states);
}

处理程序:
#ifndef OBJECTHANDLER_H
#define OBJECTHANDLER_H
#include "Block.h"
#include "Player.h"
#include "Projectile.h"
using namespace std;

class ObjectHandler : public sf::Drawable {

private:
    Player player;
    Block block;
    Projectile projectile;
    int hitX = 0;
    int hitY = 0;
    float checkX;
    float checkY;
    float keyFrameDuration = 0.0f;
    float speed = 500.0f;
public:
    ObjectHandler();
    virtual ~ObjectHandler();
    void updateProjectile(float dt);
    void updatePlayer(float dt);
    void updateBlock(float dt);
    virtual void draw(sf::RenderTarget &target, sf::RenderStates states) const;
};

#endif OBJECTHANDLER_H

#include "ObjectHandler.h"

ObjectHandler::ObjectHandler() {
    this->projectile = projectile;
    this->block = block;
    this->player = player;
}

ObjectHandler::~ObjectHandler() {
}

void ObjectHandler::updateProjectile(float dt) {
    sf::Vector2f direction;

    if (hitX == 0) {
        direction = sf::Vector2f(0.5f, checkY);
        checkX = 0.5f;
        if (this->projectile.getSprite().getPosition().x >= 700) {
            hitX = 1;
        }
    }
    else if (hitX == 1) {
        direction = sf::Vector2f(-0.5f, checkY);
        checkX = -0.5f;
        if (this->projectile.getSprite().getPosition().x <= 0) {
            hitX = 0;
        }
    }

    if (hitY == 0) {
        direction = sf::Vector2f(checkX, 0.5f);
        checkY = 0.5f;
        if (this->projectile.getSprite().getPosition().y >= 460) {
            hitY = 1;
        }
    }
    else if (hitY == 1) {
        direction = sf::Vector2f(checkX, -0.5f);
        checkY = -0.5f;
        if (this->projectile.getSprite().getPosition().y <= 0) {
            hitY = 0;
        }
    }

    this->projectile.getSprite().move(direction * speed * dt);
 }

void ObjectHandler::draw(sf::RenderTarget & target, sf::RenderStates states)   const {
    this->block.draw(target, states);
    this->projectile.draw(target, states);
    this->player.draw(target, states);
}

和游戏:
#ifndef GAME_H
#define GAME_H

#include <SFML\Graphics.hpp>
#include "ObjectHandler.h"

class Game : public sf::Drawable {
private:
    virtual void draw(sf::RenderTarget &target, sf::RenderStates states) const;
    sf::Texture backgroundTexture;
    sf::Sprite backgroundSprite;
    ObjectHandler object;
public:
    Game();
    virtual ~Game();
    void update(float dt);
};

#endif // GAME_H

#include "Game.h"
#include <iostream>
using namespace std;

void Game::draw(sf::RenderTarget & target, sf::RenderStates states) const {
    target.draw(backgroundSprite, states);
    target.draw(this->object, states);
    }

Game::Game() {
    if (!backgroundTexture.loadFromFile("../Resources/levelOne.jpg")) {
        cout << "The background could not be loaded!" << endl;
    }
    backgroundSprite.setTexture(backgroundTexture);
}

Game::~Game() {
}

void Game::update(float dt) {
    this->object.updatePlayer(dt);
    this->object.updateProjectile(dt);
    this->object.updateBlock(dt);
}

最佳答案

问题是您的sf::Sprite Projectile::getSprite()const返回了实际sprite的副本。因此,副本会调用projectile.getSprite().move(...)

为您的move设置方法Projectile:

void Projectile::move(const sf::Vector2f& amount)
{
    sprite.move(amount);
}

并以ObjectHandler命名:projectile.move(...)

您可能还想在getSprite中返回对子画面的常量引用,以避免出现多个副本:const sf::Sprite& Projectile::getSprite()const。当您尝试通过调用projectile.getSprite().move(...)对其进行修改时,它将导致错误,并且您会更快地看到该错误。

10-08 19:22