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

Author Topic: Bullets in SFML.  (Read 33152 times)

0 Members and 1 Guest are viewing this topic.

tiago221

  • Newbie
  • *
  • Posts: 24
    • View Profile
Bullets in SFML.
« Reply #30 on: September 13, 2009, 06:37:54 pm »
I have a problem with the calculate function.

Code: [Select]

void Projectile::Calculate(sf::RenderWindow &app)
{
sf::Vector2f offset;

    offset.x = static_cast<float>(cos(PI * Bullet.GetRotation() / 180) * BulletSpeed * app.GetFrameTime());
    offset.y = static_cast<float>(sin(PI * Bullet.GetRotation() / 180) * BulletSpeed * app.GetFrameTime());

    Bullet.Move(offset);
}


It said Move is an undeclared identifier so I added sf::Sprite bullet to it so it would move the bullet. Now, GetRotation I think it's wrong, because I don't know what the function is supposed to get the rotation from, if it is the bullet and I did it right, it still doesn't draw the bullets.

Spidyy

  • Sr. Member
  • ****
  • Posts: 493
    • View Profile
Bullets in SFML.
« Reply #31 on: September 13, 2009, 07:09:20 pm »
Well I think you should review all your bullet class. :\

And tell us what your programm should PRECISELY do :
- What we should have on screen
- What should happen when we use your controls

The more details we have, the more we can help you. :p

tiago221

  • Newbie
  • *
  • Posts: 24
    • View Profile
Bullets in SFML.
« Reply #32 on: September 13, 2009, 07:14:12 pm »
Right now I have a sprite as the player that can walk around the screen and rotate towards the mouse, I have a camera that follows that sprite and I want to make it shoot bullets with Mouse1 or Left Mouse Button. Controls for walking are WASD.
It's a relatively simple top-down zombie survival game where there are some other sprites as zombies going at you (not implemented yet) and you have to kill them.

As simple as that.

I'm uploading the complete source code, including .pngs and everything.

tiago221

  • Newbie
  • *
  • Posts: 24
    • View Profile
Bullets in SFML.
« Reply #33 on: September 13, 2009, 07:33:45 pm »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Bullets in SFML.
« Reply #34 on: September 13, 2009, 07:46:44 pm »
You should really learn to post only the relevant code, as short as possible, but still reproducing the problem. Many people don't feel like downloading external files with a lot of unrelated code just to answer your questions.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

tiago221

  • Newbie
  • *
  • Posts: 24
    • View Profile
Bullets in SFML.
« Reply #35 on: September 13, 2009, 07:49:39 pm »
He asked the most details possible. :D

I can post relevant code. And I did before, but it seems like it's never enough.


Projectile.h (Bullet Class)

Code: [Select]

#ifndef PROJECTILE_H
#define PROJECTILE_H
#include <SFML/Graphics.hpp>


class Projectile
{
public:
sf::Image BulletImage;
static sf::Sprite Bullet;
bool BulletState;
float BulletSpeed;
     float BulletDirection;


public:

void SetDirection(sf::Sprite);

void SetSpeed(float);

void Destroy(void);

bool IsDestroyed(const Projectile& b);

void Calculate(sf::RenderWindow &app);

};

#endif


Projectile.cpp

Code: [Select]

#include "Projectile.h"
#include <SFML/Graphics.hpp>
#define PI 3.1415926535

sf::Sprite Projectile::Bullet;

void Projectile::SetDirection(sf::Sprite Reference)
{
float TargetRotation = Reference.GetRotation();
Bullet.SetRotation(static_cast<float>(fmod(TargetRotation, 360)));
float BulletRotation = Bullet.GetRotation();
if (BulletRotation < 0)
Bullet.SetRotation(BulletRotation + 360.f);
}

void Projectile::SetSpeed(float NewSpeed)
{
BulletSpeed = NewSpeed;
}

void Projectile::Destroy()
{
BulletState = true;
}

bool Projectile::IsDestroyed(const Projectile& b)
{
if(BulletState)
{
return true;
}
else
{
return false;
}
}

void Projectile::Calculate(sf::RenderWindow &app)
{
sf::Vector2f offset;

    offset.x = static_cast<float>(cos(PI * Bullet.GetRotation() / 180) * BulletSpeed * app.GetFrameTime());
    offset.y = static_cast<float>(sin(PI * Bullet.GetRotation() / 180) * BulletSpeed * app.GetFrameTime());

    Bullet.Move(offset);
}


main.cpp Game Loop

Code: [Select]

while(Window.IsOpened())
{
sf::Event Event;
while (Window.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
Window.Close();
if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
Window.Close();
}

Bullet.SetDirection(Player);
        Bullet.SetSpeed(2);
        Bullet.Calculate(Window);
Window.Clear();
float ElapsedTime = Window.GetFrameTime();
sf::Vector2f MousePos = Window.ConvertCoords(Window.GetInput().GetMouseX(), Window.GetInput().GetMouseY());

if (Window.GetInput().IsKeyDown(sf::Key::W))  Player.Move(0, -425 * ElapsedTime);  
        if (Window.GetInput().IsKeyDown(sf::Key::S))  Player.Move(0,  425 * ElapsedTime);  
if (Window.GetInput().IsKeyDown(sf::Key::A))  Player.Move(-425 * ElapsedTime, 0);
if (Window.GetInput().IsKeyDown(sf::Key::D))  Player.Move(425 * ElapsedTime, 0);  
if (Window.GetInput().IsKeyDown(sf::Key::N))  InGameMusic.Play();
if (Window.GetInput().IsKeyDown(sf::Key::M))  InGameMusic.Stop();
if (Window.GetInput().IsMouseButtonDown(sf::Mouse::Left))  shotFired = true;

if (shotFired)
{
BulletClip.push_back(Bullet);
Bullet.BulletState = false;
}


for (std::vector<Projectile>::iterator Itr = BulletClip.begin(), End = BulletClip.end(); Itr != End; )
{
if (Bullet.IsDestroyed(*Itr))
{
Itr = BulletClip.erase(Itr);
}

else
{
Window.Draw(Bullet.Bullet);
++Itr;
}
}

shotFired = false;

Player.SetCenter(Player.GetSize() / 2.f);
Player.SetRotation(((-1* 360 / PI *(atan2(static_cast<double>(Player.GetPosition().y - MousePos.y), static_cast<double>(Player.GetPosition().x - MousePos.x))))/2)+90);

Camera.SetCenter(follow->GetPosition());
Window.SetView(Camera);
Window.Draw(BackgroundS);
Window.Draw(Player);
Window.Display();
InGameMusic.SetLoop(true);
}

K-Bal

  • Full Member
  • ***
  • Posts: 104
    • View Profile
    • pencilcase.bandcamp.com
    • Email
Bullets in SFML.
« Reply #36 on: September 13, 2009, 08:14:02 pm »
Quote from: "tiago221"

Code: [Select]

class Projectile
{
public:
sf::Image BulletImage;
static sf::Sprite Bullet;


This does not seem to make great sense. What are you trying to achieve here?
Listen to my band: pencilcase.bandcamp.com

tiago221

  • Newbie
  • *
  • Posts: 24
    • View Profile
Bullets in SFML.
« Reply #37 on: September 13, 2009, 08:15:38 pm »
Initialize the bullet sprite and image. Why doesn't it make sense?

Spidyy

  • Sr. Member
  • ****
  • Posts: 493
    • View Profile
Bullets in SFML.
« Reply #38 on: September 13, 2009, 08:15:46 pm »
Okay.

I think you need to review some of basic concepts of C++ and Oriented Object Programming. :\

I'll give you the advices you need to complete your code. Think about it, review your object model, then when you got something else, post it again. =p

You need to review your projectile class. As it is now, it cannot work as a true object. Let's see what it is now :

Code: [Select]

#ifndef PROJECTILE_H
#define PROJECTILE_H
#include <SFML/Graphics.hpp>


class Projectile
{

// First of all, the attributes, meaning "where you store datas" must be in private. An object should be a "black box", its attributes hidden and with the function as "buttons" for the user. Member data are private by default. So we delete the first "public:"

public:

sf::Image BulletImage;  // Here, the image is a big array of pixels stored in memory. When drawing, the image is "copy/paste" on the screen. There is no need to create a new Image at each projectile.

static sf::Sprite Bullet;  // Also, the sf::Sprite already know its image as you have to give it in parameter when creating the sprite, or with a sprite.SetImage(); We don't need the "static" word.

bool BulletState;  // This is OK. We need to know if a bullet is done for before destroying it from the scene.

float BulletSpeed;  // This is OK. A bullet need to know at wich speed it move.

// Let see the functions.

public:
// Here, we need one or two constructors! How the object will know what to do and what are his attributes when we create it? :/

Projectile();  // Default constructor, even if we don't need it right know, it is always usefull to have it. It's rĂ´le is to give our basic attributes a default value at creation.

Projectile(sf::Image &image, sf::vector2f &position, float speed);  // A constructor with parametter for our projectile, all it need to know is what it looks like, from where he begin his course and at what speed.

void SetDirection(sf::vector2f &target);  //  To set the direction, you can use a reference's coordinates, to tell the bullet to wich ennemy it should go

void SetDirection(float angle);  // We can also set the direction with an angle, in degree

void SetSpeed(float);  // Here, you just update the speed of the bullet if it have to change.

void Destroy(bool);  // It's OK, we need to tell when the bullet hit its target

bool IsDestroyed(const Projectile& b);  // It's OK, we need to know if the bullet have hit something, you can also test if it is off the screen here. Don't need parametter.

void Calculate(sf::RenderWindow &app); // It's OK, we need to update the positions of the bullet at each frame with it.

};

#endif


With this, our projectile became more clear. We can also enhance it through the inheritance. Why? Because the sprite already have the data members of a moving object -> a reference to it's image, the xy coordinates and a direction. Why not use it?

Code: [Select]

#ifndef PROJECTILE_H
#define PROJECTILE_H
#include <SFML/Graphics.hpp>

// We make the Projectile class inherite from sf::Sprite
class Projectile : public sf::Sprite
{
sf::Sprite Bullet;  // Projectile became itself a sf::Sprite, we don't need to create another sprite anymore.

bool BulletState;

float BulletSpeed;

public:


Projectile();  // In the default constructor, we'll call for the default constructor of sf::Sprite

Projectile(sf::Image &image, sf::vector2f &position, float speed);  // In this constructor, we'ell call for the sf::Sprite constructor and pass to it the &image and the &position.

void SetDirection(sf::vector2f &target);  // The direction to a target is still interresting, but with an angle, you don't need anymore to have a SetDirection(float angle) function, you can use the sf::Sprite::SetRotation(float rotation).

//  Functions bellow are still needed
void SetSpeed(float);

void Destroy(bool);

bool IsDestroyed();

void Calculate(sf::RenderWindow &app);

};

#endif


At the end, you should have in your main one single sf::Image created before your game loop, your vector ready to receive bullets and a way to add bullet to your vector when pressing your "fire" button. (with insert())

Try to figure out what the function's definition will look like. If you don't know what I was saying in this exemple, review your C++ tutorials and lesson first. :\

If you can't find how to write the class tomorrow or later, I'll give you some answers, but it will meaningless if you don't try a bit more by yourself. :p

And if you don't want to take those advices, feel free to do. :o

tiago221

  • Newbie
  • *
  • Posts: 24
    • View Profile
Bullets in SFML.
« Reply #39 on: September 13, 2009, 08:21:37 pm »
Of course I'll take them, and I'll start working on it right away, thanks. :D