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

Author Topic: Smaller enemy spawning per frame rate  (Read 1425 times)

0 Members and 2 Guests are viewing this topic.

bblob

  • Newbie
  • *
  • Posts: 2
    • View Profile
Smaller enemy spawning per frame rate
« on: September 23, 2024, 05:41:04 pm »
hello i am learning sfml and created a small game where if a bullet hits an enemy it spawns smaller enemies on according to the vertices of the bigger enemy. The problem is while the smaller enemies are spawing the movement is quite unusual and the smaller enemies are spawing per frame i think. I have tried everything to fix it but i just dont know what i am doing wrong. i am using an ECS system btw.

//Collision of the bullet and the enemy

void Game::sCollision()
{
   
    for (auto & b : m_entities.getEntities("bullet"))
    {
        for (auto &e : m_entities.getEntities("enemy"))
        {
            Vec2 & bulletpos = b->cTransform->pos;
            Vec2 & enemypos = e->cTransform->pos;
           
            const auto& eCR = e->cCollision->collisionRadius;
            const auto& bCR = b->cCollision->collisionRadius;
           
            if (enemypos.dist(bulletpos) < (eCR + bCR)*(eCR + bCR))
            {
                spawnSmallEnemy(e);
                e->destroy();
                b->destroy();
               
            }
           


        }
    }
}



// spawning the number of smaller enemies according to the shape and spawing it in different angles
void Game::spawnSmallEnemy(std::shared_ptr<Entity>& e)
{
   
    //get the number of sides
    size_t vertices = e->cShape->circle.getPointCount();

    Vec2 parentpos{ e->cTransform->pos.x,e->cTransform->pos.y };
    Vec2 normalizedparnetpos{ Vec2::normalize(parentpos) };

    //misc info

    sf::Color parentfill{ e->cShape->circle.getFillColor() };
    sf::Color OutlineColor{ e->cShape->circle.getOutlineColor() };
    float thickness{ e->cShape->circle.getOutlineThickness() };


    float smallenemyRadius{ e->cShape->circle.getRadius() * 0.5f };
    float smallenemyCollision{ e->cCollision->collisionRadius*0.5f };


    //looping through each angle with the sides as parameters
    float angle{ 0 };

   
   
    for (size_t i = 0; i < vertices; i++)
    {
       
       

        //spawn small enemy

        auto smallEnemy = m_entities.addEntity("SmallEnemy");


        double radians{ angle * PI / 180 };

        Vec2 velocity
        {
            std::cos(radians) * normalizedparnetpos.x + std::sin(radians) * normalizedparnetpos.y,
            std::sin(radians) * normalizedparnetpos.x - std::cos(radians) * normalizedparnetpos.y,
        };

        //Get the lenght of the vector
        float L{ sqrtf(velocity.x * velocity.x + velocity.y * velocity.y) };
        //Normalize the vector to get an unit vector
        Vec2 normalizedVelocity{ velocity.x / L,velocity.y / L };

        //Scales the normalized vertor by the parents velocity
        Vec2 newVelocity{ normalizedVelocity.x * e->cTransform->vel.x, normalizedVelocity.y * e->cTransform->vel.y };
       
        smallEnemy->cTransform = std::make_shared<CTransform>(parentpos, newVelocity, 0.0f);


        smallEnemy->cShape = std::make_shared<CShape>(smallenemyRadius, vertices, parentfill, OutlineColor, thickness);
        smallEnemy->cCollision = std::make_shared<CCollision>(smallenemyCollision);
        smallEnemy->cLifespan = std::make_shared<CLifespan>(70);
       
        angle += 360 / vertices;
    }




}

//Movement of the player and the enemies
void Game::smovement()
{
for (auto e : m_entities.getEntities())
    {
        if (e->tag() =="player")
        {
            //set rotation of the player
            m_player->cTransform->angle += 1.0f;
            m_player->cShape->circle.setRotation(m_player->cTransform->angle);

            //movement of the player
            m_player->cTransform->pos += playervel;
           
        }
        else if (e->cTransform)
        {
            //Updates the position of the entities
            e->cTransform->pos += e->cTransform->vel;
            //Rotates the entity
            e->cTransform->angle += 1.0f;
            e->cShape->circle.setRotation(e->cTransform->angle);
        }
       
       
       
    }

}

Image of the problem
« Last Edit: September 24, 2024, 08:14:18 am by eXpl0it3r »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11015
    • View Profile
    • development blog
    • Email
Re: Smaller enemy spawning per frame rate
« Reply #1 on: September 24, 2024, 08:15:31 am »
Can describe a bit more what you mean with "the movement is quite unusual"?
What would you expect to happen?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: Smaller enemy spawning per frame rate
« Reply #2 on: September 24, 2024, 10:40:04 am »
I'm just guessing based on the picture, but if the red shape is a bullet and the blue triangles are enemies, it looks like the triangle touching the red shape has spawned hundreds of small enemies that are moving away and rotating, leaving those white arm shapes. If that's the case, my guess is your destroy function isn't working. Both the red thing and blue triangle are still there, they should have been destroyed on collision, so they are continuing to collide every frame.

One side note, is your dist() function returning distance or distance squared?
if (enemypos.dist(bulletpos) < (eCR + bCR)*(eCR + bCR))
You are squaring the radii, so dist() should be the squared distance, but normally I'd expect that to have a name like distsq or something.

bblob

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Smaller enemy spawning per frame rate
« Reply #3 on: September 24, 2024, 03:19:30 pm »
Problem solved guys there was a problem with my erase function when removing the dead entitities.
« Last Edit: September 24, 2024, 03:35:45 pm by bblob »

 

anything