Jump to content
  • Advertisement
Sign in to follow this  
darkzerox

Micro Wars

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

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 this post


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

Shadx

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.


Shadx

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 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!