C++ struct iteration

Community Forums/General Help/C++ struct iteration

_PJ_(Posted 2010) [#1]
Hi peeps, I've been tryiong to get to grips with C++ but one thing has totally eluded me...

To learn it better, I'm trying to write a simple 'space invader' type game. I have created a struct for the invaders, but I don't know how to access different instances.

For example:

class InvaderClass
{
public:
	struct invader{
		short int x;
		short int y;
		int last_fired;
		short int score;
	};

	struct invader_bullet{
		short int x;
		short int y;
		short int speed;
	};

	const short int initial_invader_speed;

	short int invader_speed_base;
	short int invader_speed;
	short int mothership_speed;

	const short int initial_invader_bullet_speed;

	short int invader_bullet_speed_base;

	void MoveInvaders(){
	// Moves all existing invaders
		invader invaderinstance;
		MoveInvaderInstance(invaderinstance)
	}
};


For the function MoveInvaderInstance(), how do I loop invaderinstance to point to each invader in turn?

I know to use invaderinstance.fieldname to get the fields.

To help explain where I'm stuck, In Blitz, the equivalent (using a custom Type) would be:


	Function MoveInvaders()
	; Moves all existing invaders
		For invaderinstance.invader = Each invader
		 MoveInvaderInstance(invaderinstance.invader)
Next
End Function



CGV(Posted 2010) [#2]
If InvaderClass defines an invader instance then you wouldn't be updating all of the instances of invaders within it.

You seem to be trying to create a one class game and that's what's causing your problem.

You really should have an InvaderClass which defines the invader and a seperate BulletClass which defines the bullet and in your main game class create lists of both and just iterate through them each loop to handle movement and collisions etc.


_PJ_(Posted 2010) [#3]
in your main game class create lists of both and just iterate through them

This is what I am having trouble with.
How do I 'create' these lists?

Thanks for the help, as you can probably tell, there's a lot I'm really not familiar with when it comes to OOP stuff.
I was under the impression that Classes ought to contain all the functions and definitions etc. relevant to each object. I concede the Invader_Bullets should then have a class of their own, but I understood that EVERYTHING to do with the invaders being kept in a single class (Invader Class) would mean that's where I would define them all, not just One Instance???

I hope you can understand what I'm geting at, and that you can reply again, even if to tell me Ive gotten it very wrong indeed :)


Hotshot2005(Posted 2010) [#4]
This is interesting learning for someone who want do C++ class with Struct..

Not sure about C++ making Link lists and removing them....


CGV(Posted 2010) [#5]
Lists are not a part of the C++ core language, they're a part of the STL so google for that and you'll find plenty of tuts.

but I understood that EVERYTHING to do with the invaders being kept in a single class (Invader Class) would mean that's where I would define them all, not just One Instance???

Right, but your InvaderClass defines a single invader so all of the code in your InvaderClass has to apply only to that one instance.

You can then make a whole bunch of invader instances and add them to a list or an array.

Each instance is independent of the others so your MoveInvader() method would only move the one invader that's currently being referenced, not all of the invaders. That's why in your main game loop you have to manually iterate through them all, one after another, and call each of their MoveInvader() methods in turn.

EDIT: Here's a link. STL Guide

EDIT2: You can also get a really good free C++ ebook from here


_PJ_(Posted 2010) [#6]

Right, but your InvaderClass defines a single invader so all of the code in your InvaderClass has to apply only to that one instance.

You can then make a whole bunch of invader instances and add them to a list or an array.

Each instance is independent of the others so your MoveInvader() method would only move the one invader that's currently being referenced, not all of the invaders. That's why in your main game loop you have to manually iterate through them all, one after another, and call each of their MoveInvader() methods in turn.



The same issue of creatring a list and iterating would be done for defining the invaders. The 'invaderinstance' is simply a temporary 'local' placeholder to representwhatever "current" instance from the list.
It's how to define new instances and iterate through them I am unable to find.
Yopu refer to arrays, that seems to defeat the point of using 'struct' in the first place?
Also, for things like bullets etc. I would need to track HOW MANY bullets there are and ensure the arrays are of relevant size. Agaoin, this seems to defeat the point of structs which I had hoped would wpork like B3~
D Custom Types and allow for easy iteration and creation of instances without ever needing to know how many instances there are.

Thanks for the links, It's a little late for me know, but I'll have a good look over the stuff tomorrow and see if I can figure it out. Thanks for the help :D


marksibly(Posted 2010) [#7]
Hi,

Untested and it's been a while since I did this but something like this should work...

#include <list>
using namespace std;

Class Invader{
public:
   Invader(){
   }

   void Update(){
      //blah...
   }
};

list<Invader*> invaders;

void CreateInvaders( int count ){
   for( int i=0;i<count;++i ){
      invaders.push_back( new Invader );
   }
}

void DestroyAllInvaders(){
   while( !invaders.empty() ){
      delete invaders.back();
      invaders.pop_back();
   }
}

void UpdateInvaders(){
   for( list<Invader>::iterator it=invaders.begin();it!=invaders.end(); ){
      Invader *invader=*it;

      invader->Update();

      if( invader->WantsToBeRemoved() ){
         it=invaders.erase( it );
      }else{
         ++it;
      }
   }
}


Note: This also shows you how to safely erase something from a list while iterating through it, which is why the '++it' is in a funny place, not in the for loop.

I'd also recommend using C++ namespaces if you want to enclose a bunch of symbols in a single scope, not a class eg:

namespace SpaceInvaders{

   class Invader{
   };

   class Player{
   };

   class Missile{
   };

   class Bullet{
   };

   void CreateInvaders( int count ){
   }

   void UpdateInvaders(){
   }
   ...etc...
}


namespaces are 'open' so you can add different symbols to them in different files which can be useful on big jobs!


_PJ_(Posted 2010) [#8]
Thanks, Mark! I've learned a little on the use of namespaces, I see pointers being used in there too. It looks a lot like it has what I'm looking for, so I'll see how it works pout. Thanks again.


CGV(Posted 2010) [#9]
Even after seeing that code you still want to learn C++ :)

That's the reason I and a lot of other people switched to Blitz.


_PJ_(Posted 2010) [#10]
Yes, I'd rather stick with Blitz, I certainly prefer it's ease of accessibility despite obvious inadequacies vs C++ for many situations, but I'm prepared to struggle on for a while yet :)

I'm hoping to get work with a friend of mine too, so C++ is a must unfortunately since it's become so standardised.


Sledge(Posted 2010) [#11]
I picked up class definition and list population in C++ from the iMiniB3D examples -- they're very instructive.


CGV(Posted 2010) [#12]
I learned OOP from Java just a few months ago after struggling for years with it. I would never recommend C++ to any who's just getting started in OOP.

Just something for you to consider.


Sledge(Posted 2010) [#13]
I would never recommend C++ to any who's just getting started in OOP.
I can only agree with this -- I learned OOP with BlitzMax and, given how much rope C++ gives you to hang yourself with, I'm very glad I did so. Starting with a higher level language lets you work out what it is that you actually need to know, so you can be much more focused when it comes to adopting the C++ equivalents.


_PJ_(Posted 2010) [#14]
Some pennies have dropped into place.
I finally understand now how by declaring member vars within a Class actually means those vars apply to instances of the class objects - meaning I don't need to define structs, since the struct fields could just be vars within the class. Iteration then, is, (as I see explained above now a lot more clearly) done when the objects in the class are iterated themselves!

That makes a lot more of the comments above easier to understand too.

-------

Yeah, Coming from a higher level, procedural background straight to C++ is dainting at the least, it's amazing how different it can be, despite so much being essentially familiar, but I've started now, and I really believe I sould keep going, it's harder for me already to absorb new learning, so I am trying to keep at it enough for what I HAVE learned to stick.

One thing I do see a lot, though, is that many books and tutorials etc. all seem to start in different places, making it difficult to see where abouts a real beginner should start at, the nature of C++ with all its header files and what not, plus the 'standard' libraries that might be needed for one thing or another make even the simplest examples rather clutttered and confusing. Still, things seem to be moving forwards again, so thanks once more to all of you :)