Bullet keep following mouse please Help c++/sfml

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
Fantasy
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 4
Joined: Mon Dec 19, 2011 5:51 pm

Bullet keep following mouse please Help c++/sfml

Post by Fantasy »

Hello
can you guys please please help me. I'm going insane here.
I wrote a piece of code that when you click on the mouse the bullet check for the mouse angle and fire in that direction.
but the problem is the bullet keep following the mouse. its not suppose to do that. it should check for the mouse position and angle and fire in that direction. can you please help.

Code: Select all

void Bullet::Draw(sf::RenderWindow &Game)
{

	float ElapsedTime = Game.GetFrameTime()/60;

	int MouseX = Game.GetInput().GetMouseX();
	int MouseY = Game.GetInput().GetMouseY();

	double PI =3.14159265;
	if(Counter>=0)
	{
		for(int i=0; i<=Counter; i++)
		{
			float Speed = 10;

			float BulletX = Sprite[i].GetPosition().x;
			float BulletY = Sprite[i].GetPosition().y;
			
			float AngleX = MouseX - BulletX;
			float AngleY = MouseY - BulletY;

			float vectorLength = sqrt(AngleX*AngleX + AngleY*AngleY);

			float DirectionX = AngleX / vectorLength;
			float DirectionY = AngleY / vectorLength;

			float VelocityX = DirectionX * Speed;
			float VelocityY = DirectionY * Speed;


			Sprite[i].Move (VelocityX, VelocityY);


			Game.Draw(Sprite[i]);
		}
	}
}
User avatar
szdarkhack
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 61
Joined: Fri May 08, 2009 2:31 am

Re: Bullet keep following mouse please Help c++/sfml

Post by szdarkhack »

Hmm, it seems that you're getting the mouse position every frame and that's why it keeps following the mouse. You should only get the input once (when you click) and calculate the velocity at that point, rather than on every redraw of the sprite.

I'm assuming here that you're calling Draw every frame. It also seems that you have a sort of "draw loop" inside this function. That's bad, it will lock up the game completely for as many frames as it takes to complete.

What you should do instead is to call another function (like OnMouseClick() or something) when the mouse button is clicked that calculates the direction and velocity and stores them. After that, remove all these calculations from your Draw() and use the stored values. Your Draw() should only contain the position update (you should move that out to an Update() preferably, but it's not too big a deal for something this simple) and the drawing code.
Fantasy
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 4
Joined: Mon Dec 19, 2011 5:51 pm

Re: Bullet keep following mouse please Help c++/sfml

Post by Fantasy »

Thank you the replay i really appreciate it. However i think i did what you said (not sure) and its still not working. I'm sorry but I'm a newbie i spent the last 4 hours reading, researching and coding trying to fix the stupid problem but i just can't. Now the problem is that the when i click the mouse the bullets move only 1 pixel and spawn new bullet.

I created a new function called createBullet() which handles the calculations and Init() get mouse X and Y positions. I call CreateBullet() when the mouse is clicked.

Bullet.h

Code: Select all

#include <SFML\Graphics.hpp>
#include <iostream>
#include <string>
#include <sstream>

class Bullet
{
public:
	Bullet();
	~Bullet();
	void LoadFile(sf::RenderWindow &Game);
	void Init(sf::RenderWindow &Game);
	void SetPosition(sf::RenderWindow &Game);
	void MouseEvent(sf::Event &Event);
	void CreateBullet(sf::RenderWindow &Game);
	void Draw(sf::RenderWindow &Game);
	
	bool Clicked;
	sf::RenderWindow Game;
private:
	sf::Image Image;
	sf::Sprite Sprite[101];
	int Direction, Amenition, Amenitioncoco, MouseX, MouseY, Counter;

	float BulletX, BulletY, AngleX, AngleY, vectorLength, 
		DirectionX, DirectionY, VelocityX, VelocityY, Speed;
	double PI;
};

Bullet.cpp

Code: Select all

#include "Bullet.h"
#include "Player.h"
#include <math.h>

Player P;
Bullet::Bullet()
{
	Clicked=false;
	Speed = 10;
	Counter = -1;
	Amenition = 100;
	PI =3.14159265;
}

Bullet::~Bullet()
{
}

void Bullet::LoadFile(sf::RenderWindow &Game)
{
	Image.LoadFromFile("data/Images/Bullet.png");
}

void Bullet::Init(sf::RenderWindow &Game)
{
	MouseX = Game.GetInput().GetMouseX();
	MouseY = Game.GetInput().GetMouseY();
}

void Bullet::MouseEvent(sf::Event &Event)
{
	Amenitioncoco = Amenition - Counter;
	if(Event.Type == sf::Event::MouseButtonPressed  && Event.MouseButton.Button == sf::Mouse::Left && Amenitioncoco !=0)
	{
		Clicked=true;
		Counter++;
		CreateBullet(Game);
	}
}

void Bullet::SetPosition(sf::RenderWindow &Game)
{
	P.Movement(Game);

	if(Clicked==true)
	{
		for(int i=Counter; i<=Counter; i++)
		{
			Sprite[i].SetImage(Image);
			Sprite[i].SetPosition(P.GetPlayerX(), P.GetPlayerY());
		}
		
		Clicked=false;
	}
}

void Bullet::CreateBullet(sf::RenderWindow &Game)
{
	float ElapsedTime = Game.GetFrameTime()/60;

	if(Counter>=0)
	{
		for(int i=0; i<=Counter; i++)
		{
			BulletX = Sprite[i].GetPosition().x;
			BulletY = Sprite[i].GetPosition().y;
			
			AngleX = MouseX - BulletX;
			AngleY = MouseY - BulletY;

			vectorLength = sqrt(AngleX*AngleX + AngleY*AngleY);

			DirectionX = AngleX / vectorLength;
			DirectionY = AngleY / vectorLength;

			VelocityX = DirectionX * Speed;
			VelocityY = DirectionY * Speed;
		
			Sprite[i].Move (VelocityX , VelocityY );
		}
	}
}

void Bullet::Draw(sf::RenderWindow &Game)
{
	//Display Amo
	std::stringstream out;
	out << "Amo: " << Amenitioncoco;
	std::string myString;
	myString = out.str();
	sf::Unicode::Text myText(myString);
	sf::String Amo (myText, sf::Font::GetDefaultFont(), 15);
	Amo.SetPosition(700,550);
	Game.Draw(Amo);

	if(Counter>=0)
	{
		for(int i=0; i<=Counter; i++)
		{
			Game.Draw(Sprite[i]);
		}
	}
}
User avatar
szdarkhack
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 61
Joined: Fri May 08, 2009 2:31 am

Re: Bullet keep following mouse please Help c++/sfml

Post by szdarkhack »

Ok, let's see. If i understand correctly, when a mouse click occurs, you increase the counter by 1 and create a new bullet. However, if you look at your CreateBullet function, it loops over all the bullets. You only need to setup the new bullet, not change every single one. In fact, you don't seem to be actually creating new bullets (sprites) inside the function at all. Then, confusingly, you have a call to Move() *inside* of CreateBullet. That seems to be the only position update you do on the sprite, thus the "moving only 1 pixel" problem.

I suggest you structure this as follows:

CreateBullet <- Creates a NEW bullet (including sprite) and calculates its velocity. Called on mouseclick.
UpdateBullets <- loops through the existing bullets and updates their positions according to the velocities. Any collision detection you might add later would go here as well.
DrawBullets <- loops through the existing bullets and draws their sprites.

These should be your basic functions. Whenever you want a new bullet (when you click for example), you should call CreateBullet. The functions UpdateBullets and DrawBullets should be called every frame. If you do it this way, make sure that each function does what i listed here. You're not far off, but you need to fix a few things first.
User avatar
Van-B
Chaos Rift Regular
Chaos Rift Regular
Posts: 125
Joined: Tue Aug 10, 2010 7:17 am
Current Project: iPhone puzzle game
Favorite Gaming Platforms: All - Except Amiga
Programming Language of Choice: DBPro, ObjC++
Location: Scotland

Re: Bullet keep following mouse please Help c++/sfml

Post by Van-B »

I'm not sure if your DirectionX etc variables should be private... but that might just be me. I prefer to use STRUCTs, and compile GL meshes based on the struct arrays. That way the variables are easily accesible for other systems, like particle effects for instance that use a struct array.

I think as people have said, you need to update your bullets every loop, then you'll see yourself how it works after that - no point in doing anything else until you get the things moving properly.
Health, ammo.... and bacon and eggs.
Fantasy
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 4
Joined: Mon Dec 19, 2011 5:51 pm

Re: Bullet keep following mouse please Help c++/sfml

Post by Fantasy »

ok thank you guys very much that was very very helpful, and i really really appreciate your help :D
now when i click the mouse the bullet go in that direction :D so now it works.

just one last problem.
the thing is when I click on the mouse the counter get incremented and the bullet get created and move in the correct direction but if i click again the first bullet stops in its position and a new bullet get create and start moving.


i know and understand the problem but i don't know how to fix it.

here is my final code.

Code: Select all


void Bullet::Calculations(sf::RenderWindow &Game)
{
	P.Movement(Game);
	if(Clicked==true)
	{
		for(int i=Counter; i<=Counter; i++)
		{
			MouseX = Game.GetInput().GetMouseX();
			MouseY = Game.GetInput().GetMouseY();

			DistanceX = MouseX - P.GetPlayerX();
			DistanceY = MouseY - P.GetPlayerY();

			AngleRadian = atan2(DistanceY, DistanceX);
			AngleDegree = AngleRadian * 180 / PI;

			BulletX = cos(AngleRadian) * Speed ;
			BulletY = sin(AngleRadian) * Speed ;
		}
		Clicked=false;
		Sprite[Counter].Move (BulletX , BulletY );
	}
	
	std::cout<< " bx" << BulletX << "by " << BulletY;
}
every function is the same as the old code i just created this new function. this function is inside the game loop.
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Bullet keep following mouse please Help c++/sfml

Post by XianForce »

Are you updating ALL of your bullets? Or just the most recently created one?
Fantasy
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 4
Joined: Mon Dec 19, 2011 5:51 pm

Re: Bullet keep following mouse please Help c++/sfml

Post by Fantasy »

XianForce wrote:Are you updating ALL of your bullets? Or just the most recently created one?
I'm updating only recent bullets, because if I update all the bullets every bullet will keep changing its position when i move the mouse.
User avatar
szdarkhack
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 61
Joined: Fri May 08, 2009 2:31 am

Re: Bullet keep following mouse please Help c++/sfml

Post by szdarkhack »

You need to store the velocity of each bullet separately and keep updating all of them, each using its own velocity. So, for example, say you click and create a bullet. You calculate its direction and velocity. Now, for each frame you must update it's position in order for it to keep moving (note that i'm telling you to update the position, NOT the velocity. This bullet's velocity doesn't change once it's first calculated).

Next, you click once more and create one more bullet. Now you calculate its direction and velocity (completely independent of the previous bullet's velocity). Now, for each frame you must update the positions of both bullets, otherwise the bullets that you're not updating will stop moving.

I think the problem is that you're only using one velocity. That is very wrong, each bullet moves independently so each one will need its own velocity.
Post Reply