C ++ SFML, как сделать так, чтобы пули порождали свою индивидуальную физику? - PullRequest
0 голосов
/ 26 февраля 2020

Я делаю простую игру Bullet Hell в C ++ и SFML, где вы используете мышь для управления игроком и нажимаете на цели, чтобы увеличить счет. Каждый раз, когда на цель нажимают, она должна вызывать пулю в отдаленном от игрока месте со случайным углом перемещения. пули отскакивают от края окна и не go удаляются.

Я действительно застрял в том, как это сделать. Метод, который я мог бы попробовать, - сохранить данные пули в векторе , что я пока не знаю, как именно это сделать, но как я могу обновить позицию каждой отдельной пули, как только она там окажется? Тогда как я могу заставить каждую пулю сталкиваться с игрой?

Вот мой код, я отметил некоторые сомнительные области с комментариями многих вопросительных знаков:

#include <ctime>
#include <sstream>
#include <vector>

using namespace sf;

//?????????????????????
class enemy{
public:

    int xpos, ypos, xvel, yvel;

    void spawnEnemy(){
        CircleShape enemyc(10);
        enemyc.setFillColor(Color::Red);
    }
};
//?????????????????????

int main(){

    RenderWindow window(VideoMode(800, 600), "SFMLbullet", Style::Close);
    window.setMouseCursorVisible(false);
    window.setFramerateLimit(60);

    srand(time(0));

    //?????????????????????
    std::vector<enemy> enemies;
    //?????????????????????

    //define target
    int targetx = rand() % 580 - 20;
    int targety = rand() % 580 - 20;
    bool tregen = false;
    CircleShape targetc(20);
    targetc.setFillColor(Color::Green);

    //define player
    CircleShape playerc(10);
    playerc.setFillColor(Color::Blue);
    playerc.setOrigin(10,10);

    //define score count
    int score = 0;
    std::stringstream scoreconv;
    Font scorefont;
    scorefont.loadFromFile("SLANT.TTF");
    Text scorecount;
    scorecount.setFont(scorefont);
    scorecount.setCharacterSize(50);
    scorecount.setFillColor(Color::White);
    scoreconv.str("0");

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

        //when target is clicked
        if(Mouse::isButtonPressed(Mouse::Left) && !tregen && playerc.getGlobalBounds().intersects(targetc.getGlobalBounds())){

            //generate new target
            targetx = rand() % 780 - 20;
            targety = rand() % 580 - 20;

            //add score
            score++;
            scoreconv.str("");
            scoreconv << score;

            //?????????????????????
            enemy bullet;
            enemies.push_back(bullet);
            //?????????????????????

            tregen = true;
        }
        //don't regenerate target rapidly
        if(!Mouse::isButtonPressed(Mouse::Left)){
            tregen = false;
        }

        //window events
        Event event;
        while(window.pollEvent(event)){

            if(event.type == Event::Closed) window.close();
        }

        window.clear(Color::Black);

        //draw target
        targetc.setPosition(targetx, targety);
        window.draw(targetc);

        //draw player
        playerc.setPosition(Mouse::getPosition(window).x, Mouse::getPosition(window).y);
        window.draw(playerc);

        //?????????????????????
        //DRAW BULLETS HERE, ideally with enemyc.move()
        //?????????????????????

        //score count
        scorecount.setString(scoreconv.str());
        window.draw(scorecount);

        window.display();
    }

    return 0;
}

1 Ответ

1 голос
/ 03 марта 2020

У вас уже есть данные, необходимые для вашей пули, которую вы назвали «врагом». У вас уже есть соответствующая коллекция для хранения пуль, вы решили использовать вектор, и это нормально.

Вам нужно только настроить свои обновления / dr aws и рассмотреть несколько простых столкновений:

//update
targetc.setPosition(targetx, targety);
playerc.setPosition(Mouse::getPosition(window).x, Mouse::getPosition(window).y);

// you can place this in your enemy move function
for (Enemy enemy : enemies) {
    if (enemy.xpos < 0 || enemy.xpos > window.getSize().x) {
        enemy.xvel *= -1; // revert X velocity if touching side edges
    }
    if (enemy.ypos < 0 || enemy.ypos > window.getSize().y) {
        enemy.yvel *= -1; // revert Y velocity if touching top or bottom edges (don't know whether you want this)
    }

    enemy.xpos += enemy.xvel;
    enemy.ypos += enemy.yvel;
}

//draw
window.draw(targetc);
window.draw(playerc);
for (Enemy enemy : enemies) {
    window.draw(
}

Также обратите внимание на следующее для своего врага

class enemy{
public:
    int xpos, ypos, xvel, yvel;
    CircleShape enemyc;

    void spawnEnemy(){
        enemyc = CircleShape(10);
        enemyc.setFillColor(Color::Red);
    }
};

Последнее замечание:

Отделите ваши обновления от чертежа, как правило, вы хотите рисовать только после того, как все будет рассчитано.

...