GBA C++: Как нарисовать несколько анимационных пикселей с помощью массивов?

Я пишу игру для эмулятора GBA по образцу классической аркадной игры "Феникс", в которой корабль стреляет пулями по целям над ним. У меня в настоящее время игра работает нормально, но я хочу иметь возможность стрелять несколькими пулями одновременно.

Я создал меньший исходный файл просто для того, чтобы проверить, как я могу это сделать, чтобы не было кирпичей, кораблей и т. Д., Только источник для пуль и цвет фона.

Я попытался создать "журнал" для корабля, который содержит пять пуль, создав массив из 5 "пуль" структур, каждая из которых содержит свои координаты x и y. Каждая пуля также присваивает ей логический флаг, чтобы определить, запущен он или нет, что позволяет циклу искать в массивах при нажатии A, чтобы найти пулю, которая еще не была запущена, и запустить ее.

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

Возможно, вы могли бы помочь мне определить проблему в моем коде?

Спасибо.

#include <stdint.h>
#include "gba.h"

const int MAG_SIZE = 5;
bool bulletFired[MAG_SIZE] = {false};

struct bullet {
    int x;
    int y;
} bullet[MAG_SIZE];


bool isPressed(uint16_t keys, uint16_t key)
{ // Uses REG_KEYINPUT and a specified key mask to determine if the key is pressed

    return (keys & key) == 0; 
}

void DrawBullet(int bulletXPos, int bulletYPos)
{ // Fires bullet from player craft

    PlotPixel8(bulletXPos, bulletYPos, 2);
}

int main() 
{

    REG_DISPCNT = MODE4 | BG2_ENABLE;

    bool isPressed(uint16_t keys, uint16_t key);  
    void DrawBullet(int bulletXPos, int bulletYPos);    

    SetPaletteBG(0, RGB(0, 0, 10)); // Blue
    SetPaletteBG(1, RGB(31, 31 ,31)); // White
    SetPaletteBG(2, RGB(25, 0, 0)); // Red

    ClearScreen8(0);

    while (true)
    {

        WaitVSync();

        ClearScreen8(0);

        uint16_t currKeys = REG_KEYINPUT;

         for (int n = 0; n < 5; n++)
        {
            if ( bulletFired[n] )
            {
                bullet[n].y--;
                DrawBullet(bullet[n].x, bullet[n].y);

                if ( bullet[n].y < 1 )
                {
                    bulletFired[n] = false;
                }
            }
        }


        if (isPressed(currKeys, KEY_A))
        { // Key A is pressed
            for (int n = 0; n < 5; n++)
            {
                if ( !bulletFired[n] )
                {
                    bulletFired[n] = true;
                    bullet[n].x = 120;
                    bullet[n].y = 134;
                }   
            }
        } 

        FlipBuffers();
    }

    return 0;
}

1 ответ

Решение

Проблема здесь

if (isPressed(currKeys, KEY_A))
    { // Key A is pressed
        for (int n = 0; n < 5; n++)
        {
            if ( !bulletFired[n] )
            {
                bulletFired[n] = true;
                bullet[n].x = 120;
                bullet[n].y = 134;
            }   
        }
    }

Когда вы обнаруживаете нажатие клавиши, вы запускаете все доступные патроны одновременно.

Вы хотите что-то вроде:

    if (isPressed(currKeys, KEY_A))
    { // Key A is pressed
        for (int n = 0; n < 5; n++)
        {
            if ( !bulletFired[n] )
            {
                bulletFired[n] = true;
                bullet[n].x = 120;
                bullet[n].y = 134;
                //EXIT THE LOOP
                break;
            }   
        }
    }

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

Другие вопросы по тегам