What is the best way to store X and Y coords

Started by
25 comments, last by 3Dgonewild 15 years, 11 months ago
Advertisement
In that case wouldn't it be easier to actually use an array of tile structs? You can always calculate the real coordinates from the array indices:

struct Tile{  bool   Exists;  DWORD  Color;  Tile() :    Exists( false ),    Color( 0xffffffff )  {  }};Tile     m_Tiles[12][8];

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

In this case what you need is not a grid of possible bricks, instead a list of known bricks and where they are in your 12x8 grid.

You need to use either a vector or a list but in this example I'll use a vector (array essentially).

#include <vector> // This is our brick informationstruct Brick{	int x, y; // this is our grid X/Y (i.e. 12x8)	unsigned int color; // add a color to each brick}; // Our array of bricks in our 12x8 gridstd::vector <Brick> g_Bricks; // Load our bricks from a 2D arrayvoid LoadBricks (bool is_brick[12][8]){	// setup our loops thru i and j (x/y)	for (int i = 0; i < 12; i++)		for (int j = 0; j < 8; j++) {			if (is_brick[j]) {				Brick brick;				brick.x = i + 1; // add 1 to make our x index an x position from 1-12 not 0-11				brick.y = j + 1;				// set a color (could be randomised as well)				brick.color = 0xFFFF00; // yellow								// add our new brick to the array of bricks				g_Bricks.push_back (brick);			}		}} // Find out which brick in our array we may be hitting// x/y coordinates are in grid coordinates not pixel coordinatesint DoHitTest (int player_x, int player_y){	for (int i = 0; i < g_Bricks.size (); i++)	{		// if the brick we're testing is the same position as the player		// thats the brick we need to remove		if (g_Bricks.x == player_x && g_Bricks.y == player_y) {			// return the index of brick we found our player was hitting			return i;		}	}	// if we didn't hit any bricks lets return -1	return -1;} // Here we update the bricks by doing a hit test then removing the brickvoid UpdateBricks (int player_x, int player_y){	// find out if we hit a brick	int brick = DoHitTest (player_x, player_y); 	// if we did (not -1) remove it	if (brick != -1) {		// remember, DoHitTest returns the index in our array		// of the brick we hit so we can use this to remove it from the array		g_Bricks.erase (brick);	}}
Well I think I should explain my theory behind the reason I am trying to do it this way.
for(int i=0;i<8; i++) // this makes the rows           {                for(int l =0;l <12;l++ ) //this makes the columns                    {                        pos.y = i * 30;                          pos[l].x = l * 50;                                                               // so the first time through it make y equal 30                       // and make x = 50 which to understand why I just                                   // need the upper left corner of the brick I have                      // the size already constant. So what I was                            // thinking is that I create parallel arrays. So                      // they both contain different values but are                      // always incrementing the same.   // pos[1].y == 30// pos[1].x == 50// pos[2].y == 30// Pos[2].x == 50   ..// pos[2].y == 60// pos[2].x == 50                }           }


So should my thoughts on using this array correct?
You only have a single dimensional array. Single dimensional arrays do not have rows and columns *.

You want a two dimensional array. Or, better still, something looking like what some of the other posters suggested.

* Technically, you can access a single dimensional array as if it had rows and columns, but that is beyond you for the moment
It's hard to understand exactly what you're trying to achieve, but I think this code should be doing what you want it to do:

#define NUM_COLUMNS 12#define NUM_ROWS    8#define NUM_BRICKS (NUM_COLUMNS * NUM_BRICKS)struct coord{  int x;  int y;};coord pos[NUM_BRICKS];void load(){  int i = 0; // i is the index into the array of coords. This is completely independent of the actual coordinates stored within the array.  for(int j = 0; j < NUM_ROWS; ++j) // j is the row in which the brick belongs  {    for(int k = 0; k < NUM_COLUMNS; ++k ) //k is the column in which the brick belongs    {        // set the position of the 'i'th brick to a value calculated from the row (j) and the column (k) values      pos.y = j * 30;          pos.x = k * 50;      ++i; // move onto the next coordinate in the pos array    }  }}


Does that do what you want, and if so, do you understand how it works?

There are other ways of doing this, of course: you don't need the i variable at all, you can calculate it from j and k directly. Alternatively you could declare pos as a 2D array, and use j and k as indexes directly.

I think for something so simple , you should better do it like this:

	class Tile	{		private:		int px,py,ptype;		public:		Tile(const int& tx,const int& ty,const int& ttype){px=tx;py=ty;ptype=ttype;}		int& x()    const {return px;}		int& y()    const {return py;}		int& type() const {return ptype;}	};	//i suggest to create a simple ASCII file with all required information	//and load it .	//this is just an example.	void loadMap(std::vector<Tile>& the_map)		{			the_map.clear();			for (int y=0;y<MAP_HEIGHT;y++)				{					for(int x=0;x<MAP_WIDTH;x++)						{							the_map.push_back(Tile(x*TILE_WIDTH,y*TILE_HEIGHT,RED_BRICK));						}				}		} 	int main()		{			std::vector<Tile> map;			loadMap(map);				for(std::vector<Tile>::iterator t=map.begin(); t!=map.end();t++)				{					//assume that your render function					//takes the following parameters:					//X position of the object					//Y position of the object					//object type					render_function_goes_here(t->x(),t->y(),t->type());				}		{	



Hope it helps..

This topic is closed to new replies.

Advertisement