Iterators

Iterators are a powerful tool that lets you iterate with any object that satisfies certain condition. Below is a tutorial explaining how to use an iterator. Please read closely and follow the examples as you read the tutorial. Iterators are a extremely powerful tool

Index vs ID
A very common confusion users have when using TeaScript is understanding what an index is. Users mistakenly assume it means ID, but these are not the same thing.

So what is an index? An index is the position of an NPC in the NPC array. Look at it this way, imagine you have made this level below. the NPCs were placed from left to right. Here is a gif that illustrates how index show up and changes in-game. The index changes during runtime and is affected by other NPCs that die or get spawned. This means that storing an index across frames is not effective and unreliable.

Setting Up Your First Iterator
Now that you know how index behave, we can explain what an iterator is. An iterator is a function that will allow you to iterate over a group of NPCs indexes. This means that you can define an area and you can affect all objects in that area with custom behavior.

This is the entire process normally used for an iterator and you may use it as a template when creating one. It will be explained below how it works.

First you must create an iterator using itrCreate. When you create an iterator, you must define a type, an ID filter, and a rectangular box. SMBX will store your created iterator and return an ID to access it.

Once you create an iterator, you will be given a key to access that iterator. You give this key to itrCreate in order to access your iterator. Remember how we looked into what an index is at the beginning of the tutorial, this is where that information comes into play. The iteratorIndex is the object's index. This is very important, once we have an index we can access that object right away like this: Lets return to itrNext. Calling this function returns the first index of you group. Calling it a second time returns the second index of your group. It keeps repeating this pattern until it has succesfully iterated all objects in your group. When its finished, this function returns 0.

We are almost finished, there is one last thing we have to do. When you create an iterator you have to make sure to erase it when you are finished with it. If you create too many iterators without erasing them, the game will stop working. If you ever create an iterator and the iterators suddenly stopped working, that means you forgot to erase an iterator. You use the function BErase to erase an iterator.

Reference
Documentation to:

itrCreate

itrNext

Berase

Legacy
The iterator returns the ID of the found object within its rectangular region, so you can check the presence of an object and interact according it.

To get the next object of the iterator. Returns the object ID. If the object does not exist, the return value will be 0 and the iterator will be destroyed.

Getting started with Iterators
Before to get into iterators, make sure you can dominate the [|Loop Structure in TeaScript], otherwise this may get really confusing.

To use an iterator you need at least two variables. The first one will store the iterator, and the second one will store the ID of the found object. Here's a basic syntax of an iterator. In this example, we will create an iterator around the player's body.

This may seem a bit hard to understand at first, but don't worry! We'll get into each line. First you may be wondering, why is there nested loop? It is because the first loop runs the code every frame, while the second loop assures our iterator can iterate with various objects at the same frame. The second loop is optional, but if we don't include it the iterator will process one object per frame (which may be convenient or not, depending of what we want to do). Don't worry, we'll get into this later.

Now let's look at line 5,. The first parameter is 11 because we want it to iterate with blocks on the current screen (we could have also use 1 and it would produce the same result). The reason why the iterator is slightly bigger than the player hitbox is because we also wanted to check if the player is near to a block, not only if he's overlapping one.

In line 14, with  we're destroying the iterator on every frame. This is really important because if we don't destroy the iterator, after 255 frames it will stop working until you restart the game. If you think your code is right but for some reason the iterator is not working, you may need to restart the game.

Iterator that only detect an object per frame
There may be some cases where you want the iterator only process a object per frame. For example, if you're coding a fireball you need it to kill it only one enemy at the same time. In this scenario you don't need to use a loop (nested loop) for the iterator. In this example the iterator will show a message with the ID of the found BGO. Try overlapping two BGOs and make the player touch both of them, you'll notice how the iterator only returns the ID of the nearer BGO.

In contrast with out previous example that used a nested loop, it would have shown two or more messages at the same time (The amount of messages depends on how many objects are overlapping), while in this example it only processes only one per frame (the nearer object).

Using iterators
In real scenarios, you need iterators do more than just detecting the presence of a single object, you want interact with it. In this example, the player will become transparent every time it touches a block.