Skip to main content
gamedev.net
🔒 Locked

fire weapon....

Started by FreJa Mar 16, 2003 at 4:38 AM 12 replies 650+ views
Original Post
FreJa
FreJa
Hi, I was just experiencing some things in a 2D game to use in another game... In this experience you have ship that should fire whenever you press SPACE... but it doesn''t... look at the code: Player.cpp
  
#include "Player.h"

CPlayer::CPlayer()
{
	health = 100.0f;
	xPos = 0.0f;
	yPos = -6.5;
}

CPlayer::~CPlayer()
{}

void CPlayer::Draw()
{
	glPushMatrix();

		glTranslatef(xPos, yPos, -18.0);
		glBegin(GL_QUADS);
			glVertex2f(-0.2, -0.2);
			glVertex2f(0.2, -0.2);
			glVertex2f(0.2, 0.2);
			glVertex2f(-0.2, 0.2);
		glEnd();

	glPopMatrix();
}

void CPlayer::ChangeDirection(int direction)
{
	if(direction == 1)		//Right

	{
		xPos += 0.01f;
	}
	if(direction == 2)		//Left

	{
		xPos -= 0.01f;
	}
}

void CPlayer::Fire()
{
	CRocket *Rocket = new CRocket;

	Rocket->xPos = xPos;
	Rocket->yPos = yPos;

	Rocket->Draw();	
}
  
Rocket.cpp
  
#include "Rocket.h"

CRocket::CRocket()
{
	xPos = 0.0;
	yPos = -6.5;
}

CRocket::~CRocket()
{}

void CRocket::Draw()
{
	glPushMatrix();
		glColor3f(1.0, 0.0, 0.0);
		glTranslatef(xPos, yPos, -18.0);
		glBegin(GL_QUADS);
			glVertex2f(-0.04, -0.04);
			glVertex2f(0.04, -0.04);
			glVertex2f(0.04, 0.04);
			glVertex2f(-0.04, 0.04);
		glEnd();
		glColor3f(1.0, 1.0, 1.0);
	glPopMatrix();

	yPos += 0.01f;
}
  
MainWnd.cpp
  
#include "MainWnd.h"

CDirectInput	DirectInput;
CPlayer			*Player;
CRocket			*Rocket;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

bool CApp::Initialize()
{
     glClearColor(0.0, 0.0, 0.0, 0.0);

	if(!DirectInput.Initialize(glWindow.window.hWnd, glWindow.application.hInstance, true, IS_USEKEYBOARD | IS_USEMOUSE)) return false;

	Player = new CPlayer;
	Rocket = new CRocket;

	return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CApp::GameCycle()
{
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_SMOOTH);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	Player->Draw();
	
	glFlush();
}	

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CApp::Deinitialize()
{
	DirectInput.Unload();
	
	delete Player;	
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CApp::GetInput()
{
	DirectInput.Update();

	if (!inputInUse)
	{
		// quit

		if (DirectInput.KeyDown(DIK_ESCAPE))
			glWindow.TerminateApplication(&glWindow.window);

		if(DirectInput.KeyDown(DIK_RIGHT))	Player->ChangeDirection(1);

		if(DirectInput.KeyDown(DIK_LEFT))	Player->ChangeDirection(2);

		if(DirectInput.KeyDown(DIK_SPACE))	Player->Fire();

		if (DirectInput.KeyDown(DIK_L))		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		if (DirectInput.KeyDown(DIK_F))		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
		if (DirectInput.KeyDown(DIK_P))		glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
	}
}
  
See the problem? Thanks a lot
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
FreJa
FreJa
But isn''t it my intention to construct and draw the rocket every time I press the space button?
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
FreJa
FreJa
Well... I think it''s kinda working right now, as when I press space the rocket appears, but it isn''t affected by the translation (yPos += 0.01f), so it remains on the same spot..... why is that?
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
stephanh
stephanh
Why should it move? Every time you press your fire button and Fire is invoked you create a new Rocket instance, forgetting about the old one (-> memory leak)

CRocket *Rocket = new CRocket;
Rocket->xPos = xPos;
Rocket->yPos = yPos;
Rocket->Draw();

So Draw for each instance is only called once.

You have to create a list of all active rockets, assign each rocket a lifetime (or whatever) and update them until they "die". And perhaps re-read the chapter about dynamic memory allocation and pointers.
FreJa
FreJa
This is starting to get on my nerves.... I really can''t find a way to make this work!

If I do this:

CRocket *Rocket = new CRocket;
Rocket->Draw();

and in CRocket::Draw() do yPos += 0.01f

shouldn''t it create a new instance of CRocket, and affect it with yPos+=0.01f ??????
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
HellRiZZer
HellRiZZer
Here's what I would do:

    
class CRocket
{

...
....
bool m_bCreated;
CVector m_Speed;

virtual void Draw();
virtual void Update();
};

class CPlayer
{
...
....
CRocket rockets[MAX_ROCKETS];
virtual void Draw();
virtual void Update();
void Fire(CVector speed, CVector start_pos);
};

// ROCKET RELATED

void CRocket::Draw()
{
// Draw rocket code

}

void CRocket::Update()
{
// Update position based on given speed

if(m_Pos.y > 800)
{
m_bCreated = false;
Destroy(); // Basically this has to de-initialize all variables you use for CRocket class

}
else
m_Pos+=m_Speed;
}

// PLAYER RELATED

void CPlayer::Draw()
{
// Do your drawing for player


for (int i=0; i<MAX_ROCKETS; i++)
{
if(rockets[i].m_bCreated)
rockets[i].Draw();
}
}

void CPlayer::Update()
{
// Update player variables based on input, its X, Y and Z poss

// Similar to ChangeDirection


for (int i=0; i<MAX_ROCKETS; i++)
{
if(rockets[i].m_bCreated)
rockets[i].Update();
}
}

void CPlayer::Fire(CVector dir, CVector start_pos)
{
// Find free rocket

for (int i=0; i<MAX_ROCKETS; i++)
{
if(!rockets[i].m_bCreated)
{
rockets[i].m_Pos = start_pos;
rockets[i].m_Speed = dir;
rockets[i].m_bCreated = true;
break;
}
}
}




" Do we need us? "


Ionware Productions - Games and Game Tools Development

[edited by - HellRiZZer on March 16, 2003 4:34:05 PM]

FreJa
FreJa
Just another doubt:
if I do something like this:


  
void CPlayer::Fire()
{
Rocket = new CRocket;

Rocket->xPos = xPos;
Rocket->yPos = yPos++;

Rocket->Draw();

if(Rocket->yPos >= (glWindow.window.init.height-38)-5)
{
DeleteRocket();
}
}

void CPlayer::DeleteRocket()
{
delete Rocket;
}


it won''t work... but shouldn''t it work? because I press space, it is created a new instance of CRocket, and if the position of that rocket is X, it will delete it... and when I press again it will be created another instance of CRocket, and if the position .......... bla bla bla ?
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
Trienco
Trienco
quote:
Original post by FreJa


    
void CPlayer::Fire()
{
Rocket = new CRocket;

Rocket->xPos = xPos;
Rocket->yPos = yPos++;

Rocket->Draw();

if(Rocket->yPos >= (glWindow.window.init.height-38)-5)
{
DeleteRocket();
}
}

void CPlayer::DeleteRocket()
{
delete Rocket;
}


it seems to get worse. you wont get away without a function that will process the rocket in every frame. how is it supposed to move across the screen, if its yPos is only changed once at creation?

also checking if the rocket is outside the screen in the function that creates it is quite pointless, because if it is, then the ship itself was already outside and you have a problem. having a function just to call delete seems pretty unnecessary too.

looking at your code it seems that for some reason you still expect parts of fire() to be executed each frame on its own. this wont happen. what does happen is:
you press space -> a rocket with a pointless constructor is created -> its position is set to the ships position (and im quite sure you dont really want the ship to move forward every time you fire a rocket, so dont use the ++ operator) -> your rocket is drawn (for this and only this single frame alone, so it will disappear before you even see it) -> its checked for out of screen (rather pointless, either check that first and dont create it at all or ignore it and let the update function care about it)

im not sure what you expect this to do, but applying movement and drawing only once is about the same as doing nothing.
remove all movements and checks and whatever from this function, because it belongs into another function that will be called every frame. the only thing that belongs here is the creation of the rocket. also a cleaner constructor would be this:

CRocket::CRocket(float x, float y) : xPos(x), yPos(y) {}

then i see:

glPushMatrix();
glColor3f(1.0, 0.0, 0.0);
glTranslatef(xPos, yPos, -18.0);
glBegin(GL_QUADS);
glVertex2f(-0.04, -0.04);
glVertex2f(0.04, -0.04);
glVertex2f(0.04, 0.04);
glVertex2f(-0.04, 0.04);
glEnd();
glColor3f(1.0, 1.0, 1.0);
glPopMatrix();

are you really sure you want to use the previous matrix and apply a translation to it? given your usage of xPos i would expect that you set the matrix to identity first.

adding the movement here is ok (not exactly good practice, but at least it would work). put that out of screen check here too and make sure that draw is called every frame.

also to avoid memory leaks you have to keep new rockets from being created before the old one is deleted. so dont create one: if (Rocket) return;

this means you have to know when no rocket exists. when deleting it:

delete Rocket;
Rocket=0;


somehow it feels like your coming from a c++ builder (or similar like delphi etc.) background and are used to do typical windows apps.
f@dzhttp://festini.device-zero.de
Jirka
Jirka
I havent read all of the posts, but i think the problem is that you draw the rocket only once. When you press space the rocket is drawn, thats ok, but then u have to draw it every single frame untill the rocket will die or something like that.
So everytime the rocket is drawn, the position will change
(yPos += 0.01f

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.