Sign in to follow this  
xM1k3x

Shooting in game help

Recommended Posts

Hey guys I have now implemented shooting into my top down shooter game and there are a couple of things im not sure how to do or fix. First off I can only shoot once....lol I know its lame but im not sure exactly how to make more than one. Also second thing I need it to fire directly from the ship but right now it will only fire from the center of the screen meaning: if I start the game and move my shop to the far right when I hit fire it the bullet appears in the center instead in front of my ship and fires away. Firing function
#ifndef _FIRE_H
#define _FIRE_H

#include "PlayerShip.h"
#include "game.h"

class Fire
{
public:
	int x , y;        // Variables to handle Coordinates
	int movex , movey;
	int width , height;
	void FireBasicGun();  // Function Prototypes
	void FireSpecial();   //---------------------
};

#endif

// Fire.h Implementation File

#include "Fire.h"

void Fire::FireBasicGun()
{   
	Fire::y -= Fire::movey;

	if(Fire::y > 0)
	{
		Fire::y -= Fire::movey;
	}
	  
}
void Fire::FireSpecial()
{
   // Code for firing special 
   // weapon
}

gun_fire = LoadTexture("firegun1.bmp",D3DCOLOR_XRGB(255,0,255));
	if (gun_fire == NULL)
		return 0;

	Gun.x = Player.x;
	Gun.y = Player.y;
	Gun.width = 24;
	Gun.height = 32;
	Gun.movey = 10;
	Gun.movex = 10;

void Game_Run(HWND hwnd)
{
    //make sure the Direct3D device is valid
    if (d3ddev == NULL)
        return;
		Poll_Mouse();
		Poll_Keyboard();

        //after short delay, ready for next frame?
        //this keeps the game running at a steady frame rate
        if (GetTickCount() - start >= 30)
        {
			
            //reset timing
            start = GetTickCount();           

            //move the sprite
            Player.CallMovement();
            if(Key_Down(DIK_SPACE))
			{
				isFire = true;
			}
			if(FIRE == true)
			{
				Gun.FireBasicGun();
			}
			 //update the scrolling view
		    UpdateScrollPosition();

        //start rendering
        if (d3ddev->BeginScene())
        {
		    //erase the entire background
		    d3ddev->StretchRect(tiles, NULL, backbuffer, NULL, D3DTEXF_NONE);

            //start sprite handler
            sprite_handler->Begin(D3DXSPRITE_ALPHABLEND);

			 //create vector to update sprite position
	        D3DXVECTOR3 position((float)Player.x, (float)Player.y, 0);   

			D3DXVECTOR3 position2((float)Gun.x, (float)Gun.y, 0);
			//draw tiles onto the scroll buffer
		    DrawTiles();
			//draw the scroll window onto the back buffer
			DrawScrollWindow();
            if(isFire == true)
			{
				sprite_handler->Draw(
					gun_fire,
					NULL,
					NULL,
					&position2,
					D3DCOLOR_XRGB(255,255,255));
                FIRE = true;
			}
            //draw the sprite
            sprite_handler->Draw(
                player_ship, 
                NULL,
                NULL,
                &position,
                D3DCOLOR_XRGB(255,255,255));
          
	        sprite_handler->End();
			//stop rendering
			d3ddev->EndScene();
		}
		
		}
	

    //display the back buffer on the screen
    d3ddev->Present(NULL, NULL, NULL, NULL);

    //check for escape key (to exit program)
    if (Key_Down(DIK_ESCAPE))
       DestroyWindow(hwnd);

}

So if someone could help me it would br great and if you can explain the steps for me that would be nice since I am learning and that way I will learn from you instead of just copying your code. Thanks!

Share this post


Link to post
Share on other sites
Well the reason your gun is shooting from the center of the screen is because you have to make sure you update the gun position every time you update the player position. In pseudo code you could have something like this....

MoveShip
update ship x position
update ship y position
update gun x position
update gun y position


In your code I noticed you only set the gun position once in the beginning.

[Edited by - blewisjr on July 4, 2008 12:30:47 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by blewisjr
Well the reason your gun is shooting from the center of the screen is because you have to make sure you update the gun position every time you update the player position. In pseudo code you could have something like this....

MoveShip
update ship x position
update ship y position
update gun x position
update gun y position


In your code I noticed you only set the gun position once in the beginning.



Ok I understand what your saying but where in the could do I need to update the gun position? Because im not sure if I am doing it before the if(isFire == true) or inside the if(isFire == true) etc

Just not sure where to put it, but I understand what your saying and it makes sense.

Share this post


Link to post
Share on other sites
Update the gun position where you are moving your ship sprite. For instance if you press the right arrow key you move the ship right make sure you update the gun position to match the position of the ship.

Pseudo code again


If Left Arrow press
change ship coords to new position
change gun coords to match new ship coords





[Edited by - blewisjr on July 4, 2008 12:17:59 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by blewisjr
Update the gun position where you are moving your ship sprite. For instance if you press the right arrow key you move the ship right make sure you update the gun position to match the position of the ship.

Pseudo code again

*** Source Snippet Removed ***


Dont think I can because they are in seperate files, the movement of both sprites that is.

The ships movement is handled by playership.cpp and the gun fire by fire.cpp.

Of can I still do that?


*EDIT*

Just thought of something couldnt I pass the ships x and y to the function that moves the gun fire as parameters something like this:

void Fire::FireBasicGun(int x, int y)
{
Fire::x = x;
Fire::y = y;

Fire::y -= Fire::movey;

if(Fire::y > 0)
{
Fire::y -= Fire::movey;
}

}


Would that work?

Share this post


Link to post
Share on other sites
There alone is the first flaw. Your design is slightly off. The classes for the ship and the gun can be separated but why. The gun is part of the ship.

If you insist on keeping them separate then you should put in a property structure into each class. Use getters and setters. In the Ship class you would have 2 private variables for position x and position y. You would have the same in the gun class. Then in both classes you would have getters and setters for these values. SetPosX(int x) for instance and int GetPosX. This way in the main game class you can use the setters to update the objects positions and then in the draw you can use the getters to retrieve the positions from the objects.

However, in all honesty since the gun is part of the players ship I would just keep the 2 together in the same class and share the position values where the origin of the gun projectile is the position of the ship and after the projectile leaves the ship it should have its own variable that tracks its travel. Making the ship and the gun move as one unit.

EDIT: sorry did not see your edit. is Fire::x and Fire::y the origin of the projectile if it is yes if not then no.

[Edited by - blewisjr on July 4, 2008 12:41:16 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by blewisjr
There alone is the first flaw. Your design is slightly off. The classes for the ship and the gun can be separated but why. The gun is part of the ship.

If you insist on keeping them separate then you should put in a property structure into each class. Use getters and setters. In the Ship class you would have 2 private variables for position x and position y. You would have the same in the gun class. Then in both classes you would have getters and setters for these values. SetPosX(int x) for instance and int GetPosX. This way in the main game class you can use the setters to update the objects positions and then in the draw you can use the getters to retrieve the positions from the objects.

However, in all honesty since the gun is part of the players ship I would just keep the 2 together in the same class and share the position values where the origin of the gun projectile is the position of the ship and after the projectile leaves the ship it should have its own variable that tracks its travel. Making the ship and the gun move as one unit.

EDIT: sorry did not see your edit. is Fire::x and Fire::y the origin of the projectile if it is yes if not then no.



Let me see if I understand:

First off here is my class

class PlayerShip
{
public:
int x , y; // Variables to handle Coordinates
int movex , movey;
int width , height;
void CallMovement(); // Function Prototypes
};

#endif




and here is the implementation


// PlayerShip.h Implementation File

#include "PlayerShip.h"

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




Ok so your saying that I should keep them together, ok I understand the thinking behind that it makes sense. But how to do that is where I am a little fuzzy should I make a struct within the class that will have variables for the gun? Is that what your saying?

I am sorry that I have to make you explain so much but you really are helping me understand and I appreciate it.

Share this post


Link to post
Share on other sites
A struct would work fine. Then pass the struct into your FireBasicGuns function. And update the struct a long with the ship position in the movement code. That should work if I understand your code properly.

[Edited by - blewisjr on July 4, 2008 12:12:34 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by blewisjr
A struct would work fine. Then pass the struct into your FireBasicGuns function. And update the struct a long with the ship position in the movement code. That should work if I understand your code properly.


Ok well I have done that now but I am getting some weird errors.


Here is the class now with the struct:


class PlayerShip
{
public:
int x , y; // Variables to handle Coordinates
int movex , movey;
int width , height;
void CallMovement(); // Function Prototypes
};

struct Gun
{
public:
int x , y; // Variables to handle Coordinates
int movex , movey;
int width , height;
};

#endif



And the implementation:


// PlayerShip.h Implementation File

#include "PlayerShip.h"

void PlayerShip::CallMovement()
{
Gun::x = PlayerShip::x;
Gun::y = PlayerShip::y;

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





The error states:

Error 32 error C2597: illegal reference to non-static member 'Gun::x'


And there are 6 of them. I dont quite understand why this error is there. Any ideas?

Share this post


Link to post
Share on other sites
You're getting wierd errors because you're doing weird things. Why are you using the syntax Gun::x, PlayerShip::x? You should be using Gun.x, Player.x. Actually, in a member function of Player, whenever you use x it is assumed to be Player.x / Player::x / whatever. You need to have an actual instance of your Gun struct. I would suggest making the Gun a member of PlayerShip, either by value or by a pointer.

If that didn't make sense, you probably need to go back and do some basic research on OOP, and make sure you're clear on the distinction between a class and an object.

Share this post


Link to post
Share on other sites
Quote:
Original post by theOcelot
You're getting wierd errors because you're doing weird things. Why are you using the syntax Gun::x, PlayerShip::x? You should be using Gun.x, Player.x. Actually, in a member function of Player, whenever you use x it is assumed to be Player.x / Player::x / whatever. You need to have an actual instance of your Gun struct. I would suggest making the Gun a member of PlayerShip, either by value or by a pointer.

If that didn't make sense, you probably need to go back and do some basic research on OOP, and make sure you're clear on the distinction between a class and an object.


Lol your right you know its been a while since I last programmed I guess I have forgotten some things.

Ok the last part what do you mean by making Gun a member of Player ship?? How would I do that? I understand you said either by value or by a pointer but what do mean by making Gun a member or PlayerShip?

Thanks for your guys patience with me.

Share this post


Link to post
Share on other sites
Quote:
Original post by theOcelot
You're getting wierd errors because you're doing weird things. Why are you using the syntax Gun::x, PlayerShip::x? You should be using Gun.x, Player.x. Actually, in a member function of Player, whenever you use x it is assumed to be Player.x / Player::x / whatever. You need to have an actual instance of your Gun struct. I would suggest making the Gun a member of PlayerShip, either by value or by a pointer.

If that didn't make sense, you probably need to go back and do some basic research on OOP, and make sure you're clear on the distinction between a class and an object.


Is this what you meant?


// PlayerShip.h Implementation File

#include "PlayerShip.h"

Gun GunFire;

void PlayerShip::CallMovement()
{

GunFire.x = PlayerShip::x;
GunFire.y = PlayerShip::y;

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



Share this post


Link to post
Share on other sites
Actually, I had something a little more like this in mind. I'm just inlining functions for clarity.


class PlayerShip{
public:
Gun* ship_gun;
PlayerShip(){
//stuff...
ship_gun = new Gun(/*whatever args*/);
//more stuff...
}
~PlayerShip(){
//this may be all that's required in the destructor
delete ship_gun;
}
};



I'm not sure exactly what PlayerShip::CallMovement is supposed to do; I think you should change the name, probably to something boring like update(). It seems, though that it is just supposed to move the ship based on key-downs and make sure that the gun is always in the same position relative to it. If that's the case, here's about how I would do it.


void PlayerShip::CallMovement(){
if(keyDown(DIK_LEFT)){
x -= xmove;//notice how it is assumed that these are members of PlayerShip
//also notice that I am not moving the gun yet
}
//repeat the key-down tests as necessary
//now move the gun, all in one shot
ship_gun.x = x + GUN_OFFSET_X;
ship_gun.y = y + GUN_OFFSET_Y;
//For what it's worth, I would make firing a method of gun
if(Key_Down(DIK_SPACE)){
ship_gun->Fire(/*args?*/);//this function puts a bullet sprite in the world
}
}


GUN_OFFSET_X and GUN_OFFSET_Y are just constants that tell how far the position of the gun is from the position of the ship, since their positions are generally their top-left corners, and just assigning their positions to be equal would look funny.

Don't copy my code, because I'm in a hurry and it's almost gauranteed not to compile, but you probably get the idea.

Share this post


Link to post
Share on other sites
Quote:
Original post by blewisjr
There alone is the first flaw. Your design is slightly off. The classes for the ship and the gun can be separated but why. The gun is part of the ship.

Composition. Create a generic gun class and you can give your ship one or more guns fairly easy. You can reuse the gun code for your enemies as well. Just because something is part of something else doesn't mean you shouldn't create separate classes for them.

Quote:
If you insist on keeping them separate then you should put in a property structure into each class. Use getters and setters.

Create a decent interface instead. For example, Move() is better than a SetX() and SetY() pair, as it is more geared towards the actual use of the object.

Quote:
However, in all honesty since the gun is part of the players ship I would just keep the 2 together in the same class and share the position values where the origin of the gun projectile is the position of the ship and after the projectile leaves the ship it should have its own variable that tracks its travel. Making the ship and the gun move as one unit.

Here you're saying something interesting. Make them move as one. Personally, I would make the gun position relative to the player. This means you only need to update the player location. Whenever you fire a bullet, you add the player and gun positions together to get the initial bullet position.


A few more notes: in C++, structs are almost the same as classes, although they're often used to indicate that something is merely a collection of data. I would say that a Gun is more than just data - it also has specific behaviour (hey, it fires stuff, right?), so the current approach here is somewhat off. You're storing gun data in a Gun struct but the gun functionality resides elsewhere. Why this separation?

@theOcelot: why create the Gun on the heap? In this case, the manual memory management is more trouble than it's worth. After all, a Gun isn't a heavy object anyway.

Share this post


Link to post
Share on other sites
Quote:
Original post by Captain P
@theOcelot: why create the Gun on the heap? In this case, the manual memory management is more trouble than it's worth. After all, a Gun isn't a heavy object anyway.


Oh, no good reason. It's just what comes naturally. I actually like pointers. Allocating in the constructor and deleting in the destructor doesn't strike me as horrendously difficult. I suppose though that having it by value would be easier, esp. for a beginner or someone brushing up, and it seems OP is one of the two.

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