Automatic Water Animation

In this program, I show an example of how to create animated water without drawing the animation yourself. I originally created this program to animate the water in Petit Forest for Abgar, but he kindly consented to the creation of this example program page. This example is of average difficulty, so it's not too hard to understand, but you still need to know what you're doing. The animation is very efficient, so even if the whole screen is filled with water, it shouldn't slow down the program any more than animating a single water tile.

The System
The animation system has two parts: a large initial portion which you call once to set up the animation tiles, and a smaller second portion which you call in a loop to create the animation effect. The first part reads in all the water tile information from the BG using CHRREAD and stores it in a single variable, D$. It then performs some transformations on D$ that make the water look like it's moving left and right, and then stores each frame of the animation in an array, BGANIM$. Now that the program has the frames of animation stored, it can then use CHRSET in a loop to continuously replace the current water tiles with the next water tile from the array. Since it's only replacing the tile information, it updates every single tile on screen which uses that information at the same time, so it's super duper efficient.

Variables
These are the variables you'll want to alter to change the effect: There is also another code segment you can alter to change the way the water animates. In the example program, it does a sort of "ripple" effect. However, if you go to line 81 and 82, you should see code which looks like: BGANIM$(I*2,1)=R1$: etc. BGANIM$(I*2,3)=L1$: etc. If you change the R1 to an L1 and the L1 to an R1 in those lines, you can make the water simply move left and right instead of ripple. This may be more appropriate in situations where the water looks weird when rippling.
 * NFRAMES determines the number of VSYNCs between each animation frame. The larger this number, the slower the animation.
 * WATERSTART is the starting position of the water tiles. For instance, in the example BG sheet (taken from Petit Forest), the water starts at BG character 28.

Assumptions
This example assumes that you are:
 * Drawing the water on the BG
 * Your water tiles are arranged in a 2X2 fashion to form a larger 16X16 water tile. If not, you can just duplicate the same water tile 4 times and place them in a grid on screen to produce the same effect. However, you should really strive to have 4 distinct water tiles like the given example sheet.
 * Your water tiles are on the first BG page, BGU0. This can be changed in the code however

How to use
If you just run the program, you'll see an example which uses a partial BG sheet from Petit Forest. In order to run this example, you'll need to scan all 3 QR codes in the QR sheet. If you wish to use this in your program, you should place the code that comes before @LOOP wherever you load your BG sheet. You can remove the loop near the beginning that says you don't need it; it's just drawing the example. You'll want to change the LOAD line at the top to use whichever BG sheet you're using. Finally, just place the small IF statement block in the main game loop. If you have more than one loop where water is visible and you call VSYNC, you'll want to place it there as well. In this case, you should take the IF statement block and place it in a function which you can GOSUB to.

If you have any questions that are more specific than "How do I add this to my program", please let me know!