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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - firepro20

Pages: [1] 2
1
Network / Player Movement Interpolation / Prediction
« on: December 05, 2019, 02:16:09 am »
I am currently sending a UDP packet using sf::Packet type for data transmission.

What would be the ideal logic for interpolating between the last two packets received position and the current one? So it will be based on the last three data packets?

At the moment all I have is a send and receive packet on both server and client respectively.

2
Network / Re: Sending multiple packets simultaneously UDP
« on: December 04, 2019, 12:55:42 am »
Got it thanks!

3
Network / Sending multiple packets simultaneously UDP
« on: December 01, 2019, 07:42:52 pm »
Is it possible to send two packets simultaneously in UDP?

Quote
   playerData << playerXPosition << playerYPosition << bulletPtr->isAlive() << bulletPtr->getLocation().x << bulletPtr->getLocation().y;
   bulletData << bulletPtr->isAlive() << bulletPtr->getLocation().x << bulletPtr->getLocation().y;
   socket.send(playerData, sender, port);
   socket.send(bulletData, sender, port);

4
Network / Steaming to a client, ensure shot fired is sent once using UDP
« on: December 01, 2019, 05:32:22 pm »
Is it possible to ensure shot is sent once to a client so it is not created twice or four times when multiple packets are sent?

Quote
if (selector.wait(sf::milliseconds(10.f))) { // not enough time for server to be created with 0.1f

      // received something
      if (selector.isReady(socket)) {

         // Wait for a message
         char in[128];
         std::size_t received; // am I using this?
         sf::IpAddress sender;
         sf::Packet playerData; // playerdata1 //playerdata2
         sf::Packet bulletData;
         float playerXPosition;
         float playerYPosition;
         float clientXPosition;
         float clientYPosition;
         float clientBulletX;
         float clientBulletY;
         bool bulletShot;
         
         
         // third packet
         socket.receive(playerData, sender, port);
         // first packet - interpolate .. create scenario as tutorial

         //socket.receive(bulletData, sender, port);

         if (playerData >> playerXPosition >> playerYPosition >> bulletShot >> clientBulletX >> clientBulletY) { // if you are able to read
            clientXPosition = playerXPosition;
            clientYPosition = playerYPosition;
            

            player->setPosition(clientXPosition, clientYPosition);
            
            if (bulletShot) {
                // - might not need this
               // if not already received
               //bulletPtr->spawn(true); // once bullet spawned, should be taken care of both sides
               //
               bulletPtr->isAlive();
               bulletPtr->setLocation(clientXPosition - 13.f, clientYPosition - 24.f);
               
               //bulletPtr->getSprite().move(0.f, -20);
               //if (!bulletShot)
               //{
               //   std::cout << "Bullet should be dead";
               //   bulletPtr->kill();
               //}
               //else
               // clientbulletx and clientbullety
               
                // client window handled from both client and server what to do if bullet is alive
            }
            if (bulletShot && bulletShot!=NULL) {
               std::cout << "Satisfying both conditions" << std::endl;
               bulletPtr->kill();
            }
            //else {
            //   bulletPtr->spawn(false);
            //}
            
         }

5
General / Re: UDP Packets for Player Position
« on: December 01, 2019, 05:15:15 pm »
Receiving less error messages when timeout check is increased - solved

6
General / Re: UDP code laggy on localhost
« on: December 01, 2019, 05:14:38 pm »
I fixed this by setting wait time out on udp client selector.wait(sf::milliseconds(10.f) and wait time out on server
selector.wait(sf::milliseconds(20.f)

7
General / UDP code laggy on localhost
« on: December 01, 2019, 01:40:27 am »
I am trying to understand why the spaceship moves really jittery on screen on client on same machine using localhost as IP.

This is the code I have, followed by the order of execution -

Quote
void createUdpServer(unsigned short port) { // send data to client
   
   // Create a socket to receive a message from anyone
   sf::UdpSocket socket;
   sf::IpAddress local = sf::IpAddress::getLocalAddress(); // Currently 127.0.0.1 localhost
   sf::IpAddress receiver = sf::IpAddress::getLocalAddress();
   
   socket.setBlocking(false);
   // I was figuring out and arranging according to example.. set socket non blocking

   // Listen to messages on the specified port
   if (socket.bind(port) != sf::Socket::Done && !portBound) // You bind once
      return; // error
   else {
      portBound = true;
   }
   std::cout << "Server is listening to port " << port << ", waiting for a connection... " << std::endl;
   
   // Wait for a message
   char in[128];
   std::size_t received;
   sf::IpAddress sender;
   //unsigned short senderPort; we will be receiving and sending data on sa,e port
   
   sf::SocketSelector selector;
   selector.add(socket);

   if (selector.wait(sf::milliseconds(10.f))) { // times out after 10ms
      if (selector.isReady(socket)) {
         if (socket.receive(in, sizeof(in), received, sender, port) != sf::Socket::Done) // blocking
            return;
         std::cout << "Message received from client " << sender << ": \"" << in << "\"" << std::endl;
      }
   }
   
   // Sends connection established to client
   /*
   const char out[] = "Connection with server established!";
   if (socket.send(out, sizeof(out), sender, port) != sf::Socket::Done)
      return;
   */
   // acknowledgement of packets
   float playerXPosition = player->getPosition().x;
   float playerYPosition = player->getPosition().y;
   sf::Packet playerData;
   sf::Packet bulletData;
   playerData << playerXPosition << playerYPosition << bulletPtr->isAlive() << bulletPtr->getLocation().x << bulletPtr->getLocation().y;
   //bulletData << bulletPtr->isAlive() << bulletPtr->getLocation().x << bulletPtr->getLocation().y;
   socket.send(playerData, sender, port);
   //socket.send(bulletData, sender, port);
   //const char out[] = "";
   //if (socket.send(out, sizeof(out), sender, port) != sf::Socket::Done)
   //   return;
   
}

void runUdpClient(unsigned short port) { // receive data from server

   // Ask for the server address
   server = "127.0.0.1";
   /*
   if (server == sf::IpAddress::None)
   do
   {
      std::cout << "Type the address or name of the server to connect to: ";
      std::cin >> server;
      
   } while (server != sf::IpAddress::None);
   */
   // Create a socket for communicating with the server
   sf::UdpSocket socket;

   sf::IpAddress recipient = sf::IpAddress::getLocalAddress();
   char data[100] = "Connection with client established!";

   if (socket.send(data, 100, server, port) != sf::Socket::Done && !sendInitialToServer) // if send once dont't send again
   {
      // added up top send this only once
      // error...
   }
   else{
      sendInitialToServer = true;
   }
   
   // Think about putting this globally
   sf::SocketSelector selector;
   selector.add(socket);
   
   if (selector.wait(sf::milliseconds(10.f))) { // not enough time for server to be created with 0.1f

      // received something
      if (selector.isReady(socket)) {

         // Wait for a message
         char in[128];
         std::size_t received; // am I using this?
         sf::IpAddress sender;
         sf::Packet playerData;
         sf::Packet bulletData;
         float playerXPosition;
         float playerYPosition;
         float clientXPosition;
         float clientYPosition;
         float clientBulletX;
         float clientBulletY;
         bool bulletShot;
         
         socket.receive(playerData, sender, port);
         //socket.receive(bulletData, sender, port);

         if (playerData >> playerXPosition >> playerYPosition >> bulletShot >> clientBulletX >> clientBulletY) { // if you are able to read
            clientXPosition = playerXPosition;
            clientYPosition = playerYPosition;
            
            player->setPosition(clientXPosition, clientYPosition);
            if (bulletShot) {
                // - might not need this
               bulletPtr->spawn(true); // once bullet spawned, should be taken care of both sides
               //
               bulletPtr->setLocation(clientXPosition - 13.f, clientYPosition - 24.f);
               if (!bulletPtr->isAlive())
               {
                  bulletPtr->kill();
               }
               //else
               // clientbulletx and clientbullety

               //bulletPtr->draw(window); // client window handled from both client and server what to do if bullet is alive
            }
            
         }

         /*
         if (bulletData >> bulletShot >> clientBulletX >> clientBulletY) {
            if (bulletShot) {
               bulletPtr->spawn(true); // once bullet spawned, should be taken care of both sides
               bulletPtr->setLocation(player->getPosition().x - 13.f, player->getPosition().y - 24.f);
                              
               //bulletPtr->draw(window); // client window handled from both client and server what to do if bullet is alive
            }
         }*/
         else {
            // Handle error / packet loss // else simulate?
            std::cout << "Error - failed to read from player data packet!" << std::endl; // this is normal when packet is lost
            // I think I am getting several packet drops as I am receiving and sending from the same PC same port, localhost
         }
         
         //unsigned short senderPort;
         //if (socket.receive(in, sizeof(in), received, sender, port) != sf::Socket::Done)
         //   return;
         //std::cout << "Message received from server " << sender << ": \"" << in << "\"" << std::endl;
      }
      // this shouldn't be here, receive stuff should go on client, server just sends
   }
   else {

      // timeout reached, nothing was received

   }
   // prediction
   // bullet

}

Order of Execution from main -

Quote
   while (window.isOpen())
   {
      
      if (userChoice == NULL){
         do {

            std::cout << "User Choice - " << userChoice << std::endl;
            std::cout << "Server or client? (s/c)" << std::endl;
            std::cin >> userChoice;
            
         } while (userChoice != 's' && userChoice != 'c');
         // The game clock will keep on restarting until the user makes a decision
         clock.restart(); // This solved issue to start movements and updates at same time once user chooses an option
      }
      if (userChoice == 's' || userChoice == 'c') { // start of main if  // else start the whole program
         
         // game time over here once game starts // frame independent

         // Binding of ports for both client or server
         /*

         // bind the socket to a port
         if (socket.bind(54000) != sf::Socket::Done)
         {
            // Using UDP starts listening on this port
            // whatever happens, bind for both -> will work with two executables running on same network with two different local IPs
         }

         */

         // Puts the time counter back to zero and also returns the time elapsed since the clock was started
         sf::Time deltaTime = clock.restart();
         timeSinceLastUpdate += deltaTime;
         while (timeSinceLastUpdate > TimePerFrame) // fixed time steps // userchoice != NULL otherwise it will start immeadiately
         {
            timeSinceLastUpdate -= TimePerFrame; // solves problem with variable delta time, each frame is unique

            processEvents(window);
            //update(TimePerFrame);

            // Start of if server
            if (userChoice == 's'){

               //if(!serverCreated){ // if problems of continous connection, this needs to place outside of bind
                  // create connection
                  createUdpServer(SERVER_PORT); // over here its happening every frame
                  //serverCreated = true; // is server actually created though?
               //}

               // Player 1 movement
               sf::Vector2f movement(0.f, 0.f);
               if (mIsMovingUp)
                  movement.y -= playerSpeed;
               if (mIsMovingDown)
                  movement.y += playerSpeed;
               if (mIsMovingLeft)
                  movement.x -= playerSpeed;
               if (mIsMovingRight)
                  movement.x += playerSpeed;
               // shooting logic
               if (mIsShooting) {
                  if (!bullet.isAlive()) // && !gameOver
                  {
                     bullet.spawn(true);
                     bullet.setLocation(mPlayer.getPosition().x - 13.f, mPlayer.getPosition().y - 24.f); // mPlayer.getPosition().x + 24 (offset) if origin is not set to center
                  }
               }
         
               // ** These two parts need to be put in an if statement, if server, direct movement, if client, move needs to happen with data received
               // from server (Server - main player streamer; Client - viewer)

               // Possibly this will be the data that needs to be sent to server
               mPlayer.move(movement * TimePerFrame.asSeconds()); // Time.deltaTime frame independent movement

               // for each player eventually
               screenBound(mPlayer);
               // screenbound enemies or else check that they do not go off bounds and change direction

               // **

            } // end of if server
            else {
               // Handle control through incoming network data
               // vector x = datacoming in
               // Hypothetically mPlayer.move(data coming in);

               // bullet spawn
               // setlocation from data packet
               
               runUdpClient(SERVER_PORT);
            }

            // Enemy Behaviour // Ideally move to separate method

            sf::Vector2f enemyMovement(1.f, 0.f);
            float yOffset = 30.f;
            float xOffset = 60.f;
            // Be careful with iterators as when deleting it will automatically jump to the next item in vector
            for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) // CAUTION & solved everything again - lesson in C++, if we don't get address, we always create a copy and modify it, which is not what we want
            {
               //std::cout << "Direction before working move " << direction << std::endl;
               i->getSprite().move(enemyMovement * direction); // Issue detected direction only changing sign if greater or less than screen bounds once
               if (i->getSprite().getPosition().x + i->getSprite().getLocalBounds().width / 2 > game->getWindowWidth() ||
                  i->getSprite().getPosition().x - i->getSprite().getLocalBounds().width / 2 < game->getWindowWidth() - game->getWindowWidth()) { // this will be 0
                  direction = -(direction);
                  // Time stamp over here for network calculations
                  //std::cout << "Direction inside if statement " << direction << std::endl;
                  // another for loop move all down by yOffset
                  for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
                     i->getSprite().setPosition(i->getSprite().getPosition().x, i->getSprite().getPosition().y + yOffset);
                     //enemy.move(0.f, enemy.getPosition().y + yOffset);
                  }
                  //enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset); // y axis is inverted in SFML
                  //return 0; // move to separate method
               }

               // This takes care of everything on both sides
               if ((i->getSprite().getPosition().y > game->getWindowHeight() - mPlayer.getLocalBounds().height)) {
                  //removeEnemy(enemy);
                  // ALIVE is false, then draw based on whether alien is alive or not
                  std::cout << "Everyone should be dead game over!" << std::endl;
                  return 0; // change state to paused
               }
            }
         }

         updateStatistics(deltaTime, mStatisticsText);
            
         // ** Start of if server
         if (userChoice == 's'){
            for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
         
               // Test player and alien collision
               if (CollisionManager::collidesWith(mPlayer, *i) && i->isAlive()) { // *i it points to the enemy, and will give me an enemy
                  std::cout << "You're dead!" << std::endl;
                  mPlayerIsAlive = false;
                  
                  return 0; //-> I'm dead gameOver = true;
               }

               // Test collision between bullets and aliens
               if (CollisionManager::collidesWith(bullet, *i) && i->isAlive())
               {
                  i->kill();
                  //enemyList->erase(i); // issue here, we are trying to do this in order to get rid of rendering problems .. shit just move it out of way
                  //i->setLocation(700.f, 10.f);
                  bullet.kill();
                  bullet.setLocation(700.f, 0.f); // temporary solution for dealing with not actually killing but stop drawing bullet
                  // without above line, the bullet will not be drawn but still exist on screen
               }
         
               /*
               v.erase(std::remove_if(v.begin(), v.end(), //erase returns it, so it = erase
                  [](int i) { return i < 10; }), v.end());
               */
            }
         }
         // ** end of if server

         int deadEnemies = 0;
         for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
         
            if (!(i->isAlive())) {
               deadEnemies++;
            }
            if (deadEnemies >= NUMBER_OF_ALIENS) {
               std::cout << "You win!" << std::endl;
               
               
               return 0; // Set state win
            }
         
         }
         //std::cout << "Total Dead Enemies - " << deadEnemies << std::endl;

         //for (Enemy& enemy : enemyList) {
         //   if (enemy.isAlive()) {
         //      enemy.draw(window);
         //   }
         //}

         //enemy.render(alienArray, mWindow);
         /*
         for (int i = 0; i < mEnemies.size(); i++)
         {
            sf::Sprite temp = mEnemies.at(i);
            mWindow.draw(temp);
         }
         */

         // Render All
         // Remember draw order is important
         window.clear();
         window.draw(mBackground);
         window.draw(mPlayer);
         window.draw(mStatisticsText);


         for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
            if (i->isAlive()) {
               i->draw(window);
               //std::cout << "Enemy " << i->getID() << " position - " << i->getLocation().x << " " << i->getLocation().y << std::endl;
            }
         }

         if (bullet.isAlive()) // && !gameOver // for game state and win / lose screen representation
         {
            //draw bullet
            bullet.draw(window);
            //move bullet
            bullet.getSprite().move(0.f, -20);
         }

         //test collision with bullet and boundary
         if (bullet.getSprite().getPosition().y < 0)
            bullet.kill();

         window.display();
      } // end of main second if
   }

   return 0;
}

8
General / Re: UDP Packets for Player Position
« on: November 30, 2019, 05:37:30 pm »
Update, code actually works as when I move spaceship I also see spaceship move on the client.

I do not understand why I keep seeing the error that it failed to read from player data  packet.

Is this because there is not data to read? No data is being sent? I am sending data constantly from the other server/ player controlled spaceship as you can see from the first method

9
General / UDP Packets for Player Position
« on: November 30, 2019, 05:11:25 pm »
I am currently working on SpaceInvaders with the ability for a second executable to act as client as watch me play.

I am following tutorials and documentation online to get UDP packets working to send positional updates for my spaceship. I am getting the error failed to read from player data packet! when client connects. This is what I have so far -

Quote
void createUdpServer(unsigned short port) { // send data to client
   
   // Create a socket to receive a message from anyone
   sf::UdpSocket socket;
   sf::IpAddress local = sf::IpAddress::getLocalAddress(); // Currently 127.0.0.1 localhost
   sf::IpAddress receiver = sf::IpAddress::getLocalAddress();
   
   socket.setBlocking(false);
   // I was figuring out and arranging according to example.. set socket non blocking

   // Listen to messages on the specified port
   if (socket.bind(port) != sf::Socket::Done) // You bind once
      return;
   std::cout << "Server is listening to port " << port << ", waiting for a connection... " << std::endl;
   
   // Wait for a message
   char in[128];
   std::size_t received;
   sf::IpAddress sender;
   //unsigned short senderPort; we will be receiving and sending data on sa,e port
   
   sf::SocketSelector selector;
   selector.add(socket);

   if (selector.wait(sf::milliseconds(10.f))) { // times out after 10ms
      if (selector.isReady(socket)) {
         if (socket.receive(in, sizeof(in), received, sender, port) != sf::Socket::Done) // blocking
            return;
         std::cout << "Message received from client " << sender << ": \"" << in << "\"" << std::endl;
      }
   }
   
   // Sends connection established to client
   /*
   const char out[] = "Connection with server established!";
   if (socket.send(out, sizeof(out), sender, port) != sf::Socket::Done)
      return;
   */
   // acknowledgement of packets
   float playerXPosition = player->getPosition().x;
   float playerYPosition = player->getPosition().y;
   sf::Packet playerData;
   playerData << playerXPosition << playerYPosition;

   socket.send(playerData, sender, port);

   //const char out[] = "";
   //if (socket.send(out, sizeof(out), sender, port) != sf::Socket::Done)
   //   return;
   
}

void runUdpClient(unsigned short port) { // receive data from server

   // Ask for the server address
   server = "127.0.0.1";
   /*
   if (server == sf::IpAddress::None)
   do
   {
      std::cout << "Type the address or name of the server to connect to: ";
      std::cin >> server;
      
   } while (server != sf::IpAddress::None);
   */
   // Create a socket for communicating with the server
   sf::UdpSocket socket;

   sf::IpAddress recipient = sf::IpAddress::getLocalAddress();
   char data[100] = "Connection with client established!";

   if (socket.send(data, 100, server, port) != sf::Socket::Done)
   {
      // error...
   }

   // Think about putting this globally
   sf::SocketSelector selector;
   selector.add(socket);

   if (selector.wait(sf::seconds(0.1f))) { // not enough time for server to be created with 0.1f

      // received something
      if (selector.isReady(socket)) {

         // Wait for a message
         char in[128];
         std::size_t received;
         sf::IpAddress sender;
         sf::Packet playerData;
         float playerXPosition;
         float playerYPosition;
         socket.receive(playerData, sender, port);
         if (playerData >> playerXPosition && playerData >> playerYPosition) { // if you are able to read
            player->setPosition(playerXPosition, playerYPosition);
         }
         else {
            std::cout << "Error - failed to read from player data packet!" << std::endl;
         }
         //unsigned short senderPort;
         //if (socket.receive(in, sizeof(in), received, sender, port) != sf::Socket::Done)
         //   return;
         //std::cout << "Message received from server " << sender << ": \"" << in << "\"" << std::endl;
      }
      // this shouldn't be here, receive stuff should go on client, server just sends
   }
   else {

      // timeout reached, nothing was received

   }
   // prediction
   // bullet

}

I am instancing the player in both client and server. The position of the player is controlled by the keyboard, in client it should receive updates from the server and move accordingly from x and y values.

10
Solved the issue by continously resetting the clock until a user chooses an option -

Quote
if (userChoice == NULL){
         do {

            std::cout << "User Choice - " << userChoice << std::endl;
            std::cout << "Server or client? (s/c)" << std::endl;
            std::cin >> userChoice;
            
         } while (userChoice != 's' && userChoice != 'c');
         // The game clock will keep on restarting until the user makes a decision
         clock.restart(); // This solved issue to start movements and updates at same time once user chooses an option
      }

11
I am trying to create the possibility to play the game and for the same solution/app to be able to connect to a player to watch them play.

I will be using TCP to establish connection and UDP to send updates on the following -

1. Player Position
2. Enemy Position (based on synchronous game time since pattern is predictable)
3. Bullet Position

At the moment I have the following code, if server you have full control and can play the game, if viewer/client so far you can only see, still need to implement netcode.

Quote
int main()
{
   sf::Texture            mPlayerTexture;
   sf::Sprite            mPlayer;
   sf::Texture            mBackgroundTexture;
   sf::Sprite            mBackground;
   
   Bullet bullet(0, bulletSpeed);

   sf::RenderWindow window(sf::VideoMode(game->getWindowWidth(), game->getWindowHeight()), "SFML Application");
   //static const sf::Time   TimePerFrame;
   window.setVerticalSyncEnabled(true);
   //window.setFramerateLimit(60); // Added this

   if (!mPlayerTexture.loadFromFile("Media/Textures/PixelSpaceships/blue_01.png"))
   {
      // Handle loading error
   }
   if (!mBackgroundTexture.loadFromFile("Media/Textures/Space.jpg")) {
      // Handle loading error
   }
   
   // Set Texture and Position for Background
   mBackground.setTexture(mBackgroundTexture);
   mBackground.setOrigin(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);
   mBackground.setPosition(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);

   // Set Texture and Position for Player
   mPlayer.setTexture(mPlayerTexture);
   mPlayer.setOrigin(24.f, 24.f);
   mPlayer.setPosition(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);

   //enemy.enemyInstantiator(2, 100.f, 50.f);
   //enemyInstantiator(10, 100.f, 150.f);

   // Statistics Initialisation
   sf::Font            mFont;
   sf::Text            mStatisticsText;
   mFont.loadFromFile("Media/Sansation.ttf");
   mStatisticsText.setFont(mFont);
   mStatisticsText.setPosition(5.f, 5.f);
   mStatisticsText.setCharacterSize(10);

   // Enemy Creation // Separate method in main
      
   std::vector<Enemy> *enemyList = new std::vector<Enemy>();
   float xPosition = 100.f;
   float yPosition = 50.f;
   float yOffset = 50.f;
   float xOffset = 60.f;
   
   // New Original Instantiator
      
   for (int i = 0; i < NUMBER_OF_ALIENS; i++) {
      Enemy alien(i, enemySpeed);
      alien.getSprite().setOrigin(24.f, 24.f);
      alien.setLocation(xPosition + (i * xOffset), yPosition);
      alien.getSprite().setRotation(180.f);
      enemyList->push_back(alien);

      //std::cout << "I have " << enemyList->size() << " spaceships" << std::endl;
   }
   //std::cout << "I have " << enemyList->size() << " spaceships";
   
   // Enemy creation with rows
   /*
   int tracker = 0;

   for (int i = 0; i < NUMBER_OF_ALIENS; i++) {
      Enemy alien(i, enemySpeed);
      alien.getSprite().setOrigin(24.f, 24.f);
      alien.getSprite().setPosition(xPosition + (i * xOffset), yPosition);
      alien.getSprite().setRotation(180.f);
      if (i >= NUMBER_OF_ALIENS / 2) {
         // set position for remainder, problem is that every loop is overiding position and drawing last batch of 5
         for (int j = 0; j < NUMBER_OF_ALIENS / 2; j++) {
            
            alien.getSprite().setOrigin(24.f, 24.f);
            alien.getSprite().setPosition(xPosition + (j * xOffset), yPosition + yOffset);
            alien.getSprite().setRotation(180.f);
            //std::cout << "Enemy inside 2nd for loop position " << tempEnemy.getPosition().x << " " << tempEnemy.getPosition().y << std::endl;
            // we were not pushing each and every tempEnemy but only the last one when exiting the for loop, therefore we were only printing the last one
            enemyList->push_back(alien);
            tracker++;
            if (tracker >= NUMBER_OF_ALIENS / 2) {
               break;
            }
         }
      }
      //std::cout << "Enemy inside 1st for loop position " << tempEnemy.getPosition().x << " " << tempEnemy.getPosition().y << std::endl;
      enemyList->push_back(alien);
   }
   */

   /*
   //create a an array of enemys
   Enemy alienArray = new Enemy[];
   for (int i = 0; i < NUMBER_OF_ALIENS; i++)
   {
      Enemy alien(i, enemySpeed);

      alien.setLocation(i * 50.f + 50.f, alien.getSprite().getGlobalBounds().height / 2);
      alienArray;
   }
   */

   //game->run();

   // Measure elapsed time
   sf::Clock clock;
   sf::Time timeSinceLastUpdate = sf::Time::Zero;
   // Measure time to reach end of screen
   sf::Clock gameTime;
   sf::Time timeToHitEdge;
   char userChoice = NULL;

   // something here or within the window is open needs to happen to select whether to view or play
   // menu needs to happen over here or within

   while (window.isOpen())
   {
      
      if (userChoice == NULL){
         do {

            std::cout << "User Choice - " << userChoice << std::endl;
            std::cout << "Server or client? (s/c)" << std::endl;
            std::cin >> userChoice;
            
         } while (userChoice != 's' && userChoice != 'c');
         //system("pause");
      }
      if (userChoice == 's' || userChoice == 'c') { // start of main if  // else start the whole program
                  
         // Puts the time counter back to zero and also returns the time elapsed since the clock was started
         sf::Time deltaTime = clock.restart();
         timeSinceLastUpdate += deltaTime;
         while (timeSinceLastUpdate > TimePerFrame) // fixed time steps // userchoice != NULL otherwise it will start immeadiately
         {
            timeSinceLastUpdate -= TimePerFrame; // solves problem with variable delta time, each frame is unique

            processEvents(window);
            //update(TimePerFrame);

            // Start of if server
            if (userChoice == 's'){

               // Player 1 movement
               sf::Vector2f movement(0.f, 0.f);
               if (mIsMovingUp)
                  movement.y -= playerSpeed;
               if (mIsMovingDown)
                  movement.y += playerSpeed;
               if (mIsMovingLeft)
                  movement.x -= playerSpeed;
               if (mIsMovingRight)
                  movement.x += playerSpeed;
               // shooting logic
               if (mIsShooting) {
                  if (!bullet.isAlive()) // && !gameOver
                  {
                     bullet.spawn(true);
                     bullet.setLocation(mPlayer.getPosition().x - 13.f, mPlayer.getPosition().y - 24.f); // mPlayer.getPosition().x + 24 (offset) if origin is not set to center
                  }
               }
         
               // ** These two parts need to be put in an if statement, if server, direct movement, if client, move needs to happen with data received
               // from server (Server - main player streamer; Client - viewer)

               // Possibly this will be the data that needs to be sent to server
               mPlayer.move(movement * TimePerFrame.asSeconds()); // Time.deltaTime frame independent movement

               // for each player eventually
               screenBound(mPlayer);
               // screenbound enemies or else check that they do not go off bounds and change direction

               // **

            } // end of if server
            else {
               // Handle control through incoming network data
               // vector x = datacoming in
               // Hypothetically mPlayer.move(data coming in);

               // bullet spawn
               // setlocation from data packet
            }

            // Enemy Behaviour // Ideally move to separate method

            sf::Vector2f enemyMovement(1.f, 0.f);
            float yOffset = 30.f;
            float xOffset = 60.f;
            // Be careful with iterators as when deleting it will automatically jump to the next item in vector
            for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) // CAUTION & solved everything again - lesson in C++, if we don't get address, we always create a copy and modify it, which is not what we want
            {
               //std::cout << "Direction before working move " << direction << std::endl;
               i->getSprite().move(enemyMovement * direction); // Issue detected direction only changing sign if greater or less than screen bounds once
               if (i->getSprite().getPosition().x + i->getSprite().getLocalBounds().width / 2 > game->getWindowWidth() ||
                  i->getSprite().getPosition().x - i->getSprite().getLocalBounds().width / 2 < game->getWindowWidth() - game->getWindowWidth()) { // this will be 0
                  direction = -(direction);
                  // Time stamp over here for network calculations
                  //std::cout << "Direction inside if statement " << direction << std::endl;
                  // another for loop move all down by yOffset
                  for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
                     i->getSprite().setPosition(i->getSprite().getPosition().x, i->getSprite().getPosition().y + yOffset);
                     //enemy.move(0.f, enemy.getPosition().y + yOffset);
                  }
                  //enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset); // y axis is inverted in SFML
                  //return 0; // move to separate method
               }

               // This takes care of everything on both sides
               if ((i->getSprite().getPosition().y > game->getWindowHeight() - mPlayer.getLocalBounds().height)) {
                  //removeEnemy(enemy);
                  // ALIVE is false, then draw based on whether alien is alive or not
                  std::cout << "Everyone should be dead game over!" << std::endl;
                  return 0; // change state to paused
               }
            }
         }

         updateStatistics(deltaTime, mStatisticsText);
            
         // ** Start of if server
         if (userChoice == 's'){
            for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
         
               // Test player and alien collision
               if (CollisionManager::collidesWith(mPlayer, *i) && i->isAlive()) { // *i it points to the enemy, and will give me an enemy
                  std::cout << "You're dead!" << std::endl;
                  mPlayerIsAlive = false;
                  return 0; //-> I'm dead gameOver = true;
               }

               // Test collision between bullets and aliens
               if (CollisionManager::collidesWith(bullet, *i) && i->isAlive())
               {
                  i->kill();
                  //enemyList->erase(i); // issue here, we are trying to do this in order to get rid of rendering problems .. shit just move it out of way
                  //i->setLocation(700.f, 10.f);
                  bullet.kill();
                  bullet.setLocation(700.f, 0.f); // temporary solution for dealing with not actually killing but stop drawing bullet
                  // without above line, the bullet will not be drawn but still exist on screen
               }
         
               /*
               v.erase(std::remove_if(v.begin(), v.end(),
                  [](int i) { return i < 10; }), v.end());
               */
            }
         }
         // ** end of if server

         int deadEnemies = 0;
         for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
         
            if (!(i->isAlive())) {
               deadEnemies++;
            }
            if (deadEnemies >= NUMBER_OF_ALIENS) {
               std::cout << "You win!" << std::endl;
               return 0; // Set state win
            }
         
         }
         std::cout << "Total Dead Enemies - " << deadEnemies << std::endl;

         //for (Enemy& enemy : enemyList) {
         //   if (enemy.isAlive()) {
         //      enemy.draw(window);
         //   }
         //}

         //enemy.render(alienArray, mWindow);
         /*
         for (int i = 0; i < mEnemies.size(); i++)
         {
            sf::Sprite temp = mEnemies.at(i);
            mWindow.draw(temp);
         }
         */

         // Render All
         // Remember draw order is important
         window.clear();
         window.draw(mBackground);
         window.draw(mPlayer);
         window.draw(mStatisticsText);


         for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
            if (i->isAlive()) {
               i->draw(window);
               std::cout << "Enemy " << i->getID() << " position - " << i->getLocation().x << " " << i->getLocation().y << std::endl;
            }
         }

         if (bullet.isAlive()) // && !gameOver // for game state and win / lose screen representation
         {
            //draw bullet
            bullet.draw(window);
            //move bullet
            bullet.getSprite().move(0.f, -20);
         }

         //test collision with bullet and boundary
         if (bullet.getSprite().getPosition().y < 0)
            bullet.kill();

         window.display();
      } // end of main second if
   }

   return 0;
}

The issue I have is that if user takes x seconds to select an option, the game in the background would have already started and enemy movement would have been running in the background.

This creates an issue were once the player/viewer goes to the main game, the enemies are shown in the current position in time instead of the start position, i.e. when the game starts enemies should be at the top.

I know that the issue is related to timeSinceLastUpdate > TimePerFrame, as probably this will be far greater when actually starting the game.

In the screenshot I left the game running for 10 seconds before selecting an option. Enemies should be at the very top on start, however at the moment this is not the case.

12
I am currently using for loops to check and display sprites in my game. The game feels laggy sometimes, I believe this is mostly due to amount of for loops I am using. I'm new to C++, what are the possibilities in this case?

Quote
int main()
{
   sf::Texture            mPlayerTexture;
   sf::Sprite            mPlayer;
   sf::Texture            mBackgroundTexture;
   sf::Sprite            mBackground;
   
   

   Bullet bullet(0, bulletSpeed);

   sf::RenderWindow window(sf::VideoMode(game->getWindowWidth(), game->getWindowHeight()), "SFML Application");
   //static const sf::Time   TimePerFrame;
   window.setVerticalSyncEnabled(true);
   //window.setFramerateLimit(60); // Added this

   if (!mPlayerTexture.loadFromFile("Media/Textures/PixelSpaceships/blue_01.png"))
   {
      // Handle loading error
   }
   if (!mBackgroundTexture.loadFromFile("Media/Textures/Space.jpg")) {
      // Handle loading error
   }
   
   // Set Texture and Position for Background
   mBackground.setTexture(mBackgroundTexture);
   mBackground.setOrigin(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);
   mBackground.setPosition(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);

   // Set Texture and Position for Player
   mPlayer.setTexture(mPlayerTexture);
   mPlayer.setOrigin(24.f, 24.f);
   mPlayer.setPosition(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);

   //enemy.enemyInstantiator(2, 100.f, 50.f);
   //enemyInstantiator(10, 100.f, 150.f);

   // Statistics Initialisation
   sf::Font            mFont;
   sf::Text            mStatisticsText;
   mFont.loadFromFile("Media/Sansation.ttf");
   mStatisticsText.setFont(mFont);
   mStatisticsText.setPosition(5.f, 5.f);
   mStatisticsText.setCharacterSize(10);

   // Enemy Creation // Separate method in main
      
   std::vector<Enemy> *enemyList = new std::vector<Enemy>();
   float xPosition = 100.f;
   float yPosition = 50.f;
   float yOffset = 50.f;
   float xOffset = 60.f;
   for (int i = 0; i < NUMBER_OF_ALIENS; i++) {
      Enemy alien(i, enemySpeed);
      alien.getSprite().setOrigin(24.f, 24.f);
      alien.setLocation(xPosition + (i * xOffset), yPosition);
      alien.getSprite().setRotation(180.f);
      enemyList->push_back(alien);

      //std::cout << "I have " << enemyList->size() << " spaceships" << std::endl;
   }
   //std::cout << "I have " << enemyList->size() << " spaceships";

   /*
   //create a an array of enemys
   Enemy alienArray = new Enemy[];
   for (int i = 0; i < NUMBER_OF_ALIENS; i++)
   {
      Enemy alien(i, enemySpeed);

      alien.setLocation(i * 50.f + 50.f, alien.getSprite().getGlobalBounds().height / 2);
      alienArray;
   }
   */

   //game->run();

   // Measure elapsed time
   sf::Clock clock;
   sf::Time timeSinceLastUpdate = sf::Time::Zero;

   // something here or within the window is open needs to happen to select whether to view or play
   // menu needs to happen over here or within

   while (window.isOpen())
   {
      // Puts the time counter back to zero and also returns the time elapsed since the clock was started
      sf::Time deltaTime = clock.restart();
      timeSinceLastUpdate += deltaTime;
      while (timeSinceLastUpdate > TimePerFrame) // fixed time steps
      {
         timeSinceLastUpdate -= TimePerFrame; // solves problem with variable delta time, each frame is unique

         processEvents(window);
         //update(TimePerFrame);

         // Player 1 movement
         sf::Vector2f movement(0.f, 0.f);
         if (mIsMovingUp)
            movement.y -= playerSpeed;
         if (mIsMovingDown)
            movement.y += playerSpeed;
         if (mIsMovingLeft)
            movement.x -= playerSpeed;
         if (mIsMovingRight)
            movement.x += playerSpeed;
         if (mIsShooting) {
            if (!bullet.isAlive()) // && !gameOver
            {
               bullet.spawn(true);
               bullet.setLocation(mPlayer.getPosition().x - 13.f, mPlayer.getPosition().y - 24.f); // mPlayer.getPosition().x + 24 (offset) if origin is not set to center
            }
         }
         // shooting logic


         // Possibly this will be the data that needs to be sent to server
         mPlayer.move(movement * TimePerFrame.asSeconds()); // Time.deltaTime frame independent movement

         // for each player eventually
         screenBound(mPlayer);
         // screenbound enemies or else check that they do not go off bounds and change direction

         // Enemy Behaviour // Move to separate method

         sf::Vector2f enemyMovement(1.f, 0.f);
         float yOffset = 50.f;
         float xOffset = 60.f;
         // Be careful with iterators as when deleting it will automatically jump to the next item in vector
         for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) // CAUTION & solved everything again - lesson in C++, if we don't get address, we always create a copy and modify it, which is not what we want
         {
            std::cout << "Direction before working move " << direction << std::endl;
            i->getSprite().move(enemyMovement * direction); // Issue detected direction only changing sign if greater or less than screen bounds once
            if (i->getSprite().getPosition().x + i->getSprite().getLocalBounds().width / 2 > game->getWindowWidth() ||
               i->getSprite().getPosition().x - i->getSprite().getLocalBounds().width / 2 < game->getWindowWidth() - game->getWindowWidth()) { // this will be 0
               direction = -(direction);

               std::cout << "Direction inside if statement " << direction << std::endl;
               // another for loop move all down by yOffset
               for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
                  i->getSprite().setPosition(i->getSprite().getPosition().x, i->getSprite().getPosition().y + yOffset);
                  //enemy.move(0.f, enemy.getPosition().y + yOffset);
               }
               //enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset); // y axis is inverted in SFML
               //return 0; // move to separate method
            }

            if (i->getSprite().getPosition().y > game->getWindowHeight() - mPlayer.getLocalBounds().height) {
               //removeEnemy(enemy);
               // ALIVE is false, then draw based on whether alien is alive or not
               std::cout << "Everyone should be dead game over!" << std::endl;
               return 0; // change state to paused
            }
         }
      }

      updateStatistics(deltaTime, mStatisticsText);
      
      // Render All
      // Remember draw order is important
      window.clear();
      window.draw(mBackground);
      window.draw(mPlayer);
      window.draw(mStatisticsText);

      
      for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
         if (i->isAlive()) {
            i->draw(window);
            std::cout << "Enemy " << i->getID() << " position - " << i->getLocation().x << " " << i->getLocation().y << std::endl;
         }
      }

      if (bullet.isAlive()) // && !gameOver
      {
         //draw bullet
         bullet.draw(window);
         //move bullet
         bullet.getSprite().move(0.f, -20);
      }

      //test collision with bullet and boundary
      if (bullet.getSprite().getPosition().y < 0)
         bullet.kill();
      
      for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
         
         if (CollisionManager::collidesWith(mPlayer, *i) && i->isAlive()) { // *i it points to the enemy, and will give me an enemy
            std::cout << "You're dead!" << std::endl;
            return 0; //-> I'm dead gameOver = true;
         }
      }

      //for (Enemy& enemy : enemyList) {
      //   if (enemy.isAlive()) {
      //      enemy.draw(window);
      //   }
      //}

      //enemy.render(alienArray, mWindow);
      /*
      for (int i = 0; i < mEnemies.size(); i++)
      {
         sf::Sprite temp = mEnemies.at(i);
         mWindow.draw(temp);
      }
      */

      window.display();

   }

   return 0;
}

void processEvents(sf::RenderWindow& window) {
   sf::Event event;
   while (window.pollEvent(event))
   {
      switch (event.type)
      {
      case sf::Event::KeyPressed:
         handlePlayerInput(event.key.code, true);
         break;

      case sf::Event::KeyReleased:
         handlePlayerInput(event.key.code, false);
         break;

      case sf::Event::Closed:
         window.close();
         break;
      }
   }
}

void handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
   if (key == sf::Keyboard::W || key == sf::Keyboard::Up)
      mIsMovingUp = isPressed;
   else if (key == sf::Keyboard::S || key == sf::Keyboard::Down)
      mIsMovingDown = isPressed;
   else if (key == sf::Keyboard::A || key == sf::Keyboard::Left)
      mIsMovingLeft = isPressed;
   else if (key == sf::Keyboard::D || key == sf::Keyboard::Right)
      mIsMovingRight = isPressed;
   else if (key == sf::Keyboard::Space) {
      mIsShooting = isPressed;
      std::cout << "Spacebar was pressed!" << std::endl;
   }
}

13
General / Re: Best Practice for using setFramerateLimit
« on: November 23, 2019, 01:44:02 am »
I replaced the setFrameLimit with window.setVerticalSyncEnabled(true) and now I am getting constant 60, so smooth movement.

I think the issue was that setFrameLimit implies that it will ceil the value to 60, but if its lower it is also acceptable. So maybe that causes the weird issue.

14
General / Best Practice for using setFramerateLimit
« on: November 23, 2019, 01:37:27 am »
I currently follow the SFML Game Development example for checking the time frame update between the previous and the current frame, for frame per second in my main loop.

However, I want to set the limit to 60FPS, as in the moment it going to 1000s. I am setting the limit right after creating the window as written in the documentation, however I'm getting a jittery effect on my spaceships.

This is my current code. What would be the best practice to use setFramerateLimit with main loop calculations to update on each frame? (render, movement,input etc)

Quote
int main()
{
   sf::Texture            mPlayerTexture;
   sf::Sprite            mPlayer;
   sf::Texture            mBackgroundTexture;
   sf::Sprite            mBackground;
   
   sf::RenderWindow window(sf::VideoMode(game->getWindowWidth(), game->getWindowHeight()), "SFML Application");
   //static const sf::Time   TimePerFrame;

   window.setFramerateLimit(60);

   if (!mPlayerTexture.loadFromFile("Media/Textures/PixelSpaceships/blue_01.png"))
   {
      // Handle loading error
   }
   if (!mBackgroundTexture.loadFromFile("Media/Textures/Space.jpg")) {
      // Handle loading error
   }
   

   mBackground.setTexture(mBackgroundTexture);
   mBackground.setOrigin(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);
   mBackground.setPosition(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);

   // Set Texture and Position
   mPlayer.setTexture(mPlayerTexture);
   mPlayer.setOrigin(24.f, 24.f);
   mPlayer.setPosition(game->getWindowWidth() / 2.f, game->getWindowHeight() / 2.f);

   //enemy.enemyInstantiator(2, 100.f, 50.f);
   //enemyInstantiator(10, 100.f, 150.f);

   // Statistics Initialisation
   sf::Font            mFont;
   sf::Text            mStatisticsText;
   mFont.loadFromFile("Media/Sansation.ttf");
   mStatisticsText.setFont(mFont);
   mStatisticsText.setPosition(5.f, 5.f);
   mStatisticsText.setCharacterSize(10);

   // Enemy Creation // Separate method in main
      
   std::vector<Enemy> *enemyList = new std::vector<Enemy>();
   float xPosition = 100.f;
   float yPosition = 50.f;
   float yOffset = 50.f;
   float xOffset = 60.f;
   for (int i = 0; i < NUMBER_OF_ALIENS; i++) {
      Enemy alien(i, enemySpeed);
      alien.getSprite().setOrigin(24.f, 24.f);
      alien.setLocation(xPosition + (i * xOffset), yPosition);
      alien.getSprite().setRotation(180.f);
      enemyList->push_back(alien);

      //std::cout << "I have " << enemyList->size() << " spaceships" << std::endl;
   }
   //std::cout << "I have " << enemyList->size() << " spaceships";

   /*
   //create a an array of enemys
   Enemy alienArray = new Enemy[];
   for (int i = 0; i < NUMBER_OF_ALIENS; i++)
   {
      Enemy alien(i, enemySpeed);

      alien.setLocation(i * 50.f + 50.f, alien.getSprite().getGlobalBounds().height / 2);
      alienArray;
   }
   */

   //game->run();

   // Measure elapsed time
   sf::Clock clock;
   sf::Time timeSinceLastUpdate = sf::Time::Zero;
   while (window.isOpen())
   {
      // Puts the time counter back to zero and also returns the time elapsed since the clock was started
      sf::Time deltaTime = clock.restart();
      timeSinceLastUpdate += deltaTime;
      while (timeSinceLastUpdate > TimePerFrame) // fixed time steps
      {
         timeSinceLastUpdate -= TimePerFrame; // solves problem with variable delta time, each frame is unique

         processEvents(window);
         //update(TimePerFrame);

         // Player 1 movement
         sf::Vector2f movement(0.f, 0.f);
         if (mIsMovingUp)
            movement.y -= playerSpeed;
         if (mIsMovingDown)
            movement.y += playerSpeed;
         if (mIsMovingLeft)
            movement.x -= playerSpeed;
         if (mIsMovingRight)
            movement.x += playerSpeed;
         // shooting logic


         // Possibly this will be the data that needs to be sent to server
         mPlayer.move(movement * TimePerFrame.asSeconds()); // Time.deltaTime frame independent movement

         // for each player eventually
         screenBound(mPlayer);
         // screenbound enemies or else check that they do not go off bounds and change direction

         // Enemy Behaviour // Move to separate method

         sf::Vector2f enemyMovement(1.f, 0.f);
         float yOffset = 50.f;
         float xOffset = 60.f;
         // Be careful with iterators as when deleting it will automatically jump to the next item in vector
         for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) // CAUTION & solved everything again - lesson in C++, if we don't get address, we always create a copy and modify it, which is not what we want
         {
            std::cout << "Direction before working move " << direction << std::endl;
            i->getSprite().move(enemyMovement * direction); // Issue detected direction only changing sign if greater or less than screen bounds once
            if (i->getSprite().getPosition().x + i->getSprite().getLocalBounds().width / 2 > game->getWindowWidth() ||
               i->getSprite().getPosition().x - i->getSprite().getLocalBounds().width / 2 < game->getWindowWidth() - game->getWindowWidth()) { // this will be 0
               direction = -(direction);

               std::cout << "Direction inside if statement " << direction << std::endl;
               // another for loop move all down by yOffset
               for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
                  i->getSprite().setPosition(i->getSprite().getPosition().x, i->getSprite().getPosition().y + yOffset);
                  //enemy.move(0.f, enemy.getPosition().y + yOffset);
               }
               //enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset); // y axis is inverted in SFML
               //return 0; // move to separate method
            }

            if (i->getSprite().getPosition().y > game->getWindowHeight() - mPlayer.getLocalBounds().height) {
               //removeEnemy(enemy);
               // ALIVE is false, then draw based on whether alien is alive or not
               std::cout << "Everyone should be dead game over!" << std::endl;
               return 0; // change state to paused
            }
         }
      }

      updateStatistics(deltaTime, mStatisticsText);
      
      // Render All
      // Remember draw order is important
      window.clear();
      window.draw(mBackground);
      window.draw(mPlayer);
      window.draw(mStatisticsText);

      
      for (std::vector<Enemy>::iterator i = enemyList->begin(); i != enemyList->end(); ++i) {
         if (i->isAlive()) {
            i->draw(window);
            std::cout << "Enemy " << i->getID() << " position - " << i->getLocation().x << " " << i->getLocation().y << std::endl;
         }
            
      }

      

      //for (Enemy& enemy : enemyList) {
      //   if (enemy.isAlive()) {
      //      enemy.draw(window);
      //   }
      //}

      //enemy.render(alienArray, mWindow);
      /*
      for (int i = 0; i < mEnemies.size(); i++)
      {
         sf::Sprite temp = mEnemies.at(i);
         mWindow.draw(temp);
      }
      */

      window.display();

   }

   return 0;
}

15
The issue was resolved by changing the code structure completely in order to avoid calling private methods from public scope. This can be closed.

Pages: [1] 2
anything