Sign in to follow this  

My ship fires bullets but they don't move

Recommended Posts

I'm writing an Asteroids clone for my own education. I have classes for Bullet and PlayerShip. The main function created a PlayerShip called playerShip. I can fly this around the screen, all working well. I have made it so that when you fly off the edge you appear on the opposite edge. When you press Space, the PlayerShip's fire() event is called. This creates a Bullet object, passes it position and velocity of the PlayerShip, then returns it to be stored in a List.

 

All this seems to work perfectly, except that I can't get the bullets to move.

I tried with just a single bullet, not in a list - this moved but I could only have 1 bullet :(

 

Any ideas how to get my bullets moving?

Bullet.cpp:

Bullet::Bullet()
{
	bulletShape.setPointCount(4);
	bulletShape.setRadius(2);
	bulletShape.setFillColor(sf::Color::White);
}

sf::Vector2f Bullet::getVelocity()
{
	return velocity;
}
sf::Vector2f Bullet::getPosition()
{
	return bulletShape.getPosition();
}
sf::CircleShape Bullet::getShape()
{
	return bulletShape;
}

void Bullet::setPosition(sf::Vector2f pos)
{
	bulletShape.setPosition(pos);
}
void Bullet::setVelocity(sf::Vector2f vel)
{
	velocity = vel;
}

void Bullet::update()
{
	bulletShape.setPosition(sf::Vector2f(Bullet::getPosition().x + Bullet::getVelocity().x, Bullet::getPosition().y + Bullet::getVelocity().y));
}



PlayerShip.cpp:



#define PI 3.14159265

PlayerShip::PlayerShip(sf::Vector2f position)
{
	size = 20;
	accel = sf::Vector2f(0,0);
	velocity = sf::Vector2f(0,0);

	shipShape.setPointCount(4);
	shipShape.setPoint(0, sf::Vector2f(size / 2, 0));
	shipShape.setPoint(1, sf::Vector2f(size, size));
	shipShape.setPoint(2, sf::Vector2f(size / 2,2 * size / 3));
	shipShape.setPoint(3, sf::Vector2f(0, size));
	

	shipShape.setPosition(position);
	shipShape.setFillColor(sf::Color::Black);
	shipShape.setOutlineThickness(3);
	shipShape.setOutlineColor(sf::Color::White);

	shipShape.setOrigin(sf::Vector2f(size / 2, size * 2 / 3));

	thrustShape.setPointCount(4);
	thrustShape.setPosition(position);
	thrustShape.setPoint(0, sf::Vector2f(size / 2,0));
	thrustShape.setPoint(1, sf::Vector2f(size, size / 4));
	thrustShape.setPoint(2, sf::Vector2f(size / 2, size));
	thrustShape.setPoint(3, sf::Vector2f(0, size / 4));

	thrustShape.setOrigin(sf::Vector2f(size / 2, 0));

	thrustShape.setFillColor(sf::Color::White);
	thrustShape.setOutlineThickness(1);
	thrustShape.setOutlineColor(sf::Color::White);

}
sf::ConvexShape PlayerShip::getThrustShape()
{
	return thrustShape;
}
void PlayerShip::setPosition(sf::Vector2f newPosition)
{
	shipShape.setPosition(newPosition);
	thrustShape.setPosition(newPosition);

}
void PlayerShip::setVelocity(sf::Vector2f newVelocity)
{
	velocity = newVelocity;
}
void PlayerShip::rotate(float angle)
{
	shipShape.rotate(angle);
	thrustShape.rotate(angle);
}
void PlayerShip::thrust(float thrust)
{
	accel = sf::Vector2f(thrust * 0.01 * sin(shipShape.getRotation() * PI / 180), thrust * -0.01 * cos(shipShape.getRotation() * PI / 180));
	velocity += accel;

}
Bullet PlayerShip::fire()
{
	Bullet bullet;
	bullet.setPosition(getPosition());
	bullet.setVelocity(getVelocity());
	return bullet;
}

sf::ConvexShape PlayerShip::getShape()
{
	return shipShape;

}

sf::Vector2f PlayerShip::update()
{
	shipShape.move(velocity);
	thrustShape.move(velocity);
	return velocity;
}

sf::Vector2f PlayerShip::getPosition()
{
	return shipShape.getPosition();
}
float PlayerShip::getRotation()
{
	return shipShape.getRotation();
}
sf::Vector2f PlayerShip::getVelocity()
{
	return velocity;
}


Asteroids.cpp:


int main()
{
	int screenWidth = 800;
	int screenHeight = 600;
	
	// Prepare HUD

	sf::Text hud;
	sf::Font font;
	font.loadFromFile("ComputerFont.ttf");
	hud.setFont(font);
	hud.setCharacterSize(15);
	hud.setFillColor(sf::Color::Cyan);
	




	// Create window
	sf::RenderWindow window(sf::VideoMode(screenWidth, screenHeight), "Asteroids");


	// Create player ship
	PlayerShip playerShip(sf::Vector2f(screenWidth/2, screenHeight/2));

	// List for bullets to populate
	std::vector<Bullet> bullets;


	bool flag = false;



	while (window.isOpen()) // Game Loop
	{

		std::stringstream ss;
		sf::Event event;
		window.clear();

		while (window.pollEvent(event))
		{
			if (event.type == sf::Event::Closed)
				window.close();
		}

		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
		{
			playerShip.rotate(-0.3);
		}
		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
		{
			playerShip.rotate(0.3);
		}
		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
		{
			playerShip.thrust(0.05);
			window.draw(playerShip.getThrustShape());
		}
		else
		{
			playerShip.thrust(0);
		}

		if (sf::Keyboard::isKeyPressed(sf::Keyboard::F1))
		{
			playerShip.setPosition(sf::Vector2f(screenWidth / 2, screenHeight / 2));
			playerShip.setVelocity(sf::Vector2f(0, 0));
			
		}
		if (!flag && sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
		{
			flag = true;
			bullets.push_back(playerShip.fire());
		}
		else if (flag && !sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
		{
			flag = false;
		}

		ss << "pos: " << playerShip.getPosition().x << " , " << playerShip.getPosition().y << "\n";
		ss << "rot: " << playerShip.getRotation() << "\n";
		ss << "vel: " << playerShip.getVelocity().x << " , " << playerShip.getVelocity().y << "\n\n";

		playerShip.update();
		
		for(Bullet bullet : bullets)
		{
			ss << "Pos: " << bullet.getPosition().x << " , " << bullet.getPosition().y << "\n";
			ss << "Vel: " << bullet.getVelocity().x << " , " << bullet.getVelocity().y << "\n\n";
			bullet.update();
			window.draw(bullet.getShape());
		}
		
		hud.setString(ss.str());

		// Keep ship on screen
		if (playerShip.getPosition().x < 0)
		{
			playerShip.setPosition(sf::Vector2f(playerShip.getPosition().x + screenWidth, playerShip.getPosition().y));
		}
		else if (playerShip.getPosition().x > screenWidth)
		{
			playerShip.setPosition(sf::Vector2f(0, playerShip.getPosition().y));
		}
		if (playerShip.getPosition().y < 0)
		{
			playerShip.setPosition(sf::Vector2f(playerShip.getPosition().x, playerShip.getPosition().y + screenHeight));
		}
		else if (playerShip.getPosition().y > screenHeight)
			{
				playerShip.setPosition(sf::Vector2f(playerShip.getPosition().x, 0));
			}
		// ////////////////////

		window.draw(playerShip.getShape());
		window.draw(hud);
		window.display();
	}
	return 0;
}

Obviously I've got the relevant header files too, but don't think I need to include these

 

 

 

I'm using C++ and the SFML library

 

As you can see from the code I've put some debug text in, showing the pos and vel of each bullet. These show that position and velocity are being set.

 

Can anyone help get my bullets moving?? Any help would be much appreciated.

Share this post


Link to post
Share on other sites
for(Bullet bullet : bullets)
{
  ss << "Pos: " << bullet.getPosition().x << " , " << bullet.getPosition().y << "\n";
  ss << "Vel: " << bullet.getVelocity().x << " , " << bullet.getVelocity().y << "\n\n";
  bullet.update();
  window.draw(bullet.getShape());
}

What would happen if that loop used a reference to the elements of the list instead of a copy of the elements?

Share this post


Link to post
Share on other sites

Thanks Bregma, that did the trick

		for(Bullet& bullet : bullets)
		{
			ss << "Pos: " << bullet.getPosition().x << " , " << bullet.getPosition().y << "\n";
			ss << "Vel: " << bullet.getVelocity().x << " , " << bullet.getVelocity().y << "\n\n";
			bullet.update();
			window.draw(bullet.getShape());
		}

Now my bullets move! 

So in the previous version,

        for(Bullet& bullet : bullets)

was creating new bullet objects instead of manipulating the current ones? That explains why they were not moving!
Still getting my head around references yet, this is the first time I've had to use them

 

Thanks again for the solution :) 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this