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

Author Topic: Own Text Drawing System from sf::Sprites  (Read 2300 times)

0 Members and 1 Guest are viewing this topic.

CopyDevil

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Own Text Drawing System from sf::Sprites
« on: October 11, 2012, 06:07:08 pm »
I've got a problem that may just be caused by the wrong way of thinking.
But anyways, I need some help with it:

I made a system for drawing text to the screen by printing char after char from subrects of one sf::Sprite.
When the first character is drawn, i move the position of my sprite by the width of a char and draw the next one.
This is done in a "for"-loop which cycles through every character of a string that is passed.
My problem occurs when calling this function: The loop doesn't finish, even if the string ends.
It just keeps going on, which results in the characters getting drawn over and over again while moving out of the screen, as their position is updated every frame.
So, do you guys have any idea on how correct the loop?
Or is the error maybe a completely different one?

So, here is the relevant code:

main.cpp

#include "menu.hpp"

int main()
{
    Menu Menu;

    while (Window.IsOpened())
    {
        Window.Clear(sf::Color(255, 204, 153));

        Menu.DrawCharacters("ABC", Window);

        Window.Display();
    }

    return 0;
}
 

menu.cpp

void Menu::DrawCharacters(string Text, sf::RenderWindow &Window)
{
    for(unsigned int x = 0; x != Text.length(); x++)
    {
        if(Text[x] == 'A') { CharIndexX = 0; CharIndexY = 0; }
        if(Text[x] == 'B') { CharIndexX = 1; CharIndexY = 0; }
        if(Text[x] == 'C') { CharIndexX = 2; CharIndexY = 0; }

        CharacterSprite.SetSubRect(sf::IntRect(CharIndexX * CharWidth, CharIndexY * CharHeight, CharIndexX * CharWidth + CharWidth, CharIndexY * CharHeight + CharHeight));
        CharacterSprite.SetPosition(CharPositionX + CharWidth * CharPositionXIndex, CharPositionY);
        CharPositionXIndex++;
        Window.Draw(CharacterSprite);
    }
}

void Menu::Initialize();
{
    CharacterImage.LoadFromFile("images/characterset.png");
    CharacterImage.SetSmooth(false);
    CharacterSprite.SetImage(CharacterImage);

    CharWidth = 12;
    CharHeight = 24;

    CharIndexX = 0;
    CharIndexY = 0;

    CharPositionX = 100;
    CharPositionY = 100;

    CharPositionXIndex = 1;
}
 

menu.hpp

#ifndef MENU_HPP
#define MENU_HPP

class Menu
{
    public:

        void Initialize();
        void DrawCharacters(string Text, sf::RenderWindow &Window);

        int CharWidth;
        int CharHeight;

        int CharIndexX;
        int CharIndexY;

        int CharPositionX;
        int CharPositionY;

        int CharPositionXIndex;

        sf::Image CharacterImage;
        sf::Sprite CharacterSprite;
};

#endif
 
« Last Edit: October 11, 2012, 07:25:26 pm by CopyDevil »

cha0s

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Own Text Drawing System from sf::Sprites
« Reply #1 on: October 11, 2012, 08:24:38 pm »
Kinda hard to tell, but I'd suggest putting this:

CharPositionXIndex = 1;

Just after and outside your for loop, to reset the x position after the string is rendered.

CopyDevil

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Own Text Drawing System from sf::Sprites
« Reply #2 on: October 11, 2012, 08:37:17 pm »
Hell Yeah!
This worked perfectly, thanks!

But even if the positioning now works, the rendering continues to be done.
So, if I take the function call out of the game loop and attached it per example to a single key press, would the function (and the for loop) just get executed a single time or would it continue to be drawn over and over again with this code? If so, is there any possiblility of calling the function just once?

But actually, I think this wouldn't cause any performance issues considering RAM or CPU power, as Bitmaps are destroyed dynamically in SFML, if I am informed correctly...
« Last Edit: October 11, 2012, 09:00:04 pm by CopyDevil »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10991
    • View Profile
    • development blog
    • Email
Re: Own Text Drawing System from sf::Sprites
« Reply #3 on: October 11, 2012, 10:11:44 pm »
I'm not sure what you'd expect to happen, if you call the function every iteration/frame it will obviously render every frame...
So what should in your opinion happen?

Did you understand how SFML works (i.e. clear window, render objects, display them)?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

CopyDevil

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Own Text Drawing System from sf::Sprites
« Reply #4 on: October 11, 2012, 10:26:16 pm »
I was refering to a new situation:
Before I've done the change in code, which was proposed by cha0s, i tried moving the function call to a keypress event which resulted in getting stuck inside the for-loop and rendering on and on.
But I'm not sure, if this problem also exist with the new code. If so, I asked myself whether it is possible to kind of break the loop after one execution (after the text has been rendered already) and never enter it again at runtime.

And yes, I presume I understood those basic things so far, but this concerns the little peculiarities of SFML which can sometimes be handled a bit strange...
« Last Edit: October 11, 2012, 10:52:10 pm by CopyDevil »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10991
    • View Profile
    • development blog
    • Email
Re: Own Text Drawing System from sf::Sprites
« Reply #5 on: October 11, 2012, 10:59:31 pm »
But I'm not sure, if this problem also exist with the new code. If so, I asked myself whether it is possible to kind of break the loop after one execution (after the text has been rendered already) and never enter it again at runtime.
But then it would only get displayed for one single frame which you probably won't even really notice...

If you want things to happen once you can simply us a boolean, declare & initialize it outside the game loop, wrap the wanted code section into a if(!hasHappend) { ... } and set it to true inside that if-block, so that code section will only be called once.

Anyways if you want us to help with the specific problem you have to provide more information/code than your vague descriptions. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

CopyDevil

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Own Text Drawing System from sf::Sprites
« Reply #6 on: October 12, 2012, 01:13:22 pm »
OK, thank you very much, that solved it!
It was more like a c++-related question, but thanks for your quick answers ;-)

 

anything