• Intersecting Problem
    18 replies, posted
Well folks, I've been working on a semi-isometric RTS games based off of Age of Empires 2 - The Conquerors. I've been working on this for quite some time now (possibly 5 hours) and yet every method hasn't done me any good. Basically, it checks if there are any trees in the tile (that code is sorted out before this snippet) and if there are none, it displays an object (like a house :v:). But no method seems to work at all. [cpp] for(int ii = 0; ii < maxTrees; ii++){ int ii_y; int ii_x; //left for(ii_y = levelTrees[ii].Y; ii_y <= levelTrees[ii].Y + 63; ii_y++) { for(ii_x = levelTrees[ii].X - 63; ii_x <= levelTrees[ii].X - 1; ii_x++) { if(i * 64 == ii_x && j * 64 == ii_y){ // }else level[i][j] = 2; } } //top for(ii_y = levelTrees[ii].Y - 63; ii_y <= levelTrees[ii].Y - 1; ii_y++) { for(ii_x = levelTrees[ii].X; ii_x <= levelTrees[ii].X + 63; ii_x++) { if(i * 64 == ii_x && j * 64 == ii_y){ // }else level[i][j] = 2; } } //top-left for(ii_y = levelTrees[ii].Y - 64; ii_y <= levelTrees[ii].Y - 1; ii_y++) { for(ii_x = levelTrees[ii].X - 64; ii_x <= levelTrees[ii].X - 1; ii_x++) { if(i * 64 == ii_x && j * 64 == ii_y){ // }else level[i][j] = 2; } } } [/cpp] Any help will be appreciated!
You're going to have to give us some context here. What exactly are "i" and "j"? Indexes for tiles in the map? What does "level[i][j] = 2;" mean? Is "2" the type of tile or something?
Oh, right, damn it. I used i and j as the variable names for the for loop. They are pretty much the coordinates for each tile, were 0, 0 is the top left. So when they're displayed it's simply: [cpp] for(int i = 0; i < 10; i++){ for(int j = 0; j < 10; j++){ drawSprite(image, i * 64, j * 64); } } [/cpp] Where the 64 for both is the dimensions of the tile. Sorry about that :v: [editline]10:03PM[/editline] [QUOTE=ROBO_DONUT;24630136]What does "level[i][j] = 2;" mean? Is "2" the type of tile or something?[/QUOTE] Yes. I need to make sure I included every vital piece of information before posting next time.
Couldn't you make image[][] an array of "tile" structs/classes and store a value "has_trees" in it instead of putting the trees in their own array?
Hmm, that is actually a valid idea. Thanks, I didn't think I could get a good response so quickly.
Or maybe each tile could have a solid variable. That way you can add walls and such.
Oh wow, I'm feeling dumb now as I code. [cpp] struct Trees { int X, Y, ID; }; struct Tiles { int X, Y, ID, hasTrees; }; ... for(int ii = 0; ii < maxTiles; ii++){ for(int jj = 0; jj < maxTiles; jj++){ if((levelTrees[i].X + 25 + mapX > levelTiles[ii][jj].X + 25 + mapX && levelTrees[i].X + 25 + mapX < levelTiles[ii][jj].X + 25 + 64 + mapX) && (levelTrees[i].Y + 25 + mapY > levelTiles[ii][jj].Y + 25 + mapY && levelTrees[i].Y + 25 + mapY < levelTiles[ii][jj].Y + 25 + 64 + mapY)) levelTiles[ii][jj].hasTrees = 1; } } [/cpp] I do hope the for loops are a bit straightforward. I can explain anything if needed too as well. But all it is doing (or trying) is checking every tree to see if it's in any of the tiles. But I'm a bit confused of why it's not working..
Still too complicated. [cpp] typedef struct tree { int x, y, id; } tree_t; typedef struct tile { int x, y, id; tree_t *tree; } tile_t; [/cpp] This is in C, adjust the syntax for C++. You store a reference to the tree in the tile, if there is one. If there is no tree, you store null. Thus, to add a tree to a tile: [cpp] /* create a new tree struct (I forget how to do this in C++ because C++ has useless bizarro-world structs) */ tile.tree = &tree; /* store tree's reference in tile */ [/cpp] And to test for trees: [cpp] if (tile.tree != NULL) { /* There's a tree here */ tree_t *tree = tile.tree; /* do stuff */ } else { /* no trees! */ } [/cpp]
Yeah, I'm known to over-complicate things, it's very common :v: And thank you, I hope I can start doing this right soon!
[QUOTE=ROBO_DONUT;24633769][cpp] /* create a new tree struct (I forget how to do this in C++ because C++ has useless bizarro-world structs) */ tile.tree = &tree; /* store tree's reference in tile */ [/cpp][/QUOTE] [cpp]tree_t tree;[/cpp]
[QUOTE=esalaka;24637938][cpp]tree_t tree;[/cpp][/QUOTE] In C that allocates a tree on the stack, which is not what you want to do in the middle of a for loop to create trees. When the routine exits, tree disappears and you've got a reference to nothing. You'd do "tree_t *tree = (tree_t)malloc(sizeof(tree_t));". But in C++, structs aren't just groups of variables, they're like objects where everything is public or something, so I'm not sure that it's safe to do that.
[QUOTE=ROBO_DONUT;24640957]In C that allocates a tree on the stack, which is not what you want to do in the middle of a for loop to create trees. When the routine exits, tree disappears and you've got a reference to nothing. You'd do "tree_t *tree = (tree_t)malloc(sizeof(tree_t));". But in C++, structs aren't just groups of variables, they're like objects where everything is public or something, so I'm not sure that it's safe to do that.[/QUOTE] Oh yeah, it allocates the tree on the stack... Well, you could do tree_t * tree = new tree; or static tree_t tree; (Static inside a function sets static lifetime, eg. till main returns) [editline]06:49PM[/editline] Also, I'm fairly sure you'd do tree_t * tree = ( tree_t * ) malloc( sizeof( tree_t ) ); — even though the cast to tree_t* is, IIRC, unnecessary because of implicit casting rules.
[QUOTE=esalaka;24641051]Also, I'm fairly sure you'd do tree_t * tree = ( tree_t * ) malloc( sizeof( tree_t ) ); — even though the cast to tree_t* is, IIRC, unnecessary because of implicit casting rules.[/QUOTE] Totally meant to put that asterisk in there. But yeah, you don't need it because of the implicit cast. I explicit cast with malloc out of habit, because void* will implicitly cast to anything without a warning.
[QUOTE=ROBO_DONUT;24640957]But in C++, structs aren't just groups of variables, they're like objects where everything is public or something, so I'm not sure that it's safe to do that.[/QUOTE] An "object" is really just a struct at runtime; it just happens to have some related functions bundled into its namespace at compile time. Yes, C++ structs can do all the same things that classes can, but a "plain" C-style struct, that doesn't use any of those extensions, works the same way in C++ that it does in C. The "C++ way" to allocate an instance of the struct would be to write "new tree_t" instead of calling malloc(), but since there's no constructor to be called and you're not using RTTI or virtual functions with this struct -- that is, it's a plain C-style struct -- malloc() is suitable. [editline]01:15PM[/editline] [QUOTE=ROBO_DONUT;24641566]But yeah, you don't need it because of the implicit cast. I explicit cast with malloc out of habit, because void* will implicitly cast to anything without a warning.[/QUOTE] True in C but not C++. In C++ there's no implicit cast from void*; that's one reason why it's good to use operator new instead of malloc() even for C-style structs, because it provides the correct return type so no cast is needed.
[QUOTE=Wyzard;24643038]True in C but not C++. In C++ there's no implicit cast from void*; that's one reason why it's good to use operator new instead of malloc() even for C-style structs, because it provides the correct return type so no cast is needed.[/QUOTE] Although sometimes you might just want to do ParentClass * ptr = reinterpret_cast<ParentClass *>( new ChildClass() ); for example when ParentClass is used as an interface.
I fixed all of his problems with this :D [editline]03:31PM[/editline] Esa gonna hate.
[QUOTE=esalaka;24646304]Although sometimes you might just want to do ParentClass * ptr = reinterpret_cast<ParentClass *>( new ChildClass() ); for example when ParentClass is used as an interface.[/QUOTE] Conversion from a derived-class pointer to a base-class pointer is implicit; there's no need for reinterpret_cast there. reinterpret_cast is a completely non-typesafe, shoot-yourself-in-the-foot type of cast. Only use it if you actually need to, and if you think you need to, you can probably avoid it by improving your design.
[QUOTE=Wyzard;24653136]Conversion from a derived-class pointer to a base-class pointer is implicit; there's no need for reinterpret_cast there. reinterpret_cast is a completely non-typesafe, shoot-yourself-in-the-foot type of cast. Only use it if you actually need to, and if you think you need to, you can probably avoid it by improving your design.[/QUOTE] It's implicit in C++? I never knew! (Would a static_cast work there, then? I probably was confused with the different casts...)
[QUOTE=esalaka;24659447]It's implicit in C++? I never knew![/QUOTE] Yep. Think of it this way: every instance of ChildClass is an instance of ParentClass — that's what class inheritance means — so it's no problem for a ParentClass* to point to an instance of ChildClass. [QUOTE=esalaka;24659447](Would a static_cast work there, then? I probably was confused with the different casts...)[/QUOTE] It'd work, but I wouldn't recommend using it when all you want is an upcast. Explicit casts are for mixing types that would otherwise be incompatible, and using them gratuitously limits the compiler's ability to catch type-related errors when you make a mistake. Better to use the "smallest" cast that meets your needs, which in this case is the implicit one. (From that standpoint, reinterpret_cast is the "last resort" big gun that you haul out in extreme situations.) [url=http://www.cplusplus.com/doc/tutorial/typecasting/]This guide[/url] may help you to better understand the various types of casts.
Sorry, you need to Log In to post a reply to this thread.