2017-02-27 8 views
1

SFML로 첫 번째 작은 프로젝트로 작업하고 있습니다. 나는 화면에서 튀는 공 (발사체)과 움직일 수있는 플레이어를 만들었다. 그러나 문제는 내 개체에 Objecthandler를 만들려고 할 때 발생했습니다. 핸들러가 오브젝트의 드로잉 및 업데이트를 제어하게 한 후에 플레이어와 볼은 멈추어 움직이지 못하게되었습니다. 내 질문은 왜? 공 :스프라이트가 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); 
} 
+0

일반적으로 모든 곳에서 "this->"를 삭제할 수 있습니다. C++에서는 특정 상황 (예 : 템플릿 클래스)을 제외하고는 멤버 함수를 직접 사용할 수 있습니다. – Lemko

+0

'ObjectHandler' 생성자를 비운다. 'this-> projectile = projectile' 등을 다시 지정할 필요는 없습니다. 생성자의 몸체를 입력하기 전에 초기화됩니다. – tntxtnt

+0

팁 주셔서 감사합니다! – Henke

답변

1

문제는 sf::Sprite Projectile::getSprite()const 실제 스프라이트의 사본을 반환 당신입니다. 따라서 projectile.getSprite().move(...)이 복사본에 의해 호출됩니다.

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

ObjectHandler에 전화 :

Projectile하는 방법 move을 확인 projectile.move(...)을.

getSprite에 대한 지속적인 참조를 여러 복사본을 피하기 위해 반환 할 수도 있습니다 (const sf::Sprite& Projectile::getSprite()const). projectile.getSprite().move(...)을 호출하여 수정하려고하면 오류가 발생하며 버그가 더 빨리 표시됩니다.

+0

오키, 정말 고마워. D 지금은 괜찮아. – Henke