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

Author Topic: Unknown problem with drawing.  (Read 2775 times)

0 Members and 1 Guest are viewing this topic.

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Unknown problem with drawing.
« on: November 25, 2013, 04:41:12 pm »
I'm having some trouble with drawing tiles from a tile engine I'm working on. I'm honestly not sure if it's just a fluke, or if there's something causing it, but I wrote a quick and dirty level generator that isn't meant to actually generate anything special... it's just meant to show random tiles so I can play around with the tiles themselves. The problem, however, is that sometimes, I'll get tiles that half-appear, or appear to push other tiles over a random number of pixels.

This only seems to happen after I re-generate the level 5+ times, but hey... it's random, so who knows, right?

So is there something I'm doing wrong here?

SFMLApp.h: http://pastebin.com/67LNpf9V
SFMLApp.cpp: http://pastebin.com/NrjQKSKz
Level.h: http://pastebin.com/Ve4FET96
Level.cpp: http://pastebin.com/60WXYBfA
Tile.h: http://pastebin.com/DSU6C5xM
Tile.cpp: http://pastebin.com/C5eG5q6J

Seems like a lot of code to ask you to review, but really all you should need to look at is the GenerateLevel() method of the SFMLApp class and the Tile class' constructor and Draw() method. I just included the rest in case you need to see how I'm handling something specific.

I've attached some screenshots of the problem itself. All tiles should be the same distance from each other... 48 px, and if you'll notice, some of the tiles are pushed over slightly, or the tile's image itself will even be cut off.

Can anyone take a guess as to what's causing this?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Unknown problem with drawing.
« Reply #1 on: November 25, 2013, 05:25:26 pm »
bool turn = (((rand() % 20) + 1) > 9);
xDir = ((((cX + xDir) >= 0) && ((cX + xDir) < this->level->GetWidth()))?xDir:-xDir);
 
When you write code like that, I'm not surprised you don't understand it...

If you just want a random amount of tiles to be filled, this can be done much simpler. What random pattern do you want to use exactly? Let's rewrite it from scratch, that's faster.

Also, there are a lot of other questionable things in your code that are certain to create problems in the long term. I really suggest to fix those things, as they will turn maintenance into hell as soon as the project grows. For example:
  • Global variables
  • Manual memory management. In modern C++, you don't need new and delete! RAII is the keyword here.
  • Init/Cleanup functions instead of constructors and destructors
  • Arrays -> use std::array
  • Unnecessary include files (#include <SFML/Graphics.hpp> increases compile time unnecessarily)
  • Undefined behavior (this->tiles[r][c].~Tile(); -- you may not call destructors explicitly), there's probably more UB
  • No const-correctness (getters such as GetWidth() should be const-qualified)
  • Useless virtual destructors although you don't have polymorphism
  • Disregarded rule of three/five
« Last Edit: November 25, 2013, 05:28:02 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Unknown problem with drawing.
« Reply #2 on: November 25, 2013, 05:48:57 pm »
bool turn = (((rand() % 20) + 1) > 9);
xDir = ((((cX + xDir) >= 0) && ((cX + xDir) < this->level->GetWidth()))?xDir:-xDir);
 
When you write code like that, I'm not surprised you don't understand it...

If you just want a random amount of tiles to be filled, this can be done much simpler. What random pattern do you want to use exactly? Let's rewrite it from scratch, that's faster.

Also, there are a lot of other questionable things in your code that are certain to create problems in the long term. I really suggest to fix those things, as they will turn maintenance into hell as soon as the project grows. For example:
  • Global variables
  • Manual memory management. In modern C++, you don't need new and delete! RAII is the keyword here.
  • Init/Cleanup functions instead of constructors and destructors
  • Arrays -> use std::array
  • Unnecessary include files (#include <SFML/Graphics.hpp> increases compile time unnecessarily)
  • Undefined behavior (this->tiles[r][c].~Tile(); -- you may not call destructors explicitly), there's probably more UB
  • No const-correctness (getters such as GetWidth() should be const-qualified)
  • Useless virtual destructors although you don't have polymorphism
  • Disregarded rule of three/five

First of all, I understand everything in that snippet you posted. Second, it has been a while since I've used C++. I've been focusing on Java for a couple years, so I'm get re acclimated to pointers. Third,  what global variables?

As for the "unnecessary" include files... what's unnecessary about them? I can't very well use an SFML class without including the appropriate header... and yes, the Init() method, rather than a constructor was necessary... how else do you expect me to return a boolean value to tell the Execute() method whether or not the window was properly initialized?

And finally, as for the random level generation, I don't have anything specific in mind. The only algorithm I've looked at so far is BSP generation, but I don't really understand that yet. One thing at a time.
« Last Edit: November 25, 2013, 05:55:53 pm by packetpirate »

Sqasher

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Unknown problem with drawing.
« Reply #3 on: November 25, 2013, 08:03:17 pm »
Third,  what global variables?

Line 7 in SFMLApp.cpp:
TextureManager* SFMLApp::textureManager = new TextureManager();

As for the "unnecessary" include files... what's unnecessary about them? I can't very well use an SFML class without including the appropriate header...

Just include what you need. If you need the RenderWindow, you include <SFML/Graphics/RenderWindow.hpp>. If you need a Sprite, you include <SFML/Graphics/Sprite.hpp> and so on.

It makes the include part look longer and it takes time getting used to, but it speeds up the building process.

and yes, the Init() method, rather than a constructor was necessary... how else do you expect me to return a boolean value to tell the Execute() method whether or not the window was properly initialized?

Exceptions

But back to the topic:
Try to print out the scale, position and size of the tile your mouse is hovering over or even put the whole tilemap into a text file. Then investigate which variable is wrong. I could even imagine that there are tiles with no texture over the actual tiles.

P.S.: Nexus is right, your map generation algorithm is short, but complex and error-prone. Look here or here for some ideas.

packetpirate

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Unknown problem with drawing.
« Reply #4 on: November 26, 2013, 12:38:56 am »
Third,  what global variables?

Line 7 in SFMLApp.cpp:
TextureManager* SFMLApp::textureManager = new TextureManager();

As for the "unnecessary" include files... what's unnecessary about them? I can't very well use an SFML class without including the appropriate header...

Just include what you need. If you need the RenderWindow, you include <SFML/Graphics/RenderWindow.hpp>. If you need a Sprite, you include <SFML/Graphics/Sprite.hpp> and so on.

It makes the include part look longer and it takes time getting used to, but it speeds up the building process.

and yes, the Init() method, rather than a constructor was necessary... how else do you expect me to return a boolean value to tell the Execute() method whether or not the window was properly initialized?

Exceptions

But back to the topic:
Try to print out the scale, position and size of the tile your mouse is hovering over or even put the whole tilemap into a text file. Then investigate which variable is wrong. I could even imagine that there are tiles with no texture over the actual tiles.

P.S.: Nexus is right, your map generation algorithm is short, but complex and error-prone. Look here or here for some ideas.

That's not a global variable... that's a static member of the SFMLApp class.
As for the includes, I'll do that. I didn't realize you could include sub-classes from those packages.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: Unknown problem with drawing.
« Reply #5 on: November 26, 2013, 01:00:03 am »
That's not a global variable... that's a static member of the SFMLApp class.
Which in turn IS a global variable, since any object that knows the class can do SFMLApp::textureManager. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/