Боевая игра - как сделать бесконечную ракету? - PullRequest
0 голосов
/ 16 марта 2020

Я создаю игру, похожую на BattleCity, и хочу, чтобы мой танк продолжал выпускать ракеты всякий раз, когда я нажимал клавишу пробела. Я использовал Array, но не могу оставить индекс пустым, поскольку у меня есть целое число ракет.

PictureBox[] missileArray = new PictureBox[10];
int missileNumber = -1;
PictureBox missile = new PictureBox();
Boolean startshooting = false;   

private void shootingTimer_Tick(object sender, EventArgs e)
{
    for(int i = 0; i < missileNumber; i++)
    {
        missileArray[i].Top -= 20;
    }
}

private void Game_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyData == Keys.Space)
    {
        this.Controls.Add(missile);
        missile.Width = 10;
        missile.Height = 10;
        missile.BackColor = Color.Black;
        missile.Top = MainTank.Top + MainTank.Height / 2 - missile.Height / 2;
        missile.Left = MainTank.Left + MainTank.Width / 2 - missile.Width / 2;

        missile.BringToFront();
        missileNumber += 1;
        missileArray[missileNumber] = missile;
        shootingTimer.Start();
    }

MissileArray не может оставить его пустым, он должен иметь размер массива или что-то в этом роде. Как я буду делать бесконечные пусковые ракеты?

Извините, что не могу объяснить это правильно, и мой Engli sh не так хорош.

1 Ответ

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

Ответ на ваш вопрос

Я использовал массив, но не могу оставить индекс пустым

Этот сценарий, т.е. Неопределенное количество элементов в коллекции является точной причиной, по которой разработчики обычно используют списки (List<T>) над массивами (T[]). Это не единственная причина, но большая (если не самая большая) причина для использования списков.

Переработка вашего кода для использования списка (я пропустил весь другой код)

List<PictureBox> missiles = new List<PictureBox>();

private void shootingTimer_Tick(object sender, EventArgs e)
{
    foreach(var missile in missiles)
    {
        missile.Top -= 20;
    }
}

private void Game_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyData == Keys.Space)
    {
        missiles.Add(missile);
    }
}

Хотя использование немного отличается, список ведет себя точно так же, как и ваш массив (он даже допускает индексированный доступ), но с дополнительным преимуществом возможности размещать в нем любое количество элементов.


Ответ на ваш комментарий

Таким образом, он будет продолжать стрелять, даже если не вернется на свое место? Как и сейчас, когда я нажал пробел, изображение будет отправлено обратно

Вы продолжаете добавлять один и тот же объект missile снова и снова, сбрасывая свойства существующей ракеты всякий раз, когда должна быть запущена дополнительная ракета. Вы должны создавать новые ракеты каждый раз, когда нажимаете пробел. Нет никакой причины иметь ракетное поле в вашем классе, его можно ограничить событием нажатия клавиши пробела:

private void Game_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyData == Keys.Space)
    {
        var missile = new PictureBox();

        // set all the new missile's properties like in your code

        missiles.Add(missile);
    }
}

Вы также не должны запускать shootingTimer при каждом нажатии клавиши пробела , Таймер должен быть запущен один раз , после чего он будет автоматически перебирать все ракеты в списке. Когда нажимается пробел, вам нужно только добавить ракету в список, и она будет автоматически обработана.

Источником проблемы, с которой вы столкнулись, является недопонимание того, как справочные типы работают в C#. Это выходит за рамки ответа о StackOverflow, но я предлагаю вам прочитать ссылочные типы и типы значений в C# (эта ссылка - лишь один из многих ресурсов, которые вы можете найти в Интернете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...