You are correct that using an array for your bullets is what you should do. I would start by reading about what arrays are and how they are used in C++. Hereās one article to start with:
As the article says, an array is a way of having many āthingsā (known as objects) of the same type, and being able to refer to any one of them by its number. The āobjectsā that an array contains donāt have to be only simple variable types (like char
or int
). They can be structures or classes or even other arrays, as long as all the objects in the array are the same. Arrays can also have more than one ādimensionā but for your current requirements, a single dimensional array should be fine.
For each of your bullets (though it looks like you call them balls in the code), youāre currently keeping track of 2 things; the X coordinate and the Y coordinate of the bulletās position on the screen. It also looks like you have a variable called ballsize that gives the size of the square that you use to draw a bullet/ball.
The Arduboy2 library provides a structure
named Rect that can describe the location and size of a rectangle. This is what you need for one of you bullets, so I suggest you use it.
To create a single bullet you create a Rect
āobjectā:
Rect bullet;
You now have an object named bullet
that has 4 variables: the x
position, the y
position, the width
and the height
. To access any one of these variables you use the object name followed by a dot followed by the variable
bullet.x = 5;
bullet.y = 13;
bullet.width = ballsize;
bullet.height = ballsize;
However, this only gives us a single bullet. To get as many bullets as we want (letās say 10) we can create an array of bullets.
constexpr uint8_t bullets = 10; // define the number of bullets
Rect bullet[bullets];
To access the variables for any one of the bullets, put its number in square brackets (this is called the āindexā) after the name. Note that indexes start at 0 so for 10 bullets they will be numbered 0 to 9.
// first bullet (number 0) is at location 5, 13
bullet[0].x = 5;
bullet[0].y = 13;
bullet[0].width = ballsize;
bullet[0].height = ballsize;
// fifth bullet (number 4 starting from 0) is at location 23, 45
bullet[4].x = 23;
bullet[4].y = 45;
bullet[4].width = ballsize;
bullet[4].height = ballsize;
Note that since width
and height
are variable, each bullet could be a different size if we wanted.
Itās likely that not all your bullets, or even any, will be in use all the time, so we need a way to indicate if each bullet is currently in use. We could create an array of āin useā flags or create a new structure to add a flag. However, if a bullet is always going to be āon screenā when itās in use, we can use a ātrickā. We can set the x
value to -1 to indicate that bullet isnāt in use. To initially set all bullets as being not in use, we can use a for
loop. We can also initialise the size of the bullets at this time
constexpr int bulletOff = -1; // define the "bullet not in use" value;
for (uint8_t bulletNum = 0; bulletNum < bullets; ++bulletNum) {
bullet[bulletNum].x = bulletOff;
bullet[bulletNum].width = ballsize;
bullet[bulletNum].height = ballsize;
}
Now if we want to use a bullet, we set its x
value to be on screen, and set its y
value. (If the bullet size never changes, we only have to set width
and height
once, otherwise they can be changed as required).
To display all the bullets that are in use, we can use a simple for
loop
for (uint8_t bulletNum = 0; bulletNum < bullets; ++bulletNum) {
if (bullet[bulletNum].x != bulletOff) {
arduboy.fillRect(bullet[bulletNum].x, bullet[bulletNum].y, bullet[bulletNum].width, bullet[bulletNum].height, BLACK);
}
}
Since any bullet may or may not be in use, we might need a way to find an unused bullet to use. Hereās a function that will do that:
// return the index of the first unused bullet or return the value of "bullets" (10) if all are in use
uint8_t findUnusedBullet() {
uint8_t bulletNum;
for (bulletNum = 0; bulletNum < bullets; ++bulletNum) {
if (bullet[bulletNum].x == bulletOff) {
break; // unused bullet found
}
}
return bulletNum;
}
I think Iāll leave it at that for now and you can let us know if you understand so far.
There may be other things you have to keep track of, such as each bulletās direction. We can discuss this later, if necessary.