In building the graphics for your game, you will most likely need to use many different techniques to build the game screen, make the player, animate actions, display stats, and so on. And most of the time you will have to blend certain techniques with others specifically for the game you are producing. The main idea here is that these graphic commands and techniques are not made to stand alone. They may need to be combined, blended, isolated, and/or, mixed.
Text Sprites
Text sprites are a rarely used method of displaying sprites. This is partially due to their slowness, but they are apt for creating 2D puzzle games.
As their name implies, text sprites are sprites made of text. They generally involve using a For( loop to loop through a string, and displaying each character one more space to the right than the previous. As a result, only the first column of each character is shown, allowing almost every conceivable 5*5 sprite to be shown.
Example
Consider this:
:"([X[( →Str1 //the characters plus 2 spaces
:ClrDraw
:For(X,1,7
:Pause
:Text(0,X,sub(Str1,X,1
:End
Example Explanation
If you run this code, you will slowly see a donut being drawn out, frame by frame. Each frame introduces a new character, and as is apparent, eventually forms the sprite. And because each character is shown one pixel to the right of the previous, that character overwrites the underlying character.
You might be wondering by now why the spaces are needed. Try taking them out of the code, and see what happens. The donut becomes a sideways devil donut. Those two horns are the top and bottom pixel of the ending "(". In this case, you really only need one space, but other characters which take up more than 2 columns will need 2 or more spaces.
Advantages and Disadvantages
Text sprites are limited, as some sequences of pixels cannot be shown, like 01011 among others. Although this is very few, it still prevents certain sprites. They are also limited to 5*5, or 7*7, if you use small or big text, respectively.
Text sprites also have the annoying tendency to overwrite whatever is to the right of them. In addition, they take a few milliseconds (on an 84+SE) to appear, and thus are unsuitable for games that require speed.
Despite this, do not underestimate text sprites! Some fine examples of using them are out there, like here:
Donut Quest II
Donut Quest II Level Editor
DarkerLine made it so you can create custom tiles for Donut Quest II. Buried in the Level Editor is a program that spits out the string to display certain sprites, and also prevents you from making invalid text sprites. Invalid simply means cannot be displayed as a text sprite.
It is also worthy to note that in most cases, when using the Text() function, it draws the text and erases the pxl above the text, overall erasing 6 lines. However, on TI84's, whenever you visit the Mode menu, a flag is set that makes the small text also erase the pxl below the text. This can cause havoc in programs that use text sprites, especially because of their difficulty to track down.
The use of a simple pxl-Test( algorithm should be able to alert the user of any problems before the game starts.
There are multiple ways to remedy the Text() underline problem. The program itself can execute DispTable or the assembly program AsmPrgmFDCB058EC9. Or, you can instruct the user to visit the table (2nd TABLE), matrix editor (2nd MATRX LEFT ENTER), or list editor (STAT ENTER) - or to "Reset Defaults" in the memory menu (2nd MEM 7 2 2).
Using Picture Variables
It is common to see people use picture variables to store a picture vital to the program, such as a title screen. This is commonly justified because drawing the picture with the individual graphics commands not only takes up lots of memory, but also takes considerably more time to display than the picture variable does (which is almost instant). However, this isn't always the best policy.
Because there are only ten picture variables (Pic0-Pic9) and they are shared by all TI-Basic programs, the picture invariably is going to get overwritten by another program. You might think that Pic9 or Pic0 aren't used very often, so they are safe to use, but that is just asking for trouble. Don't store any important picture to a picture variable.
Instead, what you should do is use the graphics commands to make the picture in the program, and then either place them in a separate program (i.e. an external subprogram) or place them at the beginning of the program (if you want to limit your use of subprograms). You can just check the first time that the program is run to see if the picture exists, and if it doesn't, create it. It's okay to use a picture variable in this scenario because you can just recreate the picture if it gets deleted or overwritten.
Hard Coded Sprites
Hard coded sprites are those that are drawn using individual Basic Pxl-*() commands. While they (typically) are faster, they also take more memory, and are less easily changed if you are making a long RPG. That means that you'll have to type out every Pxl-*() command for every pixel that is on, in every tile that appears in your RPG.
An example of a hard-coded sprite looks like this:
:Pxl-On(X,Y
:Pxl-On(X+1,Y+1
:Pxl-On(X+2,Y+2
:Pxl-On(X,Y+2
:Pxl-On(X+2,Y
Fast, but takes up a lot more memory. Often times, a matrix is used to carry which pixels are turned on; this is much more effective for more tiles, since you only need the matrix, and the drawing routine handles the rest.
:Input "Sprite?",A
:If not(A
:[[1,0,0,0,1][0,1,0,1,0][0,0,1,0,0][0,1,0,1,0][1,0,0,0,1
:If A
:[[0,1,1,1,0][1,0,0,0,1][1,0,0,0,1][1,0,0,0,1][0,1,1,1,0
:For(A,1,3
:For(B,1,3
:If Ans(A,B
:Pxl-On(A,B
:End
:End
If you input 0, then an X will be drawn, but any other number makes a O. You can do this with any size sprite, provided it can fit on the calculator screen (94*62), it doesn't take up the entire memory, and you tweak the For loops to be the proper size.
Stat Sprites
Statistical sprites are created by using the Plot#( commands to draw points or lines very quickly from a pair of lists for coordinates, and are drawn whenever the graph screen is accessed. A friendly graphing window is essential to making this work. The main advantage of stat sprites is their flexibility: they can be translated (shifted), reflected (flipped), rotated (turned), and dilated (stretched) by way of simple arithmetic. This offers plenty of ease and control over the sprite display.
To handle these transformations, it is practical to keep two lists of coordinates and then use variables as modifiers on these lists. For instance, when you reflect the image horizontally, one operation would flip the entire sprite by making all the x-values negative, and another would move it forward again to the correct location by adding the right amount to the same list. Of course, these two operations simplify to merely subtracting the list from a specified number.
Here are some formulas for these transformations, with L1 as the x-list and L2 as the y-list:
| Transformation | Formula |
|---|---|
| Horizontal translation | A+L1→L1 |
| Vertical translation | B+L2→L2 |
| Reflection about the x-axis | -L1→L1 |
| Reflection about the y-axis | -L2→L2 |
| Rotation 90° clockwise |
L1→L3 -L2→L1 L3→L2 |
| Rotation 90° counterclockwise |
-L1→L3 L2→L1 L3→L2 |
| Rotation by an angle of θ | L1cos(θ)-L2sin(θ)→L3 L1sin(θ)+L2cos(θ)→ L2 L3→L1 |
| Horizontal stretch | AL1→L1 |
| Vertical stretch | BL2→L2 |
Advantages and Disadvantages
Statistical sprites are faster than the traditional sprite methods and they generally require less code, but there are still some disadvantages to using them over the other techniques. After coordinates get updated, the sprite needs to be redisplayed with the DispGraph command; unfortunately, because of the way the Plot#( commands work, this also causes the graph screen to be erased every time! This makes it almost impossible for them to be used in action games or other speed-intensive settings, but they are handy for drawings that don't need to be updated regularly, such as in a splash screen or title screen.
Greyscale
Greyscale is the use of two or more pictures to create a greyscale effect. On and Off tells what the pixel state would be on what pic
| pic1 | pic2 | pic3 | result |
|---|---|---|---|
| off | off | off | white |
| on | off | off | light grey |
| on | off | on | dark grey |
| on | on | on | black |
The N here is the one of the finance app.
1→N
Repeat getKey
While N≠4
real(3,N,0,1
N+1→N
End
1→N
End
This code is the fastest that I could think of to make greyscale. This code uses xLIB. "real(3,ℕ,0,1" By using xLIB, it makes it really fast.
Caching
Caching is the use of picture variable to store the initial game screen when it is first created. For example, you would create the level using whatever technique you want, and then storepic( to one of the picture variables. The advantage of caching is that it allows you to be as destructive in your graphics as you want, because you always have a backup copy of the original.
Lets look at a real word example.
Lets say you are making a graph screen based platform game where your character can climb up ladders. When your character moves over a ladder, it essentially covers up a section of the terrain. When you move your character again and erase the previous position, you would also erase the section of terrain (ie: the ladder) and it would be gone. Using caching, this problem would be solved by recalling the picture and restoring the terrain completely. This works because RecallPic() uses OR logic. Which means the picture will be 'laid' over the existing graph screen.