При создании обьекта класса в динамической памяти спрайт этого обьекта начинает двигатся быстрее при искомых параметрах SFML

#include <SFML/Graphics.hpp>
#include <vector>
#include <cmath>
#include <iostream>
#include <list>
#include <cstdlib>
#include <ctime>

using namespace sf;
using namespace std;

float radians = 0.017453;

//класс со сходными свойствами всех игровых объектов
class Entity
{
public:
int points, size;
float dx, dy, x, y;
float speed;
float angle = 0;
string name;
bool isLife;

CircleShape EntityShape;
Entity(float X, float Y, int POINTS, int SIZE, int ANGLE)
{
    x = X; y = Y; points = POINTS; size = SIZE;

    angle = ANGLE;
    
    dx, dy = 0;

    EntityShape.setOrigin(size, size);

    isLife = true;
}

virtual void update() {};
};

//класс игрока
class Ship : public Entity
{
public:
bool thrust = false;
float maxSpeed = 7;

Ship(float X, float Y, int POINTS, int SIZE, int ANGLE) : Entity(X, Y, POINTS, SIZE, ANGLE)
{
    EntityShape.setRadius(size);
    EntityShape.setPointCount(points);
    EntityShape.setFillColor(Color::White);
    EntityShape.setOutlineColor(Color::White);
    EntityShape.setOutlineThickness(2);
    EntityShape.setScale(0.7, 1);
    EntityShape.setPosition(x, y);
    name = "ship";
}
void update()
{
    //проверяем:есть ли тяга
    if (thrust)
    {
        dx += cos(angle * radians) * 0.2;
        dy += sin(angle * radians) * 0.2;
    }
    else
    {
        dx *= 0.99;
        dy *= 0.99;
    }

    speed = sqrt(dx * dx + dy * dy);

    if (speed > maxSpeed)
    {
        dx *= maxSpeed / speed;
        dy *= maxSpeed / speed;
    }

    //вычисляем икс и игрек
    x += dx;
    y += dy;

    //проверяем: корабль вышел за пределы игрового пространства?
    if (x > 620) x = 0;
    if (x < -20) x = 600;

    if (y > 420) y = 0;
    if (y < -20) y = 400;

    //перемещаем корабль
    EntityShape.setPosition(x, y);

    //непосредственно сам поворот
    EntityShape.setRotation(angle + 90);
}
};

class Asteroid : public Entity
{
public:
Asteroid(float X, float Y, int POINTS, int SIZE, int ANGLE) : Entity(X, Y, POINTS, SIZE, ANGLE)
{
    EntityShape.setRadius(size);
    EntityShape.setPointCount(points);
    EntityShape.setFillColor(Color::Black);
    EntityShape.setOutlineColor(Color::White);
    EntityShape.setOutlineThickness(2);
    EntityShape.setPosition(x, y);
    name = "asteroid";

    dx = rand() % 9 - 4;
    dy = rand() % 9 - 4;
}
void update()
{
    x += dx;
    y += dy;

    if (x > 650) x = -50;
    if (x < -50) x = 650;

    if (y > 450) y = -50;
    if (y < -50) y = 450;

    EntityShape.setPosition(x, y);

}
};

class Bullet : public Entity
{
public:
Bullet(float X, float Y, int POINTS, int SIZE, int ANGLE) : Entity(X, Y, POINTS, SIZE, ANGLE)
{
    EntityShape.setRadius(size);
    EntityShape.setPointCount(points);
    EntityShape.setFillColor(Color::Blue);
    EntityShape.setOutlineColor(Color::Blue);
    name = "bullet";
}
void update()
{
    dx = cos(angle * radians) * 7;
    dy = sin(angle * radians) * 7;

    x += dx;
    y += dy;

    EntityShape.setPosition(x, y);

    if (x < 0 || x > 600 || y < 0 || y > 400) isLife = false;
}
};

bool Collision(Entity* a, Entity* b)
{
if ((a->size + b->size) >= sqrt(fabs((a->x - b->x) * (a->x - b->x) + (a->y - b->y) * (a->y - b- >y))))
{
    return true;
}
return false;
}

int main()
{
//рисуем окно
RenderWindow app(VideoMode(600, 400), "Game");
app.setFramerateLimit(60);



list <Entity*> entities;
list <Entity*> :: iterator iter;
list <Entity*> :: iterator a;
list <Entity*> :: iterator b;

Ship *ship = new Ship(300, 200, 3, 10, 0);
entities.push_back(ship);

for (int i = 0; i < 10; i++)
{
    Asteroid* asteroids = new Asteroid(rand() % 600, rand() % 400, 5, 20, 0);
    entities.push_back(asteroids);
}

while (app.isOpen())
{
    Event event;
    while (app.pollEvent(event))
    {
        if (event.type == Event::Closed)
        {
            app.close();
        }
        
        if (event.type == Event::KeyPressed)
        {
            if (event.key.code == Keyboard::Space)
            {
                Bullet *bullet = new Bullet(ship->x, ship->y, 10, 3, ship->angle);
                entities.push_back(bullet);
            }
        }
    }
    
    if (Keyboard::isKeyPressed(Keyboard::A))
    {
        ship->angle -= 3;
    }
    
    if (Keyboard::isKeyPressed(Keyboard::D))
    {
        ship->angle += 3;
    }
    
    if (Keyboard::isKeyPressed(Keyboard::W))
    {
        ship->thrust = true;
    }
    else ship->thrust = false;

    for (a = entities.begin(); a != entities.end(); a++)
    {
        for (b = entities.begin(); b != entities.end(); b++)
        {
            if ((*a)->name == "asteroid" && (*b)->name == "bullet")
            {
                if (Collision(*a, *b))
                {
                    (*a)->isLife = false;
                    (*b)->isLife = false;
                }
            }
        }
    }

    app.clear(Color::Black);
    app.draw(ship->EntityShape);

    for (iter = entities.begin(); iter != entities.end(); iter++)
    {
        app.draw((*iter)->EntityShape);
    }

    for (iter = entities.begin(); iter != entities.end();)
    {
        Entity* entity = *iter;
        entity->update();
        if (entity->isLife == false) {
            iter = entities.erase(iter);
            delete entity;
        }
        else iter++;
    }

    ship->update();
    
    app.display();
}
}

Я объект класса Ship создал в динамической, а не статической памяти чтобы можно было его записать в список entities и проверять столкновения, а спрайт корабля стал двигаться быстрее чем было при тех же параметрах! Я не знаю как так, даже не представляю... Но что нужно сделать чтобы этого не было, ничего не изменяя в функции update()?


Ответы (1 шт):

Автор решения: EOF

Всё просто. Корабль ускорился, потому что Вы дважды вызываете для него метод update. Ваш корабль уже находится в entities и Вы в цикле вызываете метод update для всех обьектов. Просто уберите строку

ship->update();

По этой же причине можно убрать строку

app.draw(ship->EntityShape);
→ Ссылка