# Micro Wars

## Recommended Posts

Hello everyone. This thread is about my new game, "Micro Wars". I'll post screenshots and give more details about the game at a later date, if there is interest. However, the main purpose of this thread is so that you wonderful people can help me with various bugs. The first one I'm having is this [Linker error] undefined reference to vtable for PROJECTILE' Without a line-number it makes it a touch hard to debug. The class:
class PROJECTILE
{
public:
int  parent;
bool del;

static void handle();
virtual void step();
virtual void draw();
};


Defined as: list<PROJECTILE> projectile; A function:
void PROJECTILE::handle()
{
for( list<PROJECTILE>::iterator current = projectile.begin(); current != projectile.end(); current++ )
{
current->step();
if( current->del )
{
current = projectile.erase(current);
continue;
}
current->draw();
}
}


Where it's used: projectile.push_back(BULLET(id, px, py, 300, dir)); And the bullet:
class BULLET : public PROJECTILE
{
public:
float x1, y1, x2, y2, lx, ly;
float vel, dir;

BULLET(int p, float px, float py, float v, float d);
void step();
void draw();
bool hit_map(int r);
};

Any ideas what may be causing the problem?

##### Share on other sites
Have you defined your virtual function in the projectile class? If not, you will need to implement them or make them pure virtual.

##### Share on other sites
Virtual methods must provide a base class definition of the method. That is, unless it is pure virtual, in which case the base class has no definition, and the method must be defined in the derivative class. To make something pure virtual, you define it as such:

virtual void draw() = 0;

My guess is you didn't define your virtual functions anywhere.

##### Share on other sites
Ahhh.. so that's what pure/abstract virtual functions are all about.
No, I didn't define it anywhere else, I've never had a problem with that before.

However, now that I added the = 0 part, I get the following errors:

  In instantiation of std::_List_node<PROJECTILE>': 134 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_list.h   instantiated from _Tp* std::_List_iterator<_Tp>::operator->() const [with _Tp = PROJECTILE]' 18 H:\Dev-C++\Pixelwars14\bullet.cpp   instantiated from here 99 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_list.h cannot declare field std::_List_node<PROJECTILE>::_M_data' to be of type PROJECTILE' 99 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_list.h   because the following virtual functions are abstract: 17 H:\Dev-C++\Pixelwars14\bullet.h  virtual void PROJECTILE::draw() 16 H:\Dev-C++\Pixelwars14\bullet.h  virtual void PROJECTILE::step()  H:\Dev-C++\Pixelwars14\Makefile.win [Build Error]  [bullet.o] Error 1 

"here" refers to current->step(); (see PROJECTILE::handle())

##### Share on other sites
If you want to have a list of projectile, you'll want to make those projectile a pointer.

list<Projectile *>

Otherwise it will try to create that type, which because of the pure virtual function cannot be created since it's an abstract class.

##### Share on other sites
Hm... okay I made it <PROJECTILE*>

But now I get

18 H:\Dev-C++\Pixelwars14\bullet.cpp step' is not a type
18 H:\Dev-C++\Pixelwars14\bullet.cpp request for member of non-aggregate type before '(' token

##### Share on other sites
It seems to me that you've forgotten to change a call like:
bullet.step();
to
bullet->step();

that way BULLET* is non aggregate type, therefore cannot be the source for '.' operator.

Show us the "bullet.cpp", if you don't mind ;)

##### Share on other sites
Nope, I was always using ->, as shown above.

[source code="cpp"]#include <SDL/SDL.h>#include <windows.h>#include <cmath>#include <list>#include "draw.h"#include "misc.h"#include "collision.h"#include "bullet.h"#include "draw.h"using namespace std;extern list<PROJECTILE*> projectile;void PROJECTILE::handle(){       for( list<PROJECTILE*>::iterator current = projectile.begin(); current != projectile.end(); current++ )    {        current->step();        if( current->del )        {            current = projectile.erase(current);            continue;        }            current->draw();    }}        BULLET::BULLET(int p, float x, float y, float v, float d){    del    = 0;    parent = p;    vel    = v;    dir    = d;            x1     = x;    y1     = y;    x2     = x + cos(dir) * vel/100;    y2     = y - sin(dir) * vel/100;}               void BULLET::step(){           lx = x2, ly = y2;        float xv = cos(dir) * vel*t;    float yv = sin(dir) * vel*t;            x1 += xv;    y1 -= yv;    x2 += xv;    y2 -= yv;        if( x1 < 0 || x1 >= map->w || y1 < 0 || y1 >= map->h ) del = 1;    else if( hit_map(2) ) del = 1;}                                  void BULLET::draw(){    int a = rint(x1 - scroll_x);    int b = rint(y1 - scroll_y);    int c = rint(x2 - scroll_x);    int d = rint(y2 - scroll_y);    if( clipLine(a,b,c,d,0,0,scr->w-1,scr->h-1) ) drawLine(a,b,c,d);}   bool BULLET::hit_map(int r) {    int i,dx,dy,sdx,sdy,x,y,px,py;	dx = rint(x2 - lx);	dy = rint(y2 - ly);	sdx = (dx < 0) ? -1 : 1;	sdy = (dy < 0) ? -1 : 1;	dx = abs(dx);	dy = abs(dy);	x = dy << 1;	y = dx << 1;	px = rint(lx);	py = rint(ly);	if( !point_empty(px,py) )    {        filledEllipse(px,py,r,r,c_empty,map);        return 1;    }        if (dx >= dy) {		for (i = 0; i < dx; i++) {			y += dy;			if (y >= dx) {				y -= dx;				py += sdy;			}			px += sdx;	        if( !point_empty(px,py) )	        {	            filledEllipse(px,py,r,r,c_empty,map);                return 1;            }   		}	} else {		for (i = 0; i < dy; i++) {			x += dx;			if (x >= dy) {				x -= dy;				px += sdx;			}			py += sdy;	        if( !point_empty(px,py) )	        {	            filledEllipse(px,py,r,r,c_empty,map);                return 1;            }  		}	}	return 0;}

##### Share on other sites
Oh, now I see.

Explicit dereferencing the iterator will do (I've tested it just now).
(*current)->step();

Cheers.
/def

##### Share on other sites
Well, that fixed one problem. Thanks a lot :D

Now how would I do projectile.push_back(BULLET(id, px, py, 300, dir));? Probably need some crazy *'s all over the place..

##### Share on other sites
You could do it like this:

BULLET *newBullet = new BULLET(id, px, py, 300, dir);
projectile.push_back(newBullet);

Remember to iterate through your list and call delete to free up your memory when you're finished!

-Mezz

##### Share on other sites
Ah... I need new again. I was trying different combinations with * and ->... none of which worked :p

See, the first time I tried push_back I used new, but then I discovered I didn't need it... and now I do again... sheesh :p

Anyways, thanks!

BTW, projectile.push_back(new BULLET(id, px, py, 300, dir)); works just fine. But I've seen it done your way much more often... I like my shortcuts.

Now for my game I've planned out 12 different guns so far. Originally I had more, but I decided to give each one a secondary fire instead. So in a way... there's 23. I've tried to keep the weapons as different as possible from eachother, but there may be a few similarities here and there. I say 23, because I can't come up with a secondary for the Magnum... any suggestions?

I suppose I should tell you what the game is about first. Here's a screenie, it can do the talking for me.

There'll be blood and stuff in the newer version. I'm going to try and concentrate on game-play first. Which is really not my style, I usually get caught up in the physics and coolness of the game, but I figure having something playable for a change could get my rep up a little (haha).

I'm trying to keep my code clean this time through.. do it the proper and professional way....

Edit: Just noticed that you're Mezz :) *claps* You found my new thread.. I think I'll keep all my questions in here now (related to this game anyway).

[Edited by - darkzerox on June 3, 2005 5:23:45 PM]

##### Share on other sites

Lightning came out a lot better than expected. Had anticipated a lot more problems, but it worked out quite well. It definately feels lightning-y.

I just can't decide on which I like better.

The first version shoots 8 bolts of lightning, which go in one general direction, but are fairly erratic.

The second version allows for "forking". This was all very nice, but I had it fork in the same general direction as the rest of the lightning, resulting in just a massive buildup at the end of the stream. So I let it branch off at different angles..

Now if one branches off at say 30 degrees, and another branches off at 30 degrees,... and everything has a 10% chance to branch...

Well, the lightning literally dissolved my map. It eventually filled the entire screen... and lowered my FPS to about 20. Which really isnt bad, given the number of lines it had to draw and calculate. But it will never have to do that in a real game :D

Now originally I had the lightning bolts draw the entire path of the lightning bolt from your character to where it hits, and when it hits the entire bolt disappears. Which I thought was sort of a neat electrical property type thing, but drawing only the last 10 segments of the bolt is pretty neat too.

Anyways, I can use two different versions for my final game, one for primary and secondary fire.

I want one to be fairly straight.. so perhaps no branching.

The other one I want to have a much wider spray, but shorter range. Or perhaps I could have it go in all 360 degrees? To form like a mini-protection shield...

Also... I could have it charge up. Depending on how much you charge, it could determine how much it branches... its chance to branch, the max number of branches allowed....... so many choices!

BTW, it looks a lot cooler in game, with full motion... I made each line segment randomly change to a different shade of blue every frame (the lazy way out).. but ya. It looks good.

Grenades and Fork Lightning have also been added...... maybe I should stop posting updates til I release something eh?

[Edited by - darkzerox on June 4, 2005 4:15:12 PM]

##### Share on other sites
Got some basic networking in.
Was easier than I had newly anticipated.
I thankfully found a Dev-Cpp/mingw port of raknet.... which greatly helped.

Do wish they didn't install it to the folder they did... though its not a big concern. Just some minor adjustments and it works great.

Their tutorial/samples could have been better too I think.

But I've got it figured out now. The first time I ran my program they were nearly perfectly in sync, but now they are like 10 seconds behind eachother unfortunately... don't know what I'm going to do about that.

I'm using UNRELIABLE_SEQUENCED packets to send positions/velocities. I figured if it got behind, it would send a more recent packet and the character would warp to his new position as he should. However... it seems like nearly all the packets are being received.. just 10 seconds behind. Are the send times just slow?

[EDIT]
*WAHAHAHAA*

I think I just figured it out. I removed the FPS limiter to check how fast it would really be capable of going.. therefore there were no "waits". So the window in focus was using all the CPU....

Anyways.. thats awesome then :D

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628300
• Total Posts
2981894

• 9
• 9
• 11
• 10
• 10