2017-02-27 7 views
1

Ich arbeite mit meinem ersten kleinen Projekt in SFML. Ich habe einen Ball (Projektil) gemacht, der auf dem Bildschirm herumspringt, und einen Spieler, der beweglich ist. Das Problem trat jedoch auf, als ich versuchte, einen Objekthandler zu meinen Objekten zu machen. Nachdem der Spieler die Kontrolle über das Zeichnen und Aktualisieren der Objekte übernommen hatte, hielten der Spieler und der Ball einfach an und wurden unbeweglich. Meine Frage ist warum? Der Ball:Sprites bewegen sich nicht in 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); 
} 

Der Handler:

#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); 
} 

Und Spiel:

#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); 
} 
+0

Als allgemeine Bemerkung können Sie das "this->" überall fallen lassen. In C++, außer in bestimmten Situationen (wie Template-Klassen), können Sie direkt die Member-Funktion verwenden. – Lemko

+0

Lassen Sie den Konstruktor von 'ObjectHandler' leer. Sie müssen 'this-> proctile = proctile' usw. nicht neu zuweisen. Sie werden alle initialisiert, bevor Sie den Körper des Konstruktors eingeben. – tntxtnt

+0

Vielen Dank für den Tipp! – Henke

Antwort

1

Das Problem ist Ihre sf::Sprite Projectile::getSprite()const eine Kopie des aktuellen Sprite zurückgibt. Daher werden projectile.getSprite().move(...) von der Kopie aufgerufen.

Machen Sie eine Methode move für Ihre Projectile:

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

und es in ObjectHandler nennen: projectile.move(...).

Sie können auch einen konstanten Verweis auf Ihr Sprite in getSprite zurückgeben, um mehrere Kopien zu vermeiden: const sf::Sprite& Projectile::getSprite()const. Es wird einen Fehler verursachen, wenn Sie versuchen, es zu ändern, indem Sie projectile.getSprite().move(...) aufrufen, und Sie werden den Fehler schneller sehen.

+0

Okey, vielen Dank: D Es funktioniert jetzt gut. – Henke