Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - SFMLNewGuy

Pages: 1 2 [3] 4 5
31
General discussions / SFML GameDevelopment LoadingState
« on: May 31, 2020, 08:15:30 pm »
Hello,

So I just had some help on a super barebone example on a loading state using a thread. I'm reading SFML Game Development still and I've come to a halt to try to understand how they incorporate the loading state so that it is actually reading the files instead of the mock loading they do.

I could just do what I learned in my previous thread, but I'd like to learn how to incorporate it using the book's design. The loading state is called when you click "Play" from the main menu. I'm just trying to understand when and where I would pass the fonts/texture data into loading and where?

Any help would be greatly appreciated. Here is the basics of what it offers.

#include "ParallelTask.h"


ParallelTask::ParallelTask()
: m_thread(&ParallelTask::runTask, this)
, m_finished(false)
{
}

void ParallelTask::execute()
{
        m_finished = false;
        m_elapsedTime.restart();
        m_thread.launch();
}

bool ParallelTask::isFinished()
{
        sf::Lock lock(m_mutex);
        return m_finished;
}

float ParallelTask::getCompletion()
{
        sf::Lock lock(m_mutex);

        // 100% at 10 seconds of elapsed time
        return m_elapsedTime.getElapsedTime().asSeconds() / 10.f;
}

void ParallelTask::runTask()
{
        // Dummy task - stall 10 seconds
        bool ended = false;
        while (!ended)
        {
                sf::Lock lock(m_mutex); // Protect the clock
                if (m_elapsedTime.getElapsedTime().asSeconds() >= 10.f)
                        ended = true;
        }

        { // mFinished may be accessed from multiple threads, protect it
                sf::Lock lock(m_mutex);
                m_finished = true;
        }      
}

#include "LoadingState.h"
#include "Utils/Helpers.h"
#include"ResourceHolder.h"

#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/View.hpp>


LoadingState::LoadingState(StateStack& stack, Context context)
: State(stack, context)
{
        sf::RenderWindow& window = *getContext().window;
        sf::Font& font = context.fonts->get(Fonts::Sansation);
        sf::Vector2f viewSize = window.getView().getSize();

        m_loadingText.setFont(font);
        m_loadingText.setString("Loading Resources");
        Helpers::position::centerOrigin(m_loadingText);
        m_loadingText.setPosition(viewSize.x / 2.f, viewSize.y / 2.f + 50.f);

        m_progressBarBackground.setFillColor(sf::Color::White);
        m_progressBarBackground.setSize(sf::Vector2f(viewSize.x - 20, 10));
        m_progressBarBackground.setPosition(10, m_loadingText.getPosition().y + 40);

        m_progressBar.setFillColor(sf::Color(32,170,14));
        m_progressBar.setSize(sf::Vector2f(200, 10));
        m_progressBar.setPosition(10, m_loadingText.getPosition().y + 40);

        setCompletion(0.f);

        m_loadingTask.execute();
}


bool LoadingState::handleEvent(const sf::Event& event) {
        return true;
}

bool LoadingState::update(sf::Time) {
        // Update the progress bar from the remote task or finish it
        if (m_loadingTask.isFinished()) {
                requestStackPop();
                requestStackPush(States::Game);
        }
        else {
                setCompletion(m_loadingTask.getCompletion());
        }
        return true;
}

void LoadingState::draw()
{
        sf::RenderWindow& window = *getContext().window;

        window.setView(window.getDefaultView());

        window.draw(m_loadingText);
        window.draw(m_progressBarBackground);
        window.draw(m_progressBar);
}


void LoadingState::setCompletion(float percent)
{
        if (percent > 1.f) // clamp
                percent = 1.f;

        m_progressBar.setSize(sf::Vector2f(m_progressBarBackground.getSize().x * percent, m_progressBar.getSize().y));
}
 

The previous thread (as in my post) a fine gentleman helped me learned how to accomplish a loading screen like this (was a barebone main.cpp example)

THIS IS NOT PART OF THE BOOK CODE, BUT AN EXAMPLE BEFORE LOOKING AT BOOK CODE
// Still in main thread
std::vector<std::shared_ptr<Tile>> tilesVector;
tilesVector.reserve(Map_Height * Map_Width); // This creates the tiles with default constructor ( Tile() )

std::atomic<bool> done(false);

// Create thread to execute the bellow code while main thread continues normal execution
std::thread t([&done, &tilesVector] {
// Tile creation IS the heavy duty work
for(auto y = 0; y < Map_Height; ++y)
{
    for (auto x = 0; x < Map_Width; ++x)
    {
       Tile * tile = tilesVector[y * Map_Width + x].get(); // Get a pointer to tile to change its attributes
       tile->spr.setSize(TILE_SIZE);
       tile->spr.setFillColor({ 0,255,0,15 });
       tile->spr.setOutlineColor(sf::Color::White);
       tile->spr.setOutlineThickness(1.f);
       tile->spr.setPosition(x * TILE_SIZE.x, y * TILE_SIZE.y);
       tile->spr.setOrigin(TILE_SIZE.x / 2.f, TILE_SIZE.y / 2.f);

       if (y >= 240 && y <= 260 && x >= 240 && x <= 260)
       {
             tile->spr.setFillColor({ 200,25,22 });
       }
                               
       // tiles.emplace_back(std::move(tile)); This line no longer needed, we already have our tile vector
    }
}

// After building the tiles we set variable to true to signal that our work
// (tile creation) on this separate thread is done.
done = true;

});

Thank you, and have a nice day.

32
General discussions / Re: sf::Thread (Loading Demo)
« on: May 25, 2020, 07:28:35 am »
Got it, I feel so stupid. My comment text is very transparent and I skipped over that obvious part about "HEAVY WORK". It's all working! Thank you very much!

EDIT: I wanted to add that it all works, but that way of initializing the tiles doesn't work for me. I don't know if it has to do with MSVC or what. But it's NULL (the Tile when grabbing at 0,0), so I've always just emplaced or pushed back at the end because I've seen someone do that as well.

33
General discussions / Re: sf::Thread (Loading Demo)
« on: May 24, 2020, 11:38:30 am »


Awesome, so I got it to work. But I'm wondering if this is actually okay to do? Keep in mind this is all just a boilerplate concept example, so I'm not striving for efficiency. But I had to make a little draw function and call it at the end of each tile emplace_back to the "Tile" vector. Because where it is freezing up, I want the "Loading..." text since it's technically loading the tiles. If I do it down by the draw method, it will never be shown because it's only hanging up as the tiles load. Note*By hanging up I mean turns completely white, almost like a 'stop responding' visual and then when it gets to draw works out great*

I hope that makes sense?

void draw(sf::RenderWindow& window, sf::Text& text) {
        window.clear();
        window.setView(window.getDefaultView());
        window.draw(text);
        window.display();
}

// Atomic variable guarantes that only one thread messes with it at a time
        std::atomic<bool> done(false);
        // Create shapes on another thread
        std::thread t([&done] {
                // DOING HEAVY DUTY WORK HERE
                done = true; // Set variable in the end to signal that its done
                });

for(auto y = 0; y < Map_Height; ++y)
                for (auto x = 0; x < Map_Width; ++x) {
                        //std::unique_ptr<Tile> tile(new Tile());
                        std::shared_ptr<Tile> tile(new Tile());
                        tile->spr.setSize(TILE_SIZE);
                        tile->spr.setFillColor({ 0,255,0,15 });
                        tile->spr.setOutlineColor(sf::Color::White);
                        tile->spr.setOutlineThickness(1.f);
                        tile->spr.setPosition(x * TILE_SIZE.x, y * TILE_SIZE.y);
                        tile->spr.setOrigin(TILE_SIZE.x / 2.f, TILE_SIZE.y / 2.f);

                        if (y >= 240 && y <= 260 && x >= 240 && x <= 260)
                                tile->spr.setFillColor({ 200,25,22 });
                        tiles.emplace_back(std::move(tile));

                        if (!done)    //******** DRAWING LOADING HERE *******
                                draw(window, loadText);
                }
                       while(window.open()){ ....}
 

So I'm just asking if this is actually okay to do and how could you prevent drawing out of the game loop? From everything I've learned this just seems out of place and this could be why I've struggled in the past. How would you improve on this if I was going for efficiency and correctness? This has already taught me so much because I've always had a really hard time understanding Loading bar concepts. So this simple example is very informative. Thanks!

EDIT: I tried to make the text flicker, and it's not doing what I intended so I'll wait for your response because I'm for sure doing something wrong. Thanks

34
General discussions / Re: sf::Thread (Loading Demo)
« on: May 23, 2020, 10:24:37 pm »
Hello,

I appreciate the message and I'll give it a shot later on tonight. I just wanted to thank you real quick.

35
General discussions / sf::Thread (Loading Demo)
« on: May 21, 2020, 06:44:15 pm »
Hello,

So I'm messing with another concept, threads. I was trying to follow the SFML tutorial on threads, but it's not doing what I thought it would. I have no experience dealing with threads and just know roughly what Mutex and a Thread are.

I have this demo of a 500x500 tilemap of rectangles. And my original concept was finding ways to do tile culling. I solved, but I still get the white window until it loads everything up, then it runs perfectly. So I thought this would be a good time to try out threads and see if I can display a "Loading" sf::Text until it has gathered all the sprites up.

Also, I tried to use std::bind when initializing the thread, but it doesn't work because it is a deleted function. I'm using msvc19. But I got it to work with a lambda, but the results were the same. I put a comment giving the error when I try the std::bind and when I use the lambda. I

Quote
/*Failed to activate the window's context Failed to activate OpenGL context: The requested resource is in use.*/

So I'm assuming it obviously is trying to access data that's being used? ...Right ???? Any help would be appreciated, have a nice day!

#include <SFML/Graphics.hpp>
#include <iostream>
#include <functional>

sf::Vector2u WINDOW_SIZE{1400,900};
constexpr unsigned TPS = 60; //ticks per seconds
const sf::Time     timePerUpdate = sf::seconds(1.0f / float(TPS));
sf::Vector2f TILE_SIZE{64.f,64.f};

struct Tile
{
        sf::RectangleShape spr;
};


void loadingText(sf::RenderWindow& window, sf::Font& font, const std::string& text) {
        sf::Text loadText{ text,font,25 };
        loadText.setPosition((float)window.getSize().x / 2.f, (float)window.getSize().y / 2.f);
        loadText.setFillColor(sf::Color{ 88,225,0 });
        loadText.setOutlineThickness(1.f);
        loadText.setStyle(sf::Text::Style::Underlined | sf::Text::Style::Bold);
        window.draw(loadText);
}


int main() {
        sf::RenderWindow window{ sf::VideoMode{WINDOW_SIZE.x,WINDOW_SIZE.y},"" };
        //      window.setFramerateLimit(60);
        window.setPosition(sf::Vector2i{ window.getPosition().x,0 });

        bool lostFocus = false;
        sf::Clock clock;
        auto lastTime = sf::Time::Zero;
        auto lag = sf::Time::Zero;
        auto dt = 0.f;
        unsigned ticks = 0;
        auto view = window.getDefaultView();

        sf::Font font;
        if (!font.loadFromFile("fonts/arial.ttf"))
                std::cout << "Failed to load arial.ttf\n";


        sf::Thread thread([&]() {
                loadingText(window, font, "Loading");
                });
        /*Failed to activate the window's context Failed to activate OpenGL context: The requested resource is in use.*/
        thread.launch();

//***sf::Thread thread(std::bind(&loadingText, window, font, "Loading...")); *** (Doesn't Work)

/*Severity      Code    Description     Project File    Line    Suppression State
Error   C2280   'std::_Binder<std::_Unforced,void (__cdecl *)(sf::RenderWindow &,sf::Font &,
const std::string &),
sf::RenderWindow &,sf::Font &,
const char (&)[11]>::_Binder(const std::_Binder<std::_Unforced,void (__cdecl *)(sf::RenderWindow &,
sf::Font &,
const std::string &),
sf::RenderWindow &,sf::Font &,
const char (&)[11]> &)'
: attempting to reference a deleted function    E:\Libaries\SFML\include\SFML\System\Thread.inl 70
*/


        constexpr int Map_Width = 500;
        constexpr int Map_Height = 500;
        std::vector<Tile> tiles;

        sf::RectangleShape camera{ TILE_SIZE };
        camera.setFillColor({ 255,255,255,100 });
        camera.setOutlineThickness(1.f);
        camera.setOutlineColor(sf::Color::White);

        for(auto y = 0; y < Map_Height; ++y)
                for (auto x = 0; x < Map_Width; ++x) {

                        auto tile = new Tile;
                        tile->spr.setSize(TILE_SIZE);
                        tile->spr.setFillColor({ 0,255,0,15 });
                        tile->spr.setOutlineColor(sf::Color::White);
                        tile->spr.setOutlineThickness(1.f);
                        tile->spr.setPosition(x * TILE_SIZE.x, y * TILE_SIZE.y);

                        if (y >= 240 && y <= 260 && x >= 240 && y <= 260)
                                tile->spr.setFillColor({ 200,25,22 });

                        tiles.emplace_back(*tile);
                }

        view.setCenter(Map_Width / 2.f * TILE_SIZE.x, Map_Height / 2.f * TILE_SIZE.y);
        while (window.isOpen()) {

        auto time = clock.getElapsedTime();
        auto elapsed = time - lastTime;
        lastTime = time;
        lag += elapsed;

        //Fixed time update
        while (lag >= timePerUpdate)
        {
            ticks++;
            lag -= timePerUpdate;
            //x fixedUpdate(elapsed);
        }

                        sf::Event event{};
                        while (window.pollEvent(event)) {
                                if (event.type == sf::Event::Closed ||
                                    event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
                                        window.close();
                                if (event.type == sf::Event::KeyPressed) {
                                        switch (event.key.code) {
                                                case sf::Keyboard::Enter: std::cout << "Enter Pressed\n"; break;
                                                case sf::Keyboard::Space: std::cout << "Space Pressed\n"; break;
                                                default: break;
                                        }
                                }
                                if (event.type == sf::Event::Resized) {
                                        // update the view to the new size of the window
                                        view.setSize(static_cast<float>(event.size.width),
                                                           static_cast<float>(event.size.height));
                                }
                                if (event.type == sf::Event::LostFocus)     { lostFocus = true; }
                                if (event.type == sf::Event::GainedFocus) { lostFocus = false; }
                        }

                        if (!lostFocus) {
                                auto mousePos = sf::Mouse::getPosition(window);
                                auto mouseWorldPos = window.mapPixelToCoords(mousePos, view);

                                window.setTitle("Mouse Position: (" + std::to_string(int(mouseWorldPos.x / 64.f)) + ", " +
                                        std::to_string(int(mouseWorldPos.y / 64.f)) + ")");

                                if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
                                        if (mouseWorldPos.x >= 0 && mouseWorldPos.y >= 0 &&
                                                mouseWorldPos.x < WINDOW_SIZE.x &&
                                                mouseWorldPos.y < WINDOW_SIZE.y) {
                                        }
                                }

                                //! ** INPUT SECTION **
                                if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
                                        view.move(0, -100 * elapsed.asSeconds());
                                }
                                if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
                                        view.move( -100 * elapsed.asSeconds(),0);

                                }
                                if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
                                        view.move(0, 100 * elapsed.asSeconds());

                                }
                                if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
                                        view.move(100 * elapsed.asSeconds(), 0);

                                }

                                //! ** UPDATE SECTION**                
                                window.setView(view);
                        }

               
                        //! ** DRAW SECTION **
                        window.clear();

                        camera.setPosition(view.getCenter());

                        int cam_posX = camera.getPosition().x;
                        int cam_posY = camera.getPosition().y;
                        cam_posX /= TILE_SIZE.x;
                        cam_posY /= TILE_SIZE.y;
                        int minMaxWidth = 12;
                        int minMaxHeight = 12;

                        //std::cout << "Camera: " << camera.getPosition().x << ", " << camera.getPosition().y << "\n";
                        //std::cout << "View: " << view.getCenter().x << ", " << view.getCenter().y << "\n";
                        //std::cout << "posX: " << posX << "\n";
                        //std::cout << "posY: " << posY << "\n";
                        for (auto y = cam_posY - minMaxHeight < 0 ? 0 : cam_posY - minMaxHeight;
                                      y <= cam_posY + minMaxHeight && y < WINDOW_SIZE.y; y++) {
                                for (auto x = cam_posX - minMaxWidth < 0 ? 0 : cam_posX - minMaxWidth;
                                              x <= cam_posX + minMaxWidth && x < WINDOW_SIZE.x; x++) {
                                        window.draw(tiles[y * Map_Width + x].spr);
                                }
                        }
                        window.draw(camera);

                        window.setView(window.getDefaultView());               
                        window.display();
                }
       
        return EXIT_SUCCESS;
}




36
General discussions / Re: SFML Game Development (book) adding tiles
« on: May 13, 2020, 04:27:59 am »
For those curious, I did speak to the author of SFML Game Development (Jan Haller) and he provided me with excellent information regarding adding a tile system. He suggested I provide the answer to my own link. This is what he recommends for those interested or possibly have similar goals.
Quote

From Jan Haller:

1. Make a data model (i.e. class/struct) for a tile. A tile may contain:
       
  • the tile type (Grass, Dirt, Trees, Water, ...) -- preferably a C++11 enum class
  • if you want, a variant (if you have multiple Grass variants, to make it look less regular) as an integer
  • the position (integer x/y coordinates, which express the index in the tile map) -- this is not needed inside the tile class, but can simplify things
  • if needed, extra topological information, such as elevation/height
  • possibly a reference to game elements, such as a structure constructed on it

 6. Make a data model for a tile map. A tile map is a collection of tiles (std::vector), together with its size.
    Design a nice TileMap class with encapsulation. Some challenges:
       
  • Tile& operator[] (sf::Vector2i tileCoord) to access a tile at given index (+ const overload)
  • accessors for size
  • bounds checking with assert
  • an easy way to iterate over all tiles, e.g. a method taking std::function which is applied to each tile
  • constructor with size + possibly tile generator function

 6. Create some tile graphics. Make sure each has the same square size, and store all in a single .png file.
    Load it as sf::Texture.

 7. Draw your tilemap using sf::VertexArray. This class can efficiently batch draw calls, so you won't need to draw each tile separately, resulting in considerable speedup.
    The vertex array can reference the texture you just loaded and is effectively an alternative to sf::Sprite.
    Choose the texture rect depending on tile type and variant.
    Consult SFML tutorial and documentation to get familiar with those (we also have some vertex array examples in the book, under Particles).

  8. Once your tile map is populated (steps 1+2) and rendered (step 4), it's time to integrate it into the
     book's code. Clone the official repo and start either at the latest chapter (10), or 9 if you don't need
     network.
     Add a new node class, which contains your TileMap instance and a vertex array. Override the
     draw() function to draw the vertex array. Override update() if you want to change the tilemap over time,
     or implement logic (such as collision with certain tiles).

Hope that helps as a start!
Jan

Additionally, when I asked if I should derive TileMap from SceneNode:

Quote
No, I would keep them separate. So you end up with 4 types:
  • enum class TileType
  • class Tile
  • class TileMap
  • class TileNode (or TileMapNode) -- this one will  hold a TileMap + sf::VertexArray instance.

Thanks again Jan!

37
General / Re: Rotating Tiles and keeping the player within Tile
« on: May 12, 2020, 03:31:01 am »
Hey,

Thanks for the attempt to help me. I greatly appreciate it. I wanted to clarify that I'm understanding your solution? Because it's not working out. I'm not exactly sure what you mean by "don't forget to rotate?" I'm sure there is something simple I'm missing. Following up, is there any way you can explain what's going on exactly to achieve this? What should I be searching to look more into this? Thanks

 
                auto playerPosition = player.getPosition();

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
                       for (auto& tile : m_map)                        
                                tile.rotate(-5);

                       for (auto& tile : inner_map)
                                tile.rotate(-5);

                        sf::Vector2f convertedPlayerPosition{
       m_map[7 * MapWidth + 11].getInverseTransform().transformPoint(playerPosition) };

                       player.rotate(-5);

                        sf::Vector2f newPlayerPosition{
         m_map[7 * MapWidth + 11].getTransform().transformPoint(convertedPlayerPosition) };

                      player.setPosition(newPlayerPosition);
/} // Q Key End
 

if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) {
                        for (auto& tile : m_map)
                                        tile.rotate(5);

                        for (auto& tile : inner_map)
                                        tile.rotate(5);

                         sf::Vector2f convertedPlayerPosition{
         m_map[7 * MapWidth + 11].getInverseTransform().transformPoint(playerPosition) };

                         player.rotate(5);

                         sf::Vector2f newPlayerPosition{
         m_map[7 * MapWidth + 11].getTransform().transformPoint(convertedPlayerPosition) };

                         player.setPosition(newPlayerPosition);        
}  // E Key End
 
PS: Yes, I want the rectangle (player) to stay within the rectangle (tile) that it is in. I hardcoded the player's position at (11, 7) to try to see if it worked. I tried to make the code look nice here, sorry if it looks bad.

38
General / Rotating Tiles and keeping the player within Tile
« on: May 12, 2020, 12:51:31 am »
Hello,

This is just a concept I'm trying to understand, I got curious about :-X. I have basic sf::RectangleShape's in a Tile struct and just being displayed 50 by 50 with a 64x64 tile size. I have a 32x32 rectangle shape considered the player that you can move around with the WASD keys.

With Q and E I have a backward and forward rotation of all tiles by -5 and 5. How exactly could I maintain keeping the player within the same tile? So essentially, moving by the rotation of the tiles? I thought I could just grab the position of the tile the player is on and rotate him the same amount. But that doesn't seem to work.

Thanks

39
General discussions / Re: Why is intersect too "basic?"
« on: May 01, 2020, 09:00:16 pm »
Thanks for the response. I'd appreciate it and the example.

40
General discussions / Why is intersect too "basic?"
« on: April 30, 2020, 01:07:12 am »
Hello,

I was wondering what exactly is the gripe with the built-in intersect function in SFML? Why do people say to do your own for more accurate detection (along those lines)?

Can someone tell me why you wouldn't use the built-in feature and what it does that "your own" would?

How I was always taught was checking each side of a square and if it intersects, return true. So it can't be THAT different and seems exaggerated. Perhaps the built-in function would cause problems in a quadtree?

41
General discussions / SFML Game Development (book) adding tiles
« on: April 27, 2020, 02:21:32 am »
Hello,

I've been reading over this book, which I think the source code is actually on the SFML Github so that makes me think someone here made it. For those who have read it, I was wondering how someone might implement a tile system using the same engine the book walks you through. Preferably, it would be nice to see source code with the same engine customized with tiles and not overly done with other features (kept basic). I've read all the SFML books, but this is the only one that actually goes into implementing gameplay more complex and going past just the engine (forgot about the side scroller By Example does). So I've decided to read this again with more attention. One of my major problems is learning how to take, say, take this example, and expand on it my own way (or RPG genre from Airplane scroller). SFML Game Development By Example is one of my favorite books, but trying to add on to it is a bit complex still, which is why I came back to this book which implements a nice little engine and shows how to do gameplay content in a more straightforward way.

I figured I could make a tile system using the SceneNode. But I'm not exactly sure if that's a good way to do it. I'm not sure if it would involve changing too much. When I read Procedural Generation Content for C++, it had a Tile struct (which I'd consider a node because of the parent pointer) and allowed you to do pathfinding easy. Which is something I really don't want to make difficult, because I've had trouble implementing pathfinding outside of the way they show it.

I made a hardcoded example and I got tiles to appear instead of the desert scrolling background. But I want to implement this in a class that would be the most efficient way. The reason I'm hesitant is because of how the SceneNode interacts with the airplanes in a tree-like behavior. It's not exactly the same way I have learned to do tiles (from books and myself). For clarity, I would be changing the whole genre of the book.

I don't want to continue to ramble on, but any help would be appreciated (especially, with examples). I hope this makes sense.

Thank you! Be safe and have a nice day.

tldr; Using SFML Game Development, by Artur Moreira how can I implement a tile system efficiently and if anyone has examples using the concepts from this book I'd greatly appreciate it.

NOTE: I'm not talking about SFML Game Development By Example! Although, it is my favorite book!

EDIT: I did see a thread similar to this one here, but it didn't provide me with any help.

42
Graphics / Re: RenderTexture Help
« on: April 24, 2020, 08:47:57 pm »
Okay!  :)   I recreated the program and I have the same problem.

Game.h
{

struct Tile{ sf::Sprite sprite; sf::Vector2f pos; }
...
private:
sf::RenderTexture m_renderTexture;
std::vector<std::vector<Tile> m_TileMap;
}
Here is the Game.cpp code.


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


const sf::Time Game::TimePerFrame = sf::seconds(1.f / 60.f);
const float TILE_SIZE = 32;
int MAP_WIDTH = 15;
int MAP_HEIGHT = 15;

Game::Game()
    : m_window({WINDOW_SIZE.x,WINDOW_SIZE.y},"RenderTexture Example")

{

    m_window.setPosition({ m_window.getPosition().x, 0 });
    m_window.setVerticalSyncEnabled(true);

    MAP_WIDTH = m_window.getSize().x / TILE_SIZE;
    MAP_HEIGHT = m_window.getSize().y / TILE_SIZE;

    sf::Texture tex;
    tex.loadFromFile("media/grass.png");

    m_renderTexture.create(MAP_WIDTH * TILE_SIZE, MAP_HEIGHT * TILE_SIZE);


    for (auto i = 0; i < MAP_HEIGHT; i++) {
        m_tileMap.emplace_back();
        for (auto j = 0; j < MAP_WIDTH; j++) {
            auto newTile = new Tile;
            newTile->sprite.setTexture(tex);
            newTile->pos = sf::Vector2f{ j * TILE_SIZE ,i * TILE_SIZE };
            m_tileMap[i].push_back(*newTile);
        }
    }
    m_renderTexture.clear();

    for (auto& tile : m_tileMap) {
        for (auto& it : tile) {
            it.sprite.setPosition(it.pos);
            m_renderTexture.draw(it.sprite);
        }
   }

    m_renderTexture.display();
   

}

void Game::run()
{
    sf::Clock clock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;

     while (m_window.isOpen()) {
            const sf::Time elapsedTime = clock.restart();
        timeSinceLastUpdate += elapsedTime;

     while(timeSinceLastUpdate > TimePerFrame) {
               timeSinceLastUpdate -= TimePerFrame;
     
                processEvents();
                update(TimePerFrame);
        }
 
        render();
    }
}

void Game::processEvents()
{
    sf::Event event{};
    while (m_window.pollEvent(event)) {
        switch (event.type) {
            case sf::Event::KeyPressed:
                  handlePlayerInput(event.key.code, true);
                if(event.key.code == sf::Keyboard::Escape)
                    m_window.close();
            break;

            case sf::Event::KeyReleased:
                handlePlayerInput(event.key.code, false);
            break;

            case sf::Event::Closed:
                if(event.type == sf::Event::Closed)
                    m_window.close();
            break;
            default: break;
        }
    }

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
 

        m_tileMap[5][5].sprite.setColor(sf::Color::Red);
        m_renderTexture.clear();

        for (auto& tile : m_tileMap) {
            for (auto& it : tile) {
                it.sprite.setPosition(it.pos);
               
                m_renderTexture.draw(it.sprite);
            }
        }

        m_renderTexture.display();
    }
}


void Game::update(sf::Time elapsedTime)
{
 
}

void Game::render()
{
    m_window.clear();
 
    auto& texture = m_renderTexture.getTexture();

    m_window.draw(sf::Sprite(texture));

    m_window.display();
}

void Game::handlePlayerInput(const sf::Keyboard::Key key, const bool isPressed) {

}

EDIT: And just to tell you the problem again. When I hit space to set tileMap[5][5] sprite color to red. The screen goes all white where the tiles once were and a red square (not tile sprite) shows up.

SOLVED: Okay, I just set the texture to a member variable and added it in the "keypressed(space)" section and I got it to work. I'd like to ask an additional question. Because I realized this worked without ever using m_renderTexture.clear() and m_renderTexture.display(). When exactly would I need to use this? I thought I used it every time I draw to a sf::RenderTexture?

43
Graphics / Re: RenderTexture Help
« on: April 24, 2020, 01:52:04 am »
Sorry to bump this, but I still haven't found any answer or have solved this. Whatever I do I just get a blank white screen with a red square (not a red-colored tile) once I try to redraw to it. I wish I could find more tutorials involving RenderTexture. There seems to be a huge lack of information. It's not a serious problem, I was just making an example to better understand it.

I know longer have my example, but I was wondering if setting the window.clear() to sf::Color::Transparent. It would have been my next thing to try. It basically just becomes a huge white square with a red square where the tile was. So I was wondering if it's underneath it.

PS: Any more complex example than the one on the SFML page would be appreciated. Thanks

44
Graphics / RenderTexture Help
« on: April 22, 2020, 05:35:01 am »
Hello,

Had a quick question about RenderTexture, which I'm trying to understand better (off screen drawing).

I have a initialize class where I do this

 

init() {
...
 if (!renderTexture.create(50*32, 50*32)) {
        std::cout << "Error: creating renderTexture\n";
    }

    renderTexture.clear();

    for (auto i = 0; i < 50; i++) {
        for (auto j = 0; j < 50; j++) {
            tiles[j][i].sprite.setPosition(tiles[j][i].pos);
            renderTexture.draw(tiles[j][i].sprite);
        }
    }

    renderTexture.display();
}
 

    In my draw function, I have...
void draw(){
    const sf::Texture& tex = renderTexture.getTexture();

    m_window.clear();
    m_window.draw(sf::Sprite(tex));
    m_window.draw(m_player);
    m_window.display();
}
 


Now here is the part it is messing up. I added a space key to change tile[10][10] to a red tile and try to update it all and it creates all the tiles (50x50 Map/32x32 Tiles) white (losing the texture) except the 10x10 tile.


 
void handleInput(){
...
   if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
        // drawing uses the same functions
        if (!renderTexture.create(50 * 32, 50 * 32)) {   // may not need this?
            std::cout << "error\n";
        }
        renderTexture.clear();
        for (auto i = 0; i < 50; i++) {
            for (auto j = 0; j < 50; j++) {
                tiles[j][i].sprite.setPosition(tiles[j][i].pos);
                if (i == 10 && j == 10)
                    tiles[j][i].sprite.setColor(sf::Color::Red);

                renderTexture.draw(tiles[j][i].sprite);
            }
        }
         

          renderTexture.display();
     }
}
    }

Any help would be appreciated, I'm just trying to learn how to use this more in this example since a few times I feel this concept would have been handy to know. I understand that it would be better to just put a red color sprite on top since this seems to be demanding to constantly run except the initial part.

45
General / Re: mapPixelsToCoords vs mapCoordsToPixels
« on: March 24, 2020, 02:40:52 am »
Hey,

Sorry to get back a little late. I appreciate the response and example. I'm going to have to read it a few times to really grasp it haha. I know when you are setting up a view for split-screen for example, you would use the 0-1 to get the view to appear where you want.

I'm pretty sick right now and having trouble thinking, but I just wanted to say thanks for the help.

Pages: 1 2 [3] 4 5
anything