I've heard of the white box issue, but why is only a black box rendering where my sprite is? My code was working fine until I gave the sprite its own class, then it stopped responding to all setPositions()'s and is only showing a 10*10 black box (the texture is 10*10 as well). Here is the new code I tried to implementFlashlight::Flashlight(){
light.setOrigin(light.getGlobalBounds().width / 4, light.getGlobalBounds().height / 2);
light.setPosition(250, 250);
light.setTexture(imgr.GetImage("images/light.png"));
}
light light is a class sprite. I set their velocites like this: if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
flashlight.AddVelocity(sf::Vector2f(-1, 0));
}
//and
void Flashlight::AddVelocity(sf::Vector2f increment){
velocityX += increment.x;
velocityY += increment.y;
}
//return functions
sf::Vector2f &Flashlight::GetVelocity(){
if(velocityX >= MAX_FLASHLIGHT_VELOCITY.x){
velocityX = MAX_FLASHLIGHT_VELOCITY.x;
}
if(velocityY >= MAX_FLASHLIGHT_VELOCITY.y){
velocityY = MAX_FLASHLIGHT_VELOCITY.y;
}
return sf::Vector2f(velocityX, velocityY);
}
sf::Sprite Flashlight::GetLight(){
return light;
}
//and move the sprite, which is also not working
void Engine::Update(float interpolation){
if(CollisionTest() == false){
flashlight.GetLight().move(flashlight.GetVelocity().x * interpolation * .8, flashlight.GetVelocity().y * interpolation * .8);
flashlight.GetShader().setPosition(flashlight.GetLight().getPosition());
}
}
Where flashlight is an object of my new class I created.
That's everything related to my new code. I'm not sure why the sprite is now unresponsive, but any help would be appreciated.
instead of
sf::Sprite Flashlight::GetLight(){
return light;
}
you should have a function
Flashlight::move(dt)
I think it's because you return a copy in this function
sf::Sprite Flashlight::GetLight(){
return light;
}
instead of a reference or pointer to the sprite.
It does say minimal and complete. While you have everything in your head and know what gets drawn where and when and how, we've no idea. ;)
For example: What does imgr.GetImage() return? If we couldn't deduce from the functions called, we wouldn't be able to know that light is a sprite. How are light and flashlight connected? How do you draw things? Do you copy that "different class" around? etc. etc.
I think it's because you return a copy in this function
sf::Sprite Flashlight::GetLight(){
return light;
}
instead of a reference or pointer to the sprite.
That doesn't have to be an issue. The texture reference will get copied as well.
How is one supposed to tell, why you are seeing a black square, without you even showing the code where your sprite is drawn? I can only say what has been said. Create a minimal example, that compiles, which illustrates your problem. Who knows, you might solve it yourself trying to do so. At least show more code. Maybe someone can find the error without making a program from it.
Nobody can guess what the error might be. Or maybe one could, but it wold most likely lead to nothing
One more thing: I checked the docs and couldn't find a ´setPosition()´ member function for shaders. This makes
flashlight.GetShader().setPosition(...
rather confusing
Ok, so here is a compile-able piece of code. The movement is glitchy, but whatever, the image draws on screen just fine. The black box issue comes in whenever I give the sprite flashlight its own class, which is why I had all the random bits of code. #include "stdafx.h"
#include "SFML\Graphics.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
sf::RenderWindow window;
window.create(sf::VideoMode(500, 500, 32), "Test");
sf::Sprite flashlight;
sf::Texture texture;
texture.loadFromFile("images/light.png");
flashlight.setTexture(texture);
const sf::Vector2i MAX_FLASHLIGHT_VELOCITY = sf::Vector2i(5, 5);
sf::Vector2f flashlightVelocity(0, 0);
while(window.isOpen()){
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
flashlightVelocity.x -= 1;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
flashlightVelocity.x += 1;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)){
flashlightVelocity.y += 1;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
flashlightVelocity.y -= 1;
}
if(flashlightVelocity.x > MAX_FLASHLIGHT_VELOCITY.x){
flashlightVelocity.x = MAX_FLASHLIGHT_VELOCITY.x;
}
if(flashlightVelocity.x < MAX_FLASHLIGHT_VELOCITY.x * -1){
flashlightVelocity.x = MAX_FLASHLIGHT_VELOCITY.x * -1;
}
if(flashlightVelocity.y > MAX_FLASHLIGHT_VELOCITY.y){
flashlightVelocity.y = MAX_FLASHLIGHT_VELOCITY.y;
}
if(flashlightVelocity.y < MAX_FLASHLIGHT_VELOCITY.y * -1){
flashlightVelocity.y = MAX_FLASHLIGHT_VELOCITY.y * -1;
}
flashlight.move(flashlightVelocity);
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
window.close();
window.clear();
window.draw(flashlight);
window.display();
}
return 0;
}
Like I said, that works. This will be long, but here is the full code of the flashlight class just so you guys can see what I am working with:
flashlight.h
#include "stdafx.h"
#include "SFML\Graphics.hpp"
#pragma once
#include "stdafx.h"
#include "ImageManager.h"
class Flashlight{
public:
Flashlight();
~Flashlight();
//individual functions for independent collision movement, set both x and y for regular movement
void AddVelocityX(float increment);
void AddVelocityY(float increment);
void AddVelocity(sf::Vector2f increment);
void SetVelocityX(float velocity);
void SetVelocityY(float velocity);
void SetVelocity(sf::Vector2f velocity);
sf::Vector2f &GetVelocity();
sf::Sprite &GetLight();
sf::Sprite &GetShader();
private:
void CheckVelocities();
//class objects
ImageManager imgr;
float velocityX, velocityY;
sf::Sprite light;
sf::Sprite shader;
};
flashlight.cpp
#include "stdafx.h"
#include "Flashlight.h"
const int SCREEN_WIDTH = 500;
const int SCREEN_HEIGHT = 500;
const sf::Vector2i MAX_FLASHLIGHT_VELOCITY = sf::Vector2i(5, 5);
Flashlight::Flashlight(){
//light.setOrigin(light.getGlobalBounds().width / 2, light.getGlobalBounds().height / 2);
light.setPosition(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
light.setTexture(imgr.GetImage("images/light.png"));
shader.setOrigin(SCREEN_WIDTH, SCREEN_HEIGHT);
shader.setPosition(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
light.setTexture(imgr.GetImage("images/shader.png"));
velocityX = 0;
velocityY = 0;
}
Flashlight::~Flashlight(){
}
void Flashlight::AddVelocityX(float increment){
velocityX += increment;
}
void Flashlight::AddVelocityY(float increment){
velocityY += increment;
}
void Flashlight::AddVelocity(sf::Vector2f increment){
velocityX += increment.x;
velocityY += increment.y;
}
void Flashlight::SetVelocityX(float velocity){
velocityX = velocity;
}
void Flashlight::SetVelocityY(float velocity){
velocityY = velocity;
}
void Flashlight::SetVelocity(sf::Vector2f velocity){
velocityX = velocity.x;
velocityY = velocity.y;
}
sf::Vector2f &Flashlight::GetVelocity(){
if(velocityX > MAX_FLASHLIGHT_VELOCITY.x){
velocityX = MAX_FLASHLIGHT_VELOCITY.x;
}
if(velocityX < MAX_FLASHLIGHT_VELOCITY.x * -1){
velocityX = MAX_FLASHLIGHT_VELOCITY.x * -1;
}
if(velocityY > MAX_FLASHLIGHT_VELOCITY.y){
velocityY = MAX_FLASHLIGHT_VELOCITY.y;
}
if(velocityY < MAX_FLASHLIGHT_VELOCITY.y * -1){
velocityY = MAX_FLASHLIGHT_VELOCITY.y * -1;
}
return sf::Vector2f(velocityX, velocityY);
}
void Flashlight::CheckVelocities(){
if(velocityX >= MAX_FLASHLIGHT_VELOCITY.x){
velocityX = MAX_FLASHLIGHT_VELOCITY.x;
}
if(velocityY >= MAX_FLASHLIGHT_VELOCITY.y){
velocityY = MAX_FLASHLIGHT_VELOCITY.y;
}
}
sf::Sprite &Flashlight::GetLight(){
return light;
}
sf::Sprite &Flashlight::GetShader(){
return shader;
}
I draw these sprites the exact same way as I did in the compile-able code:
window.clear(sf::Color::Black);
window.draw(flashlight.GetLight());
window.draw(flashlight.GetShader());
window.display();
These functions can be seen in the flashlight.cpp code. Sorry that's a little long, it's just hard to find a balance between too much code and incomplete code. Please continute to bear with me.
Wow, ok I found out the soultion while trying to provide a better code sample ;D So can anybody explain this to me? The solution was that I had to create the sf::Texture on a lower base class than the flashlight class. I'll demonstrate:class Flashlight{
//...
sf::Sprite flashlight;
//sf::Texture texture; this doesn't work here, it must "go down" a class
};
class BaseClass{
//...
//this class holds both the instance of the Flashlight object and the sf::Texture I was trying to use
Flashlight flashlight;
sf::Texture texture; //I moved the sf::Texture declaration to the class which holds the Flashlight object
//^^why is this necessary
}
My question: why does the sf::Texture need to be in the same class as the instance of the Flashlight object? Why can't a texture be in the same class as its sprite is? And I know this code is just pseudo-code, but that's because I'm just looking for a more abstract answer now as my problem seems to be solved.