Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Program crashes when LMB is pressed  (Read 2314 times)

0 Members and 1 Guest are viewing this topic.

Dark Byte

  • Newbie
  • *
  • Posts: 30
    • View Profile
Program crashes when LMB is pressed
« on: October 07, 2010, 12:30:16 am »
This program compiles correctly, but when the left mouse button is pressed it gives this error:
pure virtual method called
terminate called without active exception

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

It only happens when a new instance of the class CBullet is created. It (in this program) is only created when you press the LMB.

When a new CBullet is created it adds a pointer to that class to the vector CBullets. And when it is destroyed it is removed from the vector.

I am compiling with MinGW. My command line is:
g++ main.cpp -obin/output.exe -lsfml-system -lsfml-window -lsfml-graphics -lsfml-audio -static-libgcc -static-libstdc++

Edit:
It happens when the sprite is drawn at line 188

Code: [Select]

#include <cmath>
#include <vector>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

#define PI 3.14159265358979

using namespace std;

template <class T>
T FindDistance(T x1, T x2, T y1, T y2)
{
return sqrt( (x2 - x1)*(x2-x1) + (y2 - y1)*(y2-y1) );
}

class CBullet;
vector<CBullet*> CBullets;

sf::Image IMGBullet;

class CBullet
{
private:
float MAX_DIST, rot, sx, sy;
bool force_destroy;

public:
sf::Sprite Sprite;

CBullet(float x, float y, float rot_)
{
this->MAX_DIST = 350.f;
this->force_destroy = false;
this->Sprite.SetImage(::IMGBullet);
this->Sprite.SetX(x);
this->sx = x;
this->Sprite.SetY(y);
this->sy = y;
this->rot = rot_;
CBullets.push_back(this);
}

~CBullet()
{
for ( int i; i < CBullets.size(); i++ )
{
if ( CBullets[i] == this )
{
CBullets.erase(CBullets.begin() + i);
break;
}
}
}

void Update (void)
{
if ( !this->force_destroy )
{
float X = this->Sprite.GetPosition().x;
float Y = this->Sprite.GetPosition().y;
if ( FindDistance<float> (X, sx, Y, sy) >= MAX_DIST )
{
this->force_destroy = true;
}

this->Sprite.SetX( X + sin(rot) );
this->Sprite.SetY( Y - cos(rot) );
}
else
delete this;
}

} ;


int main()
{
sf::Image IMGPlayer;
sf::Image IMGCursor;
sf::Image IMGBack;

sf::SoundBuffer SNBShoot;

sf::RenderWindow App(sf::VideoMode(800,600,32), "rotation test");

App.ShowMouseCursor(false);

sf::Clock CLKShoot;

if ( !IMGPlayer.LoadFromFile("gfx/player.bmp") )
App.Close();
IMGPlayer.CreateMaskFromColor(sf::Color(255,0,255));

if ( !IMGCursor.LoadFromFile("gfx/pointer.bmp") )
App.Close();

if ( !IMGBack.LoadFromFile("gfx/desktop.png") )
App.Close();

if ( !SNBShoot.LoadFromFile("sfx/elite.wav") )
App.Close();

if ( !IMGBullet.LoadFromFile("gfx/bullet.bmp") )
App.Close();

sf::Sound SNDShoot;
SNDShoot.SetBuffer(SNBShoot);

IMGCursor.CreateMaskFromColor(sf::Color(255,0,255));

sf::Sprite SPRPlayer;
sf::Sprite SPRCursor;
sf::Sprite SPRBack;

SPRPlayer.SetImage(IMGPlayer);
SPRCursor.SetImage(IMGCursor);
SPRBack.SetImage(IMGBack);

SPRPlayer.SetSubRect(sf::IntRect(1,1,32,32));
SPRCursor.SetSubRect(sf::IntRect(0,0,25,25));

SPRPlayer.SetX(400);
SPRPlayer.SetY(300);

SPRPlayer.SetCenter(16.f, 16.f);
SPRCursor.SetCenter(11.f, 11.f);

sf::Vector2f Center(400, 300);
    sf::Vector2f HalfSize(400, 300);
sf::View MainView(Center, HalfSize);
CLKShoot.Reset();
while ( App.IsOpened() )
{
sf::Event Event;
while ( App.GetEvent(Event) )
{
if ( Event.Type == sf::Event::Closed )
App.Close();
}

float Offset = 150.f*App.GetFrameTime();
if ( App.GetInput().IsKeyDown(sf::Key::LShift) )
Offset *= 0.35f;
if ( App.GetInput().IsKeyDown(sf::Key::W) )
{
MainView.Move(0, -Offset);
SPRPlayer.Move(0, -Offset);
}
if ( App.GetInput().IsKeyDown(sf::Key::A) )
{
MainView.Move(-Offset, 0);
SPRPlayer.Move(-Offset, 0);
}
if ( App.GetInput().IsKeyDown(sf::Key::S) )
{
MainView.Move(0, Offset);
SPRPlayer.Move(0, Offset);
}
if ( App.GetInput().IsKeyDown(sf::Key::D) )
{
MainView.Move(Offset, 0);
SPRPlayer.Move(Offset, 0);
}
if ( App.GetInput().IsMouseButtonDown(sf::Mouse::Left) && CLKShoot.GetElapsedTime() >= SNBShoot.GetDuration() )
{
SNDShoot.Play();
CBullet bullet(SPRPlayer.GetPosition().x, SPRPlayer.GetPosition().y, SPRPlayer.GetRotation());
CLKShoot.Reset();
}

App.SetView(MainView);
App.Clear();

sf::Vector2f MousePos = App.ConvertCoords(App.GetInput().GetMouseX(), App.GetInput().GetMouseY());

SPRCursor.SetX(MousePos.x);
SPRCursor.SetY(MousePos.y);

SPRPlayer.SetRotation( -(atan2(App.GetInput().GetMouseY()-300, App.GetInput().GetMouseX()-400) * 180 / PI + 90) );

App.Draw(SPRBack);
App.Draw(SPRPlayer);

for ( int i = 0 ; i < CBullets.size(); i++ )
{
CBullets[i]->Update();
App.Draw(CBullets[i]->Sprite);
}

App.Draw(SPRCursor);

//App.SetView(App.GetDefaultView());

App.Display();
}

return 0;
}


Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Program crashes when LMB is pressed
« Reply #1 on: October 08, 2010, 01:02:36 am »
Minimize your code to a complete example still reproducing the problem, but abandoning any parts that are irrelevant to the error.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

ThaxSillion

  • Newbie
  • *
  • Posts: 5
    • View Profile
Program crashes when LMB is pressed
« Reply #2 on: October 09, 2010, 03:04:35 pm »
I guess the problem is here:

Code: [Select]
CBullet bullet(SPRPlayer.GetPosition().x, SPRPlayer.GetPosition().y, SPRPlayer.GetRotation());
         CLKShoot.Reset();
      }


The bullet is being pushed back to your list/vector, but it's destroyed - goes out of scope.

Try doing something like

Code: [Select]
CBullet *bullet = new CBullet(SPRPlayer.GetPosition().x, SPRPlayer.GetPosition().y, SPRPlayer.GetRotation());

don't forget about deleting it somewhere later.

Dark Byte

  • Newbie
  • *
  • Posts: 30
    • View Profile
Program crashes when LMB is pressed
« Reply #3 on: October 09, 2010, 08:38:30 pm »
It has been fixed

 

anything