Sign in to follow this  
stitchs_login

Abstracting Draw Code: Am I on the right path?

Recommended Posts

stitchs_login    1361
Hello all,

I am going back to basics, and attempting to master everything I was taught at University, Analysis, Design, Software Processes, Testing, Game Development; by making a Tic-Tac-Toe game!!!1!! I am following a youtube challenge.

What I am attempting to do is separating the Logic from the Draw code. Currently I have my 'logical' classes of Player and Grid, and a class that encompasses the two called game engine. Grid is slightly more developed and better demonstrates what I am asking. I have created a Grid class as below;
[source lang="cpp"]#include <vector>

using std::string; using std::vector;

class Grid
{
private:
int a_GridSquareSize; // Pixel size of each square in the grid.
vector<string> a_Grid; // Container of characters representing a Grid

public:
Grid(void);
~Grid(void);

char f_GetGridSquare(int, int); // Get a grid square at the location passed in, using the GridSquare X and Y coordinates, not pixel coordinates.
int f_GetHeight(); // Get the height of the grid.
int f_GetWidth(); // Get the width of the grid.
int f_GetGridSquareSize(); // Get the pixel size of the grid square.
void f_SetGridSquare(int, int, char); // Sets the selected grid square by passing in X and Y coordinates, and the desired symbol used to change the state of said Square.
};

#endif //GRID_H[/source]
This is the header file, and as you can see I have created a Vector of strings that represent each square on the board. I also have other methods that return a Grid Square, and Width/Height of the Grid. I call these methods in the Engines' drawGrid() and use the data returned to show the Grid on screen:

[source lang="cpp"]void GameEngine::f_DrawGrid()
{
// Use two for-loops to go through each element in
// in the Vector and draw a line at each blocks left
// edge, in pixel coordinates.
for(unsigned int j = 0; j < a_Grid->f_GetHeight(); j++){
for(unsigned int i = 0; i < a_Grid->f_GetWidth(); i++){
// One Line drawing function to represent Vertical lines, determined by X coordinate spacing.
// Parameters: Draw to, X1 calculated at top of screen evenly spaced by SquareSize, Y1 as zero,
// X2 the same as X1, and Y2 is screen height, WHITE. //600
line(screen, i * a_Grid->f_GetGridSquareSize(), 0, i * a_Grid->f_GetGridSquareSize(), 768, makecol(255,255,255));
// One Line drawing function to represent Horizontal lines, determined by Y coordinate spacing.
line(screen, 0, j * a_Grid->f_GetGridSquareSize(), 768, j * a_Grid->f_GetGridSquareSize(), makecol(255,255,255)); //both need to be 'j'
// Check each grid square to determine what should be drawn there.
if(a_Grid->f_GetGridSquare(i, j) == 'O'){
// Using circles to test if drawing is correct
circlefill(screen,
/*X*/ ((i + 1) * a_Grid->f_GetGridSquareSize()) - (a_Grid->f_GetGridSquareSize()/2), // Plotting the X and Y for the circle require that they be calculated as
/*Y*/ ((j + 1) * a_Grid->f_GetGridSquareSize()) - (a_Grid->f_GetGridSquareSize()/2), // the circle centre. Also, cannot (/2) as this will draw the circles closer to each other.
a_Grid->f_GetGridSquareSize() / 2, makecol(255,0,0));
}
/*if(a_Grid->f_GetGridSquare(i, j) == 'O'){
circlefill(screen,
}*/
}
}
}[/source]
This outputs a 9x9 grid of composed of white lines, and draws circles if any of the GridSquares are a char 'O'. My question is, am I along the right sort of lines?

Thanks to all who read this,

Stitchs.

P.S. I am using my old MVC notes from Software Dev in Java and think I am following them in the right manner.

P.P.S. I understand that this may not be the most ideal solution, having the Engine handle everything will make it big, but I am developing this game in Iterative-Increments and will add more classes, should ownership issues arise.

Share this post


Link to post
Share on other sites
Acotoz    73
I haven't tested the code, but it seems right.

I'm a fan of primitive data types so I would've used char** for the grid. But that's just me.

Good luck Edited by Acotoz

Share this post


Link to post
Share on other sites
stitchs_login    1361
Thanks for your reply.

I have already implemented it but I'm not asking if it would/should/could run. I just want to know if this is along the right lines of separating the Model from the View, by making the classes not be in charge of their own drawing, but supply the methods that allow other classes to use this data and draw with it.

Thanks.

Share this post


Link to post
Share on other sites
ZachBethel    921
I guess it doesn't really matter how you implement the visual/logic aspects of your game, it's just a good idea to keep them separate. Since your example is a simple tic-tac-toe game, having a render function in the game engine that uses the data from your grid seems to me like a good solution. What you don't want is a render function on your grid class. That adds bloat to your class and defeats the purpose of an object oriented design.

In terms of larger scale projects, the big thing right now is entity/component systems. Basically, your entity is just a placeholder or id. Your components are the data, and you have separate "system" classes that perform logic on the component data. That logic can be anything: translating input into character movement, physics, rendering, etc. The components can communicate between each other, either by shared variables within the entity, or by just keeping references to each other (i.e. a render component needs a transform to use. The transform could be another component).

Take a look at Artemis framework for a good example of this: [url="http://gamadu.com/artemis/"]http://gamadu.com/artemis/[/url]

For something like tic-tac-toe, don't go overboard trying to engineer a good design. No solution is perfect. For what it's worth, I think you're on the right track for what you're trying to do. Edited by ZBethel

Share this post


Link to post
Share on other sites
stitchs_login    1361
Thanks for you reply ZBethel.

I had a feeling that I was, it's just nice to be assured that I am. I understand that I don't need to over-engineer a super-complex solution for the size of the game, I feel that on my next project (Pong or Tetris), then I can re-use what I've learned here. I would like to be able to refine this solution, but also adapt it into a bigger scale project, on each subsequent project. So much so that when I re-delve into 3D, which won't be for a looooong while, I can literally lift pieces of what I've made in my bigger 2D projects, add in a Z-buffer for kicks, and start better developing heavily OO, small 3D software pieces for my portfolio.

Obviously I will use the link you have provided, and research into other methods of achieving this, per project in aiding my refinement.

Once again, thank you for your reply, and if you have any other information you feel might be of use. Chuck it my way, either here or via PM.

Regards,

Stitchs.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this