Archived

This topic is now archived and is closed to further replies.

Question about weapons

This topic is 5376 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

Lately, i''ve been trying to create a space game (like star control to give you an idea, you know, top down) and i''ve kind of hit a snag with the actual firing and drawing of the bullets/missles/lasers. So how would i go about implementing the use of weapons into my game. One thing is that the weapons won''t dissappear if they go off screen, instead they have to wrap around to the other side [a la star control, again]. This part i got done just by moving the co-ordinates over, the main thing is the ability to fire repeatedly and dissappearing after a set amount of time. Also, we have to have the weapons start with the velocity of the ship and then continue on its path without being affected by the ship''s movement. Thanks,

Share this post


Link to post
Share on other sites
a good idea is to use vectors for the acceleration/velocity/position.

if you are programming object-oriented style then create an independant bullet class...

class Bullet
{
Vector3f velocity;
Vector3f position;
int life; //life in frames or seconds

public:
Bullet(Vector3f position, velocity);

update/draw();

};

then when you fire, dynamically create one of these suckers then call it in your global update/draw routine,
where position+=velocity*timePassed;
if position>screenBoundary, then position= blahblah....
also life+=timePassed; and if life>1000 or whatever destroy the chump

Actually a good design would incorporate a base Object class that has member functions such as draw, update, and variables such as velocity, position...then all your specific object are just inherited from these. then you can create an ObjectManager singleton class that controls the creation/destruction and management of all the objects via polymorphism.

does this help???

Share this post


Link to post
Share on other sites
You can''t name your function "update/draw"; that''s illegal in C/C++. You can only use numbers and letters and the underscore character. Your name can start with the under score or letter, but it cannot start with a number. Do you understand!

Share this post


Link to post
Share on other sites
hmmm this was actualy something i was wondering myself, heres what i had so far...

//global things...
camera g_Camera //my camera, controls the view and such
projectile *bullet=NULL;

//projectile class
class projectile
{
public:
projectile();
projectile(vector3 starposition, vector3 startvelocity, vector3 startacceleration, unsigned int startlife);
void update();
unsigned int life;
private:
vector3 position;
vector3 velocity;
vector3 acceleration;

};

projectile:rojectile()
{
position.x=0;
position.y=0;
position.z=0;
velocity.x=0;
velocity.y=0;
velocity.z=0;
acceleration.x=0;
acceleration.y=0;
acceleration.z=0;
life=1000;
}

projectile:rojectile(vector3 startposition, vector3 startvelocity, vector3 startacceleration, unsigned int startlife)
{
position=startposition;
velocity=startvelocity;
acceleration=startacceleration;
life=startlife;
}

void projectile::update()
{
glBegin(GL_QUADS);

glColor3ub(255,0,0);
glVertex3f(position.x-1,position.y+1,position.z);
glVertex3f(position.x+1,position.y+1,position.z);
glVertex3f(position.x+1,position.y-1,position.z);
glVertex3f(position.x-1,position.y-1,position.z);

velocity=velocity+acceleration;
position=position+velocity;

life--;
glEnd();
}


//WinProc, this is where i check to see if Z has been pressed to fire the projectile

LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LONG lRet=0;
PAINTSTRUCT ps;

switch (uMsg)
{
case WM_SIZE: if (!g_bFullScreen)
{
SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));
GetClientRect(hWnd,&g_rRect);
}
break;
case WM_PAINT: BeginPaint(hWnd,&ps);
EndPaint(hWnd,&ps);
break;
case WM_KEYDOWN: switch (wParam)
{
case VK_ESCAPE: PostQuitMessage(0);
break;

case ''Z'': if (bullet==NULL)
{
vector3 sposition;
sposition.x=g_Camera.view.x-g_Camera.position.x;
sposition.y=g_Camera.view.y-g_Camera.position.y;
sposition.z=g_Camera.view.z-g_Camera.position.z;
vector3 svelocity;
svelocity.x=0;
svelocity.y=0;
svelocity.z=0.1f;
vector3 sacceleration;
sacceleration.x=0;
sacceleration.y=0;
sacceleration.z=0.0;
bullet=new projectile(sposition,svelocity,sacceleration,100);
}
break;

}
break;
case WM_CLOSE: PostQuitMessage(0);
break;
default: lRet=DefWindowProc(hWnd,uMsg,wParam,lParam);
break;
}

return lRet;
}

//function that does the drawing for the entire environment
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

gluLookAt(g_Camera.position.x,g_Camera.position.y,g_Camera.position.z,g_Camera.view.x,g_Camera.view.y,g_Camera.view.z,g_Camera.upvector.x,g_Camera.upvector.y,g_Camera.upvector.z);

//draw scene here
// wireframecube(1,0,0,0,255,0,0);
// wireframecube(2,0,0,0,0,255,0);
// wireframecube(3,0,0,0,0,0,255);

// trianglematrix(6,2,0,0,0);

if (bullet!=NULL)
{
bullet->update();
if (bullet->life<=0)
{
delete bullet;
bullet=NULL;
}
}



SwapBuffers(g_hDC);
}

it sorta works, it doesnt go in the direction i hoped, but hey, its a start at making projectiles =P

Bungo!

Share this post


Link to post
Share on other sites
lol changed it so under the update function this is what is used...

glVertex3f(position.x-0.1f,position.y+0.1f,position.z);
glVertex3f(position.x+0.1f,position.y+0.1f,position.z);
glVertex3f(position.x+0.1f,position.y-0.1f,position.z);
glVertex3f(position.x-0.1f,position.y-0.1f,position.z);

makes the square smaller, which actualy seems to make a difference

now to figure out how to make it go forward lol
and how to make it stop once it goes out too far =P

Bungo!

Share this post


Link to post
Share on other sites
oh, and while im thinkin about it, how would i go about making it so i didnt necessarily have to have a global pointer, or even a global array (for multiple projectiles). i cant really see a way to do it, cause itd have to be created in the RenderScene() function, and that function is called by another function that uses an infinate loop (to continualy draw the scene). so im at a loss as to how else it could be done, but i know there has got to be a way, cause if there isnt then itd get very messy when you had for example, multiple characters firing multiple shots =/ bah!

Bungo!

Share this post


Link to post
Share on other sites
heres what i reckon u do:

1. for a start don't rely on the camera to get coords, each OBJECT has there own positions, which when drawn are then affected by the camera's position simply by using a glTranslate function or whatever.
2. get rid of acceleration for bullets, they should have a const velocity which is velocity of ship+some number.
3. use an Object Manager singleton class to create ALL objects. if you don't know what a singleton class is then have a read up of gamedev articles. basically it means that there is only ever one instance of a class made at one time. enabling you to pass a reference of it to any other files/classes and they can access the information within them (bad explanation!)
4. either create a linked list structure class, or just use STL's vector, or better yet- map, for the storage of all your objects.

*i was just thinking, if ur not comfortable with polymorphism, then u could create manager classes for each object type...like ShipManager, BulletManager, AsteroidManager...etc


    
//basically


class BulletManager
{
//input singleton stuff ....


//has one vector to store all objects...


vector<Bullet>bulletList;
vector<Bullet>iterator it;//container iterator


public:

//blah blah blah

void addBullet();
void update();

};

void addBullet()
{
Bullet newbullet;
it.push(newbullet);
}

void ObjectManager::update()
{
for(it=objectList.begin(); it!=objectList.end(); it++)
{
it->update(); //calls the individual Objects update function (syntax maybe wrong)

}
}
/////


BulletManager& bulletManager = BulletManager::getHandle();//singleton stuff


///keyboard handler////

case 'Z':
{
vector3 sposition=ship.getPosition();
vector3 svelocity=ship.getVelocity();

bulletManager.addbullet(sposition, svelocity+bulletconstant);
break;
}




i have probably confused you even more, but this is the general track u should follow for a nice and clean game structure...

and thinking about it, using a queue for the bullets would actually be a lot quicker and easier to implement, as all the bullets have the same life span

[edited by - kuladus on March 25, 2003 5:31:17 AM]

Share this post


Link to post
Share on other sites
i thought about using vectors (along with a queue of some sort), i dont know what a singleton is, but ive at least heard of them, ill look into them and see if that helps in the slightest

Bungo!

Share this post


Link to post
Share on other sites
i took your idea on singletons and tried to impliment it, most of it seems to work, but one function (which you wrote)...

void projectilemanager::update()
{
for(it=projectileslist.begin();it!=projectileslist.end();it++)
{
it->update();
}
}

i think i see what that function does, it sets the iterator vector to the begining of the projectile vector. then it goes through each one in the list, then updates it. seems ok, except it gives me the following errors:

--------------------Configuration: Camera2 - Win32 Debug--------------------
Compiling...
Main.cpp
c:\program files\microsoft visual studio\my projects\miscellaneous\camera part 2\main.cpp(177) : error C2660: ''addprojectile'' : function does not take 3 parameters
projectilemanager.cpp
c:\program files\microsoft visual studio\my projects\miscellaneous\camera part 2\projectilemanager.cpp(35) : error C2679: binary ''='' : no operator defined which takes a right-hand operand of type ''class projectile *'' (or there is no acceptable conve
rsion)
c:\program files\microsoft visual studio\my projects\miscellaneous\camera part 2\projectilemanager.cpp(35) : error C2678: binary ''!='' : no operator defined which takes a left-hand operand of type ''class std::vectortor >'' (or there is no acceptable conversion)
c:\program files\microsoft visual studio\my projects\miscellaneous\camera part 2\projectilemanager.cpp(35) : error C2676: binary ''++'' : ''class std::vector >'' does not define this operator or a
conversion to a type acceptable to the predefined operator
c:\program files\microsoft visual studio\my projects\miscellaneous\camera part 2\projectilemanager.cpp(37) : error C2819: type ''std::vector >'' does not have an overloaded member ''operator ->''
c:\program files\microsoft visual studio\my projects\miscellaneous\camera part 2\projectilemanager.cpp(37) : error C2227: left of ''->update'' must point to class/struct/union
Error executing cl.exe.

Camera2.exe - 6 error(s), 0 warning(s)

seems to have to do with the STL vector lacking those overloaded operators or something... im not totaly sure how to fix this cause i am only just understanding the whole process here...

here is the class i have going so far (the projectile manager singleton)

//projectilemanager.h
#ifndef _projectile_manager_h
#define _projectile_manager_h

#include <vector>

class projectilemanager
{
public:
~projectilemanager();
static projectilemanager* create();
void addprojectile(vector3 sposition, vector3 svelocity, vector3 sacceleration, int slife);
void update();
private:
projectilemanager();
static bool flag;
static projectilemanager *instance;
std::vector projectileslist;
std::vector it;
};

#endif


//projectilemanager.cpp
#include "main.h"

bool projectilemanager::flag=false;
projectilemanager* projectilemanager::instance=NULL;

projectilemanager:rojectilemanager()
{

}

projectilemanager::~projectilemanager()
{
flag=false;
}

projectilemanager* projectilemanager::create()
{
if (!flag)
{
flag=true;
instance=new projectilemanager;
}

return instance;
}

void projectilemanager::addprojectile(vector3 sposition, vector3 svelocity, vector3 sacceleration, int slife)
{
projectile newprojectile(sposition,svelocity,sacceleration,slife);
it.push_back(newprojectile);
}

void projectilemanager::update()
{
for(it=projectileslist.begin();it!=projectileslist.end();it++)
{
it->update();
}
}


//inside main.cpp (the file with all the global functions and fun stuff
#include "main.h" //where #include "projectilemanager.h" can be found (just so you know)

projectilemanager *projectiles=projectilemanager::create();

//under WinProc
case ''Z'': vector3 sposition;
sposition.x=g_Camera.view.x-g_Camera.position.x;
sposition.y=g_Camera.view.y-g_Camera.position.y;
sposition.z=g_Camera.view.z-g_Camera.position.z;
vector3 svelocity;
svelocity.x=0.0f;
svelocity.y=0.0f;
svelocity.z=-0.1f;
vector3 sacceleration;
sacceleration.x=0.0f;
sacceleration.y=0.0f;
sacceleration.z=0.0f;
projectiles->addprojectile(sposition,svelocity,sacceleration,100);
break;

//under the RenderScene() function, the function that updates continualy draws everything

projectiles->update();


i think thats all the relevant code =P

Bungo!

Share this post


Link to post
Share on other sites
hmmm seems the easiest way around all this mess was just a vector =P


  
//in main.cpp

std::vector <projectile> bullets;

//inside of winproc

case ''Z'': vector3 sposition;
sposition.x=g_Camera.view.x-g_Camera.position.x;
sposition.y=g_Camera.view.y-g_Camera.position.y;
sposition.z=g_Camera.view.z-g_Camera.position.z;
vector3 svelocity;
svelocity.x=0.0f;
svelocity.y=0.0f;
svelocity.z=-0.1f;
vector3 sacceleration;
sacceleration.x=0.0f;
sacceleration.y=0.0f;
sacceleration.z=0.0f;
bullets.resize(bullets.size()+1);
projectile newbullet(sposition,svelocity,sacceleration,100);
bullets[bullets.size()-1]=newbullet;
break;

//under RenderScene()

for (int x=0;x<bullets.size();x++)
{
bullets[x].update();
}

for (x=0;x<bullets.size();x++)
{
if (bullets[x].life<=0)
{
if (bullets.size()==1)
{
bullets.resize(0);
}
else
{
if (x==bullets.size()-1)
{
bullets.resize(bullets.size()-1);
}
else
{
for (int y=x;y<bullets.size()-1;y++)
{
bullets[y]=bullets[y+1];
}
bullets.resize(bullets.size()-1);
}
}
}
}


it works, now to make them start from different positions and such...

i know there was other stuff you mentioned i should fix, one thing at a time hehe. as far as acceleration goes, this projectile class im thinkin is gonna be a base class for other things that will have acceleration (even acceleration that changes in all directions so it can loop around and such). but yeah, for bullets acceleration is left at 0

Bungo!

Share this post


Link to post
Share on other sites
the fact that you have a global vector of projectiles, defeats the purpose of the manager class. As your program gets larger and larger you will end up confusing yourself...!

oh, and you should use a queue because of the nature of the pjoectiles, especially bullets.

Basically your main.cpp should be nice and clean-


  

//main.cpp


BulletManager& bMan = BulletManager::getHandle(); //global


//winproc


case ''Z'':
{
vector3 sposition;
sposition=g_Camera.view-g_Camera.position; //overload the common operators (+,-,etc) in your vector3 class dude!!!

vector3 svelocity(0,0,-0.1f); //add appropriate constructors to make it cleaner

vector3 sacceleration(0,0,0);

bMan.newBullet(sposition, svelocity, sacceleration, 100);
}

//update

bMan.update();

//render

bMan.drawAll();


this way, the manager handles all creation/deletion and updating of bullets. It also handles all the drawing of the bullets.

if you need more help, i''ll give you a hand at fleshing this all out...but really its not that difficult, just a little arduous at finding the right information to encapsulate

Share this post


Link to post
Share on other sites
oh yer, shouldn''t:
bullet position=ships position,
and
bullet velocity=constant*(ships direction normal)

i don''t know where your going by making position = camera.view-camera.pos, but it looks awful messy!

cheers

Share this post


Link to post
Share on other sites
well right now i dont got a "ship" or anything (the guy who started this prolly does). im just messing around so i can get the gist of how this all works

i guess id use the projectilemanager class if it worked. in theory it should, but what i was doing didnt seem to work =/. i honestly dont know how to fix it tho =(

Bungo!

Share this post


Link to post
Share on other sites
oh and i do have +,-,*, and / overloaded in the vector3 class, i dont know why i didnt use them =P prolly just forgot i had them overloaded

as far as using a queue, right now i dont need to, cause it would just make things complicated, ill deal with that later. plus with what i have now it kind of looks like the plasma gun from doom =P. well... in that its a bunch of rapidly firing projectiles that have no descernable limit as to how fast they can be fired off (which is kind of the effect im going for).

Bungo!

Share this post


Link to post
Share on other sites
Bungo- ahh so you are making an fps? shakes his head :o

what was your problem with the projectile manager class? compilation or runtime issue?

plus queues are easier to use than vectors...

  
#include <queue>
deque<Bullet> bulletQueue;

//addnewbullet

Bullet newBullet(pos, vel);
bulletQueue.push_back(newBullet);

//updator


if(bulletQueue.front().getLife()>BULLET_LIFE_SPAN) bulletQueue.pop_front(); //delete one at front if life is over constant value (but only need to test first one, as it was first in)


for (it=bulletQueue.begin(); it!=bulletQueue.end(); it++) it->update();

so simple!!!

Share this post


Link to post
Share on other sites
quote:
Original post by 63616C68h
You can''t name your function "update/draw"; that''s illegal in C/C++. You can only use numbers and letters and the underscore character. Your name can start with the under score or letter, but it cannot start with a number. Do you understand!


I can''t figure out if he is making a joke or not. I hope he is.

~CGameProgrammer( );
DevImg.net - Post screenshots, comment on others.
Town 3D Engine - A city-rendering 3D engine. Download the demo.

Share this post


Link to post
Share on other sites
quote:

projectile:rojectile()
{
position.x=0;
position.y=0;
position.z=0;
velocity.x=0;
velocity.y=0;
velocity.z=0;
acceleration.x=0;
acceleration.y=0;
acceleration.z=0;
life=1000;
}

projectile:rojectile(vector3 startposition, vector3 startvelocity, vector3 startacceleration, unsigned int startlife)
{
position=startposition;
velocity=startvelocity;
acceleration=startacceleration;
life=startlife;
}


talking about less messy.. default parameters and initialization are your friends here:


        
class vector3 {
public:
float x,y,z;
vector3(float x0=0, float y0=0, float z0=0) : x(x0), y(y0), z(z0) {}
};
//just for speed, not necessary

vector3 zerovec(0,0,0);

class p {
public:
vector3 position;
vector3 velocity;
unsigned life;

p(vector3& startposition=zerovec, //faster

vector3& startvelocity=vector3(), //also possible

unsigned int startlife=100);
};

p::p(vector3& startposition, vector3& startvelocity, unsigned int startlife)
:position(startposition), velocity(startvelocity), life(startlife) {}

int main() {
p pro0; //all zero, life=100

p pro1(vector3(4,5,2)); //pos(4,5,2), vel=0, life=100

p pro2(vector3(4,5,2), vector3(1,2,3)); //and so on

p pro3(vector3(4,5,2), vector3(1,2,3), 50);
return 0;
}


i think thats a lot more comfortable than writing a constructor for every single case and shorter code is easier to read

[edited by - Trienco on March 27, 2003 3:28:45 AM]

Share this post


Link to post
Share on other sites
"ahh so you are making an fps? shakes his head :o"

huh? bah im new to all this =P so i honestly dont know what the best way to do ANYTHING is

the problem with the projectile manager singleton was a run time issue, it didnt do ANYTHING... i pressed ''Z'' (to make a projectile appear) and it didnt do a thing =/

i think im just confused about the whole queue thing right now... lol ill figure it out, i understand how vectors work, but im a lil shaky (spelling?) on queues (im only in HS computer science 2). so all of this is waaaaaaaaaaaay beyond anything we talk about in class (though we did do a breif thing on queues, it was the stupid AP class tho, so its not the standard). like i said, one thing at a time =P when i get the whole projectile manager down ill work on making it use queues. oh and btw, whats an fps? and by shaking your head i take it that means whatever it is there is something wrong with it? if so how else can i do this? or rather, is there a better method to doing it? being a newbie sucks =(

Bungo!

Share this post


Link to post
Share on other sites
fps=first person shooter.

since u said u didn't have a 'ship' and your bullets seemed to be directly linked to the camera, i just figured you were making an fps.

queues are just FIFO (first-in first-out) lists. so the first thing u push_in, will be the first thing you pop_out.

so if u have bullets with all the same life span, then obviously the first one made is the first one destroyed.

ed: oh yer, i was shaking my head, because i thought you were making a 2d shooter...

[edited by - kuladus on March 28, 2003 1:19:14 AM]

Share this post


Link to post
Share on other sites
oh lol... well i wasnt specificly making a first person shooter, i guess i could turn it into one. for now im just trying stuff out and seeing if i can get everything to work =P

right now the way i have everything set up it kinda works such that the first bullet created is the first one to be destroyed, they all go the same distance, but no matter the first one fired is the first one to disappear (or be deleted from the vector).

ill mess around with a queue and see if it works more efficiently (and see if it works in a way i want).

2d shooter? like doom? hehe nah =P

Share this post


Link to post
Share on other sites