Jump to content
  • Advertisement
Sign in to follow this  
xM1k3x

Multiple instances of the same sprite

This topic is 3686 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all I am almost done with my one level video game thanks to all the help I have received from you all! I have just one last issue that I dont know how to solve and it is the issue of firing from the players ship. I have gotten my ship to fire one single bullet correctly but I am not sure how I would make it so that it can shoot infinte amount of bullets. I have a tried an array type of thing but it didnt work so I will show you guys my class and how it works right now and perhaps you all can give me some suggestions as to how I should proceed. PlayerShip.h Class
#include <stdlib.h>
#include "dxgraphics.h"
#include "dxinput.h"
#include "game.h"
#include "Fire.h"

class PlayerShip
{
public:
	int x , y , gunx , guny;        // Variables to handle Coordinates
	int movex , movey;
	int width , height , gunwidth , gunheight;
	void CallMovement();  // Function Prototypes
	void CallFire();
};
#endif

PlayerShip.cpp Class
// PlayerShip.h Implementation File

#include "PlayerShip.h"


void PlayerShip::CallMovement()
{

  if(Key_Down(DIK_LEFT))
  {
	  if(PlayerShip::x != 0)
	{
		PlayerShip::x -= PlayerShip::movex;
		PlayerShip::gunx -= PlayerShip::movex;
	}
  }
  if(Key_Down(DIK_RIGHT))
  {
	  if(PlayerShip::x < (SCREEN_WIDTH - PlayerShip::width))
	  {
		PlayerShip::x += PlayerShip::movex;
		PlayerShip::gunx += PlayerShip::movex;
	}
  }
  if(Key_Down(DIK_UP))
  {
	  if(PlayerShip::y != 0)
	{
		PlayerShip::y -= PlayerShip::movey;
		PlayerShip::guny -= PlayerShip::movey;
	}
  }
  if(Key_Down(DIK_DOWN))
  {
	  if(PlayerShip::y < (SCREEN_HEIGHT - PlayerShip::height))
	{
		PlayerShip::y += PlayerShip::movey;
		PlayerShip::guny += PlayerShip::movey;
	}
  }

}
void PlayerShip::CallFire()
{
	PlayerShip::guny -= PlayerShip::movey;
    if(Key_Down(DIK_SPACE))
	{
		PlayerShip::guny -= PlayerShip::movey;
		if(PlayerShip::guny > 0)
		{
			PlayerShip::guny -= PlayerShip::movey;
		}

	}
}

And here is how everything is called and setup in my main file:
Player.x = 270;
	Player.y = 300;
	Player.gunx = 280;
	Player.guny = 300;
	Player.width = 96;
	Player.height = 96;
	Player.gunwidth = 24;
	Player.gunheight = 32;
	Player.movex = 7;
	Player.movey = 7;

//move the sprite
 Player.CallMovement();
            
	if(Key_Down(DIK_SPACE))
	{
		isFire = true;
	}
	 if(FIRE == true)
	{

        	Player.CallFire();
	}

D3DXVECTOR3 position2((float)Player.gunx,Player.guny,0);

if(isFire == true)
{
	sprite_handler->Draw(
		gun_fire,
		NULL,
		NULL,
		&position2,
		D3DCOLOR_XRGB(255,255,255));

		FIRE = true;
}
		  

So thats basically how the firing is handled. Any ideas as to how to make it so I can fire more than one shot? Thanks

Share this post


Link to post
Share on other sites
Advertisement
I want to see your code for when you tried to use an array, which is what I'm going to tell you I did. However, an std::vector would be better; vector is a class that acts as an array. Vectors can resize themselves if you try to insert too many elements and they'll also clean themselves up.

But, even better, in my opinion, is an std::list. It's a little slower, but I NEVER found this to be a problem. The advantage is that they can take out elements for you without forcing you to worry about reordering. With a vector, you'd have to do a little extra work, and it's not a lot, but with a list, you don't need to worry about it.

Here's example code:

#include <functional>
using std::mem_fun;

#include <algorithm>
using std::for_each;

// My class and how I made a list of it.
class Character;

typedef list< Character* > CharList;
CharList characterList;

/* Character is meant to be a base class. For extended functionality, see CharacterEx. */
class Character
{
public:
bool isDead;

Character()
{
// It actually adds itself to the list!
characterList.push_back( this );
}

// A derived class will define this.
virtual void move() = 0;
};

// The way I create a Character is simply by entering:
new Player();
// Even though Player is a derived class from Character,
// the Character constructor is called, so this is safe.

/* This function helps the characterList know if it's time to kill a character.
A function like this makes popping elements from the list MUCH easier.
*/

bool timeToKill( Character* character, bool KILLL=false )
{
// If the Character's dead, or we just want it dead, kill it.
if( character->isDead || KILLL )
{
// Dealocate the Character as the list won't do that for us.
// This also calls the destructor, which the list only does to non-pointers.
delete character;
return true;
}

return false;
}

/* This will help clean out the Character list at the end. */
bool killAll( Character* character )
{
// Will always return true;
return timeToKill( character, true );
}

int main()
{
// Now we have to get each Character to move by calling each Character stored in characterList's move function.

// Using a for loop isn't pretty.
for( CharList::iterator i=characterList.begin();
i != characterList.end();
i++ )
{
(*i)->move();
}

// But, they makers of the list were smart enough to realize that, so they made for_each.
for_each( characterList.begin(), characterList.end(), mem_fun(&Character::move) );
// This works, even though Character.move() is undefined. It calls, for a bullet, bullet.move().
// Must #include <functional> to use mem_fun();
// Also must #include <algorithm> for for_each();

// At the end of every frame, we should check what items need to be taken out.
// Luckily, we don't need to do much:
characterList.remove_if( timeToKill );

// Before the program closes, we need to empty the list.
// It's a good thing I wrote that killAll function.
characterList.remove_if( killAll );

return 0;
}






As you can see, this is a good bit of work, but now that I've done it, I won't have to worry about how to add or delete anything from that list ever again. A just type in "new derived_class( args );" and forget about it. Then, somehow, I decide it should die and all I need to do is set a public boolean to false.

However, I do realize that there might be a lot here you're unfamiliar with and don't want to push you into something you're not ready for. This also might not be the best solution, I'm not a programmer of ten years. It's just a solution I found to be simple and elegant.

Also, you may be able to use this and never know what the programming concept of a list is, but it's always a good idea to find out. You should always know a little of the underlying logic of what you're working with so you can better work with them. If you use my suggestion, make sure you know or learn about: polymorphism (which is great and you should learn to take advantage of, anyway), linked-lists (more specifically, DOUBLE-linked lists), and function pointers.

As I mentioned above, I would like to see your attempt at using an array, and you might find it easier to find a solution closer to what you already did than my suggestion.

BTW: D3DXVECTOR3 uses floats for x, y, and z for good reason: they're more accurate. I found that even for my own modest game, it was necessary to use floats for position. Using ints, my sprites could only move in eight directions because they only moved one or two pixels a frame.

Use floats or doubles for position.

There's more I could say about your code, but I've said a mouthful already. Maybe later. Good luck.

[Edited by - Splinter of Chaos on July 19, 2008 3:02:57 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!