For context, I have 3 classes: `AsteroidClass`, `RocketClass`, and `Spaceship`. Spaceship is the player controlled spaceship, whilst `AsteroidClass` are the asteroids, and `RocketClass` is the class for all projectiles shot by the player.
Shooting is checked inside the `Spaceship` classes' `Update()` function. When it detects space key pressed, it creates a new `RocketClass` instance and pushes it to the private vector `GlobalRockets`. At the end of the update function, this vector is looped through and individually calls the `Update` function on each `RocketClass` instance, and then drawing it to the window.
However, I never see any projectile rendered. I have tried manually creating a new `RocketClass` instance inside of the `main`
function, calling it's `Update`, then rendering it manually and no problems there. The only issue is rendering it inside of the Player's `Update`. Here is my code:
#include <iostream>
#include <SFML/Graphics.hpp>
#include <cmath>
#include <vector>
enum Turn {
Static,
Glide
};
enum AsteroidType {
Small,
Medium,
Large
};
const int WINDOW_LENGTH = 800;
const int WINDOW_HEIGHT = 600;
class RocketClass {
private:
const double MOVE_SPD=3.5;
double ROTATION_RAD;
const double OUTLINE_THICKNESS=1.5;
const float SIZE=3;
public:
sf::CircleShape Rocket;
RocketClass(sf::Vector2f StartPos, double Rotation){
Rocket.setRadius(SIZE);
Rocket.setFillColor(sf::Color(0, 0, 0, 0));
Rocket.setPosition(StartPos);
Rocket.setRotation(Rotation);
Rocket.setOutlineThickness(OUTLINE_THICKNESS);
ROTATION_RAD = Rotation*180/3.14159265;
}
void Update(double TimeFrame){
Rocket.move(MOVE_SPD*TimeFrame*cos(ROTATION_RAD), MOVE_SPD*TimeFrame*sin(ROTATION_RAD));
if (Rocket.getPosition().y > WINDOW_HEIGHT){
Rocket.setPosition(sf::Vector2f(Rocket.getPosition().x, 0));
}
if (Rocket.getPosition().y < 0){
Rocket.setPosition(sf::Vector2f(Rocket.getPosition().x, WINDOW_HEIGHT));
}
if (Rocket.getPosition().x > WINDOW_LENGTH){
Rocket.setPosition(sf::Vector2f(0, Rocket.getPosition().y));
}
if (Rocket.getPosition().x <0){
Rocket.setPosition(sf::Vector2f(WINDOW_LENGTH, Rocket.getPosition().y));
}
}
};
class AsteroidClass {
private:
double ROTATE_SPD =0.8;
double VELOCITY =70;
double DIRECTION=0;
double SIZE_MULTIP=0.25;
const double OUTLINE_THICKNESS = 1;
AsteroidType Type = AsteroidType::Large;
public:
sf::ConvexShape Asteroid;
AsteroidClass(AsteroidType ConstType){
srand(time(NULL));
Type = ConstType;
switch(Type){
case AsteroidType::Small:
SIZE_MULTIP =3.75;
break;
case AsteroidType::Medium:
SIZE_MULTIP= 6.25;
break;
case AsteroidType::Large:
SIZE_MULTIP=8.75;
break;
}
switch(rand()%2+1){
case 1:
Asteroid.setPointCount(11);
Asteroid.setPoint(0, sf::Vector2f(-2*SIZE_MULTIP, -5*SIZE_MULTIP));
Asteroid.setPoint(1, sf::Vector2f(0*SIZE_MULTIP, -5*SIZE_MULTIP));
Asteroid.setPoint(2, sf::Vector2f(0*SIZE_MULTIP, -4*SIZE_MULTIP));
Asteroid.setPoint(3, sf::Vector2f(2*SIZE_MULTIP, -4*SIZE_MULTIP));
Asteroid.setPoint(4, sf::Vector2f(4*SIZE_MULTIP, -2*SIZE_MULTIP));
Asteroid.setPoint(5, sf::Vector2f(4*SIZE_MULTIP, 2*SIZE_MULTIP));
Asteroid.setPoint(6, sf::Vector2f(2*SIZE_MULTIP, 4*SIZE_MULTIP));
Asteroid.setPoint(7, sf::Vector2f(1*SIZE_MULTIP, 4*SIZE_MULTIP));
Asteroid.setPoint(8, sf::Vector2f(0*SIZE_MULTIP, 3*SIZE_MULTIP));
Asteroid.setPoint(9, sf::Vector2f(-3*SIZE_MULTIP, 3*SIZE_MULTIP));
Asteroid.setPoint(10, sf::Vector2f(-2*SIZE_MULTIP, 2*SIZE_MULTIP));
Asteroid.setPoint(11, sf::Vector2f(-2*SIZE_MULTIP, 1*SIZE_MULTIP));
Asteroid.setPoint(12, sf::Vector2f(-4*SIZE_MULTIP, 0*SIZE_MULTIP));
Asteroid.setPoint(13, sf::Vector2f(-4*SIZE_MULTIP, -4*SIZE_MULTIP));
Asteroid.setPoint(14, sf::Vector2f(-3*SIZE_MULTIP, -4*SIZE_MULTIP));
Asteroid.setPoint(15, sf::Vector2f(-2*SIZE_MULTIP, -5*SIZE_MULTIP));
Asteroid.setOutlineThickness(OUTLINE_THICKNESS);
Asteroid.setPosition(sf::Vector2f(100, 100));
Asteroid.setFillColor(sf::Color(0, 0, 0, 0));
break;
case 2:
Asteroid.setPointCount(17);
Asteroid.setPoint(0, sf::Vector2f(-3*SIZE_MULTIP, -4*SIZE_MULTIP));
Asteroid.setPoint(1, sf::Vector2f(2*SIZE_MULTIP, -4*SIZE_MULTIP));
Asteroid.setPoint(2, sf::Vector2f(2*SIZE_MULTIP, -3*SIZE_MULTIP));
Asteroid.setPoint(3, sf::Vector2f(4*SIZE_MULTIP, -1*SIZE_MULTIP));
Asteroid.setPoint(4, sf::Vector2f(4*SIZE_MULTIP, 2*SIZE_MULTIP));
Asteroid.setPoint(5, sf::Vector2f(3*SIZE_MULTIP, 3*SIZE_MULTIP));
Asteroid.setPoint(6, sf::Vector2f(2*SIZE_MULTIP, 3*SIZE_MULTIP));
Asteroid.setPoint(7, sf::Vector2f(1*SIZE_MULTIP, 4*SIZE_MULTIP));
Asteroid.setPoint(8, sf::Vector2f(-2*SIZE_MULTIP, 4*SIZE_MULTIP));
Asteroid.setPoint(9, sf::Vector2f(-2*SIZE_MULTIP, 3*SIZE_MULTIP));
Asteroid.setPoint(10, sf::Vector2f(-3*SIZE_MULTIP, 3*SIZE_MULTIP));
Asteroid.setPoint(11, sf::Vector2f(-4*SIZE_MULTIP, 2*SIZE_MULTIP));
Asteroid.setPoint(12, sf::Vector2f(-3*SIZE_MULTIP, 1*SIZE_MULTIP));
Asteroid.setPoint(13, sf::Vector2f(-3*SIZE_MULTIP, -1*SIZE_MULTIP));
Asteroid.setPoint(14, sf::Vector2f(-4*SIZE_MULTIP, -2*SIZE_MULTIP));
Asteroid.setPoint(15, sf::Vector2f(-4*SIZE_MULTIP, -3*SIZE_MULTIP));
Asteroid.setPoint(16, sf::Vector2f(-3*SIZE_MULTIP, -4*SIZE_MULTIP));
Asteroid.setOutlineThickness(OUTLINE_THICKNESS);
Asteroid.setPosition(sf::Vector2f(100, 100));
Asteroid.setFillColor(sf::Color(0, 0, 0, 0));
}
}
void Update(double FrameTime){
Asteroid.rotate(ROTATE_SPD);
const int Degrees_Rotation = DIRECTION*180/3.14159265;
Asteroid.move(VELOCITY*FrameTime*cos(Degrees_Rotation), VELOCITY*FrameTime*sin(Degrees_Rotation));
if (Asteroid.getPosition().y > WINDOW_HEIGHT){
Asteroid.setPosition(sf::Vector2f(Asteroid.getPosition().x, 0));
}
if (Asteroid.getPosition().y < 0){
Asteroid.setPosition(sf::Vector2f(Asteroid.getPosition().x, WINDOW_HEIGHT));
}
if (Asteroid.getPosition().x > WINDOW_LENGTH){
Asteroid.setPosition(sf::Vector2f(0, Asteroid.getPosition().y));
}
if (Asteroid.getPosition().x <0){
Asteroid.setPosition(sf::Vector2f(WINDOW_LENGTH, Asteroid.getPosition().y));
}
}
};
class SpaceShip {
private:
std::vector<RocketClass> GlobalRockets = {};
const Turn TURN_TYPE = Turn::Static;
const int OUTLINE_THICKNESS = 1;
const int SIZE_MULTIP=4;
const double ACCELERATION_SPD=0.02;
const double DECELERATION_SPD=0.018;
const double MAX_SPD = 4;
double TURN_SPD=2.5;
const double GLIDE_TURN_SPD = 0.07;
const double MAX_TURN_SPD = 7.5;
double Velocity =0;
double TurnVelocity =0;
double Degrees_Rad = 0;
const double FRAME_TIME_MULTIP=75;
public:
sf::ConvexShape Ship{(5)};
SpaceShip(){
Ship.setPoint(0, sf::Vector2f(4*SIZE_MULTIP, 0));
Ship.setPoint(1, sf::Vector2f(-4*SIZE_MULTIP, -3*SIZE_MULTIP));
Ship.setPoint(2, sf::Vector2f(-2*SIZE_MULTIP, 0));
Ship.setPoint(3, sf::Vector2f(-4*SIZE_MULTIP, 3*SIZE_MULTIP));
Ship.setPoint(4, sf::Vector2f(4*SIZE_MULTIP, 0));
Ship.setOutlineThickness(OUTLINE_THICKNESS);
Ship.setPosition(sf::Vector2f(100, 100));
Ship.setFillColor(sf::Color(0, 0, 0, 0));
if (TURN_TYPE == Turn::Glide){
TURN_SPD = GLIDE_TURN_SPD;
}
}
void Update(double FrameTime, sf::RenderWindow &Window){
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) || sf::Keyboard::isKeyPressed(sf::Keyboard::W)){
Velocity+=ACCELERATION_SPD;
if (Velocity > MAX_SPD){
Velocity = MAX_SPD;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) || sf::Keyboard::isKeyPressed(sf::Keyboard::S)){
Velocity-=DECELERATION_SPD;
if (Velocity < MAX_SPD*-1){
Velocity=MAX_SPD*-1;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right) || sf::Keyboard::isKeyPressed(sf::Keyboard::D)){
TurnVelocity+=TURN_SPD;
if (TurnVelocity >= MAX_TURN_SPD){
TurnVelocity = MAX_TURN_SPD;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Keyboard::isKeyPressed(sf::Keyboard::A)){
TurnVelocity -= TURN_SPD;
if (TurnVelocity <= MAX_TURN_SPD*-1){
TurnVelocity = MAX_TURN_SPD*-1;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)){
RocketClass Projectile(Ship.getPosition(), Ship.getRotation());
GlobalRockets.push_back(Projectile);
}
switch (TURN_TYPE){
case Turn::Static:
Ship.rotate(TurnVelocity*(FrameTime*FRAME_TIME_MULTIP));
TurnVelocity = 0;
break;
case Turn::Glide:
Ship.rotate(TurnVelocity*(FrameTime*FRAME_TIME_MULTIP));
break;
}
Degrees_Rad = Ship.getRotation() *3.14159/180;
Ship.move(sf::Vector2f(Velocity*FrameTime*FRAME_TIME_MULTIP*cos(Degrees_Rad), Velocity*FrameTime*FRAME_TIME_MULTIP*sin(Degrees_Rad)));
if (Ship.getPosition().y > WINDOW_HEIGHT){
Ship.setPosition(sf::Vector2f(Ship.getPosition().x, 0));
}
if (Ship.getPosition().y < 0){
Ship.setPosition(sf::Vector2f(Ship.getPosition().x, WINDOW_HEIGHT));
}
if (Ship.getPosition().x > WINDOW_LENGTH){
Ship.setPosition(sf::Vector2f(0, Ship.getPosition().y));
}
if (Ship.getPosition().x <0){
Ship.setPosition(sf::Vector2f(WINDOW_LENGTH, Ship.getPosition().y));
}
for (int i=0;i<GlobalRockets.size();i++){
GlobalRockets.at(i).Update(FrameTime);
Window.draw(GlobalRockets.at(i).Rocket);
}
}
};
int main(){
const double MAX_FPS = 60;
SpaceShip Player;
AsteroidClass AsteroidInstance(AsteroidType::Large);
sf::RenderWindow Window(sf::VideoMode(WINDOW_LENGTH, WINDOW_HEIGHT), "Asteroids");
sf::Clock FrameTime;
while (Window.isOpen()){
sf::Event Event;
while (Window.pollEvent(Event)){
if (Event.type == sf::Event::Closed){
Window.close();
}
}
if (FrameTime.getElapsedTime().asSeconds() >= 1/MAX_FPS){
Player.Update(FrameTime.getElapsedTime().asSeconds(), Window);
AsteroidInstance.Update(FrameTime.getElapsedTime().asSeconds());
Window.clear();
Window.draw(Player.Ship);
Window.draw(AsteroidInstance.Asteroid);
Window.display();
FrameTime.restart();
}
}
}
I think the main focus is the contents of the `Spaceship` class, however the rest of the code is there for context.