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

Author Topic: Some newbie questions  (Read 1445 times)

0 Members and 2 Guests are viewing this topic.

Lkcynric

  • Newbie
  • *
  • Posts: 17
    • View Profile
Some newbie questions
« on: July 25, 2017, 05:52:09 pm »
I finally looked into state machines and made one, then ported my previous game (first SFML project) to it. Everything is working fine, but while porting it I got some questions that maybe I can get an answer to here.

Please note I don't need help, the game works, these are for future reference, to be honest don't know where to ask, so I will try it here.
I don't want to waste anyone's time, these are dumb questions, they came from my lack of programing and game creation knowledge.
Thank you if you decide to read it anyway.

SFML Relate Q:

1. - Should I always draw the screen every frame? Even for screens that never changes, like a High Score list screen. If I only display it once, the only "problem" is if I minimize the window, and it comes back it won't show anything but thats fixable with a "on minimize draw again".
Or drawing it uses so little resources anyway that its pointless to stop it (using a if(bool) in the drawing method.

1.5 - If I draw several lines of text on screen, like on a High Score screen, should I have a SF::text for every line, or use only one, have a string[] to save the strings and a for loop to display them in place.

2. - In my game I earn points every second, except when the game is paused. Since I can't pause a clock, every second I add 1 to a counter Var and restart the clock. So when I pause, it still only counts a sec. Is this a good way to do it? Or there's a smart way I couldn't think of.

3. - The only problem in my game is controls.  Here's some of it
sf::Event evt;
while (window.pollEvent(evt)) {
if (evt.type == sf::Event::KeyPressed)
     switch (evt.key.code) {
          case sf::Keyboard::P:
                if(paused)
                     unpause
                else
                     pause
          case sf::keyboad::W:
                blablabla...

If I press and hold P it pauses/unpauses the game every frame. I can solve this with a bool. (I don't like the "on key release", I like the responsiveness of "do it on keydown", because sometimes you hold the key just a little longer). I only pause/unpause if the bool is true. As soon as "keypressed" I set it to false, when key is release, I set it to true.

The real problem is... My game is a snake clone, so when I go right, I can't turn left before going up or down.
But, if I while going right, I press up then quickly left, I can move from left to right. I don't know how to solve this.
If I use the bool method, the game doesn't feel very responsive. And I think it still sometimes happens, its just harder to do.
If I use a clock and only process input every X ms... again, the controls don't feel responsive. Maybe I haven't found the right ms timing for it.
How could I solve this? I cant thin of a good solution.

NON SFML Q:
As I said, these are dumb questions from my lack of knowledge, feel free to laugh and ignore them.

4. - I use PRAGMA ONCE on my .hpp files. a.hpp includes b.hpp and c.hpp. But then d.hpp includes a.hpp but also b.hpp, that was included in a.hpp... its a mess.
It works, but should I leave it as a mess? (maybe thats how its supposed to be) or should I use a "hppList.hpp" put all of them inside, and include this list only one in the main?

5. - In my game I have to sometimes wait for 1 second in that place before proceding with the code.
I use while (timer.getElapsedTime().asMilliseconds() < 1250) {}.
Is there a better way to pause the code? Ive done it before, but not on c++ and can't remember how.

6. - I don't check for errors, all the textures/soundbuffers/fonts work and load correctly.
The game will work, unless you move/delete the assets. But if you do, its not my fault. Reinstall it.
Still, is it the wrong thing to do? IS there a point of showing a error saying the game crashed because it can't load a texture/whatever when it was the users fault?

7. - I have a lot of warnings (around 15), most of them from "int to float conversion".
Should I try fix those or ignore them since the game works and actually no useful info is lost in the conversion.

If you read this far, thank you for your time, sorry for the wall of text boss.


eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Some newbie questions
« Reply #1 on: July 25, 2017, 06:17:08 pm »
1. - Should I always draw the screen every frame? Even for screens that never changes, like a High Score list screen. If I only display it once, the only "problem" is if I minimize the window, and it comes back it won't show anything but thats fixable with a "on minimize draw again".
Or drawing it uses so little resources anyway that its pointless to stop it (using a if(bool) in the drawing method.
Yes, always fully redraw your screen.

1.5 - If I draw several lines of text on screen, like on a High Score screen, should I have a SF::text for every line, or use only one, have a string[] to save the strings and a for loop to display them in place.
Use multiple sf::Text objects. For light objects "in place" drawing can work, but sf::Text needs more setup and you'd waste a few processing cycles. For lots of text, rendering to a render texture might even perform better.
In most cases with a few lines of text on screen, it really doesn't matter as it won't have a big impact on performance.

2. - In my game I earn points every second, except when the game is paused. Since I can't pause a clock, every second I add 1 to a counter Var and restart the clock. So when I pause, it still only counts a sec. Is this a good way to do it? Or there's a smart way I couldn't think of.
You might want to use some kind of state machine, so you know code X gets executed when the menu is shown, code Y is executed when the game runs and code Z is executed when the game is paused etc.
There are many ways to implement such state machines.

3. - The only problem in my game is controls.  Here's some of it
You want to save the current input states separately. So you can differentiate between pressed, released and held down or anything in between; i.e. you change the state when the KeyPressed event is triggered and change it again when KeyReleased is triggered. Then you can save the state on the previous frame and if there was no change, you don't change your input either.
cur: pressed - prev: not pressed => change
cur: pressed - pre: pressed => no change
cur: not pressed - pre: pressed => no change
cur: not pressed - pre: not pressed => no change

4. - I use PRAGMA ONCE on my .hpp files. a.hpp includes b.hpp and c.hpp. But then d.hpp includes a.hpp but also b.hpp, that was included in a.hpp... its a mess.
It works, but should I leave it as a mess? (maybe thats how its supposed to be) or should I use a "hppList.hpp" put all of them inside, and include this list only one in the main?
No, using a single header file for other header files (pre compiled header) only starts to make sense for huge projects.
In a header file you should only include another header file if you're using the type from the other header file in this header file. If you use a reference or a pointer, you can just forward declare the type. If you only use the type in the source file, then include the header only in the source file.
Some good C++ reference should explain you how to deal with headers and forward declaration.

5. - In my game I have to sometimes wait for 1 second in that place before proceding with the code.
I use while (timer.getElapsedTime().asMilliseconds() < 1250) {}.
Is there a better way to pause the code? Ive done it before, but not on c++ and can't remember how.
[/code]
Busy-waiting loops are not a good solution. If you want an easy fix, but not really a good practice, you could use sf::sleep().
The real solution is to use some state machine that allows for a pause state where nothing happens.

6. - I don't check for errors, all the textures/soundbuffers/fonts work and load correctly.
The game will work, unless you move/delete the assets. But if you do, its not my fault. Reinstall it.
Still, is it the wrong thing to do? IS there a point of showing a error saying the game crashed because it can't load a texture/whatever when it was the users fault?
A crashing game is never a solution. You could just make if fail silently or not show anything on screen, but that's just hiding the problem and not a very good practice either.
You know how to detect if the resources were loaded correctly and you know ways to inform the user why something went wrong, so don't play the lazy card and not implement a user friendly system. ;)
If something doesn't load, you can inform the user with a specific message that something went wrong. Try to be as descriptive as possible, that way some users might be able to fix the problem on their own, while others might provide you descriptive error messages, that you can then tell them what to do.

7. - I have a lot of warnings (around 15), most of them from "int to float conversion".
Should I try fix those or ignore them since the game works and actually no useful info is lost in the conversion.
Yes, always aim for 0 warnings, always! If you want an explicit conversion, then do an explicit conversion with static_cast (and the like). Also keep in mind that the conversion between sf::Vector2f and sf::Vector2i are intentionally not implicit, because they'll usually represent different spaces and the conversion should happen through a function. For example the mouse position should always be map from screen space to world space with mapPixelToCoords and not just casted from int to float. Because once you move or change the view, your whole code would suddenly break.

Hope that helps a bit! :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Lkcynric

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Some newbie questions
« Reply #2 on: July 26, 2017, 02:35:09 pm »
Thank you so much! That helps a lot.

I have to handle input differently it seams. That actually makes sense, and will help with what I plan to do next. I wasn't sure how to do what I will need yet, but now I know.

I do have a state machine, but its simple and I am not using it correctly. I don't fully understand them yet (I will be adding more functionality as I understand it and get more experience working with them).
ATM my states are basically different game screens. Like, menu, highscore and game. The states have "initialization" "handle input" "update" and "draw". They are not really "game states" like.. is jumping or has a power up.

For some reason I didn't think of "paused game" as a different state, but it does make sense.

I also didn't implement "pause" "resume" for a state, since I don't understand it too well, and doesn't make sense (to me), the way I use my machine atm. My states are a stack and only the one on TOP runs, when I remove the top, if there is one bellow it will resume automatically.

Again, thank you so much! You helped me understand some things a little better :)
I still have a lot to learn, but I'm having so much fun.
Oh and your "Small game engine" also helped, I didn't fully understand it, but helped me create my simple one.