Needing some quick tips on how to organize my code

Started by
19 comments, last by dmatter 10 years, 1 month ago

Depending on the project (ie single file or multiple) I use Geany and invert colors so the background is black and the Sons of Oblivion theme in C::B if I'm doing a large project. It isn't so much that I have issues with white backgrounds (and in fact I get nostalgic and change to them once in a while), but rather at night the dark IDE doesn't put off so much light so I don't wake my son while I'm programming.

Advertisement

@dejaime, from reading that article, which I noticed is quite class heavy (which I guess was to be expected), I think I have to admit that separating code and creating classes seem to be two things that don't really go too well without each other. But classes are 6 chapters away in the book.... I guess I'll make a detour and see what I can manage to do.

I kind of noticed CB had themes, but I didn't feel like losing time with it. I may still try some sometime. One thing I noticed about CB is that it allows you to create a list of "user keywords", which probably helps if I want to make it look more similar to ST. But this is something I don't want to get distracted with right now. It's been two days since I last messed up with my code, and it was always distractions that made me end up stopping in the past...

@tanzanite7, sublime text isn't a "proper IDE", it's just a proper generalized text editor with lots of potential to be a decent coding environment. Much like TextMate (I think) and Vim and another one I can't remember. But of course it never reaches the same level of functionalities of an IDE that's made specifically for a language. I will probably want to use the debugger at some point.

I created a pointer of type Toilet so I don't have to go to the bathroom as often.

I started placing stuff into a new file just to see if I could make sense of it. This is what I could gather so far, but I have conflicting ideas here:

I don't know if I should ask the GraphicsM class to draw the map on the buffer, or if that class should allow other classes to draw on it. Or maybe I'm missing something else that might solve my dilema. Or maybe I'm simply doing it all wrong. smile.png


class GraphicsManager
{
	private:
		char tempBuffer[18][35]; 

	public:
		void drawOnBuffer();   // draw something on the buffer?
		void blit();
		void clearBuffer();
		void paintBackground(int symbol);    // paints background with the specified ascii symbol
};

class Map
{
	private:
		int map[18][35];  // the object is given a map from an output source (file), or from user interface (map editing)
		int tileset[2][7];  // class stores active tileset here

	public:
		drawMap();  // draw the map to the buffer?   // or maybe ask the graphics manager to do it instead?
		drawTileset(); // draw the tileset to the buffer?
};

I still haven't read about constructors and such, so don't mind the lack of anything that may be lacking. This is not even the real thing, it's just me trying to understand how to put it together from the code I already have and from what I already learned (which isn't much).

I created a pointer of type Toilet so I don't have to go to the bathroom as often.

What i would do is create the Map class and let it handle the drawing, then i might add it to the GraphicManager later on, and access it from there.

The truth is, there is no perfect answer to this, but the map class should be responsible to draw the map (and do other map related stuffs) and nothing more.

Blit? what api are you using to draw your stuff? I generally just let a function called RenderScene() to do all the rendering to be honest, which call other classes or functions to draw the different parts of the scene.

Here's a small sample of my main drawing routine of an old game of mine


			// Disable lightning + depth test
			glDisable(GL_LIGHTING);
			glDisable(GL_DEPTH_TEST);

			// Draw the sky
			RenderSkyDome();
			RenderSkyPlane();

			// Enable lightning + depth test
			glEnable(GL_LIGHTING);
			glEnable(GL_DEPTH_TEST); 

			// Draw solid objects
			RenderTerrain(UseLodModels());
			RenderRocks();
			RenderColumn();
			// Render chess board
			RenderChessBoard();
			// Render chess pieces
			RenderReflectedPcx(UseLodModels());
			RenderChessPieces(UseLodModels());
			RenderChessPiecesNextMoves(UseLodModels());
			// Draw transparent objects
			RenderWater(UseLodModels());
		
			// Check the sun visibility status
			pCam->SunVisStatus = DoLensFlareTests(pCam);

			// Generate the shadows effects
			if(Menus.Options.ShowShadows){
				if(Menus.Options.ShadowMode == SHADOW_SIMPLE){
					CastPlanarShadow();
				} else {
					Cast3DShadows(pCam);
				}
			}

This is just to give you an idea. As you can see, i havent splitted objects into class, i just wrote a function to handle each of them, but it's an old game, today i might do this differently, but this was the simplest solution i though of at the time. I do however usually use a menu class to draw menu related stuff (not shown here).

Maybe you should start writting it in a more functionnal way, then refactor it later into classes, since you look a bit lost on what you are trying to achieve.

OOP is great, but it's a bit hard to get everything right the first time to be honest.

No APIs, just pure c++ and the console. I'm not sure if it matters much but since I'm making it purely on the windows console, the "rendering" may be a little different. Still, I'm doing something comparable to double buffering, where I'm drawing everything to an array, clear the screen, and then draw the whole array on the screen. That's why I named that function blit(), it was just the first thing that came to mind when I needed a name for it. Same with one I have called doThingsWithInput(). smile.png

Here's the source code, by the way. If it matters.

The way I'm "rendering" it has it's caveats, is kind of slow and forced me to use system calls (for CLS - and this is because I didn't want to have the whole history of the console above, and also because the scrolling seemed worse to watch) for lack of better options. I made a post on TIG about it but no one seemed to have any better solutions that didn't involve external libraries. Still, I'm not really worried about that, I'm more worried about progressing. I'll do something better with SDL one of these days. I'm also enjoying the challenge of getting around the limitations of the console.

So, I don't know, since everything that needs to be drawn is drawn on that array before it gets drawn on the screen, either everything draws in it, or everything tells the class what to draw in it... I suppose those are the options, but I'm not sure which to choose. But if I choose the latter, I'm not sure how to make that class grasp every other class's needs.

So the first option, which is basically what you're saying, seems easier.

I created a pointer of type Toilet so I don't have to go to the bathroom as often.

You have the right idea ... isolating the thing you are working on rather than fighting several battles at once.

But I guess your project might be too ambitious.

Refactoring existing code is hard as hell. I think you would need a mentor who can explain what you did right and what problems you might run into with a chosen approach.

I would isolate practicing game logic algorithms (and data structures for those) on the one hand and managing complexity on the other.

To get better at adding complexity I would follow the suggested path here: going through games like Tetris, Snake etc.

You don't need to abandon your project completely, but you need to think about refactoring the right way and that takes time.

You can see how far you get with a common sense approach - making incremental changes that you feel confident about.

Read some articles about principles like DRY (Don't Repeat Yourself) and SoC (Separation of Concerns) ...

but be aware that there can be no simple answer here that explains it all.

You can read about UML class diagrams. There might be articles that help with thinking about structuring software the right way.

Given enough eyeballs, all mysteries are shallow.

MeAndVR

I read (vaguely) something about complexity somewhere but I can't recall where... Not sure if it was in the book I'm reading. Which is C++ Primer, by the way.

My only fear at this point - 5 chapters away from classes and not yet much more versed in anything that I wasn't before - would actually be to end up repeating myself, even if I was trying not to, since if I delve into another project the only things I'll do better right now are maybe just to make use of a few more I/O functions and a few tricks I learned about strings.

Or maybe, since the map editor is pretty much finished (except for one slightly important functionality that I couldn't implement due to the messy code (and loading maps)), I might get back to the game itself and start applying whatever else I learn in the next days.

But maybe I'm getting ahead of myself in my thinking. I'll do some reading as you suggested. Thanks.

I created a pointer of type Toilet so I don't have to go to the bathroom as often.

One question, from what I understand from what I've been reading, vectors are great to be used for, say, a player or a room's inventory. Would they be just as good for maps? Considering that the maps as I'm using them, are just an array of ints, I suppose at first they might be, but then the maps are sort of constant (the number of elements never changes in a map, an index's value can change (i.e, closed door (visible)/open door (not visible), but that's about it).

If so then I wonder if I have any use for arrays at all for what I'm doing.

I created a pointer of type Toilet so I don't have to go to the bathroom as often.

I think (and I could be wrong) the general rule is that anything you use an array for, you can use a vector for. Obviously, the first major trade off is you can now make maps any size (so you can make maps that get larger as the player goes on) and resize it per level. This would be a plus in puzzle games as you could start small and get bigger as the player plays and learns more, for example.

I've planned the maps to be of a fixed size, where you can "travel" from one map to the other in an open-world-ish kind of way. But who knows I may change my mind given the opportunity...

I created a pointer of type Toilet so I don't have to go to the bathroom as often.

This topic is closed to new replies.

Advertisement