A Commodore 64 sprite is made up of small pixels, can have up to 16 colors, can travel over the background, travel up/down/left/right, be multiple sizes, detect collisions, and so much more. This section will introduce sprites and show how to create one.
Our Commodore 64 sprite has a width of 24 pixels and a height of 22. This provides the Commodore 64 programming with the ability to create a very defined sprite. We will now demonstrate how to create one in memory.
Below is a screenshot from the book Commodore 64C system guide, which came bundled with the earlier Commodore 64C computers. The picture is from page 81 and shows an example sprite.
For our example however, we will be creating a mouse found in the book Commodore 64 Programmer’s Reference Guide on page 167. The modified code for our Commodore 64 sprite is listed below.
20 fors1=12288to12350:readq1:pokes1,q1:n ext
25 fors2=12352to12414:readq2:pokes2,q2:n ext
30 fors3=12416to12478:readq3:pokes3,q3:n ext 35 pokev+39,15:pokev+1,68
40 printtab(160)”i am the dancing mouse! ”
50 forx=0to347step3 55 rx=int(x/256):lx=x-rx*256
100 data30,0,120,63,0,252,127,129,254,12 7,129,254,127,189,254,127,255,254
101 data63,255,252,31,187,248,3,187,192, 1,255,128,3,189,192,1,231,128,1,255,0
102 data31,255,0,0,124,0,0,254,0,1,199,3 2,3,131,224,7,1,192,1,192,0,3,192,0
103 data30,0,120,63,0,252,127,129,254,12 7,129,254,127,189,254,127,255,254
104 data63,255,252,31,221,248,3,221,192, 1,255,128,3,255,192,1,195,128,1,231,3
105 data31,255,255,0,124,0,0,254,0,1,199 ,0,7,1,128,7,0,204,1,128,124,7,128,56
106 data30,0,120,63,0,252,127,129,254,12 7,129,254,127,189,254,127,255,254
107 data63,255,252,31,221,248,3,221,192, 1,255,134,3,189,204,1,199,152,1,255,48
109 data7,14,0,204,14,0,248,56,0,112,112 ,0,0,60,0,+1
Starting with line 10. The print chr$(147) clears all the data from the Commodore 64 screen. Then a variable of V is created to hold the value of 53248. This defines the start of VIC chip (Video Interface Controller). Next the variable p is initialized to 192 (explained later). Then we use pokev+21,1 (53269,1) which is the Sprite Enable Register. Placing a 1 here activates Bit 1 which turns on sprite #1. This is so we can visibly see the sprite on the screen.
In line 20 we have fors1=12288to12350:readq1:pokes1,q1:next. This cycles through memory locations 12288 to 12350 which is used to store the sprite data that will be displayed on the screen. The readq1 begins reading at the first data statement. The pokes1,q1 stores that data into the sprite shape area. Finally the next wraps up the loop to continue the next iteration. Lines 25 and 30 continue the rest of the sprite data reading section.
The next line pokev+39,15:pokev+1,68. Then pokev+39,15 (53287) defines the color for Sprite 0. Next pokev+1,68 (53249) positions sprite 0 in the vertical position, which is 68 pixels from the top.
After this printtab(160)”I am the dancing mouse!” prints the message “I am the dancing mouse” on the screen tabbed over 160 spaces to center the text.
Line 50 shows forx=0to347step3. This creates a loop that counts by 3 from 0 to 347. This is used to expanse the sprite completely across the screen.
Line 55 shows rx=int(x/256):lx=x-rx*256. This is used to extract the low and high bytes of horizontal position. This is necessary since when the sprite reaches position 255 to cross over that boundry the most significant bit of the sprite must be set so the sprite can continue to move to the right. More on that later.
Line 60 shows pokev,lx:pokev+16,rx. This is translated as poke53248,lx;poke53264,rx. As mentioned earlier this extracts the low byte into memory location 53248 which controls the horizontal movement. It is used to determine the distance in pixels the sprite is moving to the right. The memory location 53264 is where the Most Significant Bit of the Sprite 0’s horizontal position is calculated. This allows the sprite to finally cross that gap beyond 255. When memory location 53264 is set to 1 the bit in memory location 53248 is reset back to 0 which allows the sprite to continue from that area to travel across the rest of the screen.
Line 80 shows poke2040,p:fort=1to60:next. The poke2040,p defines Sprite Shape Data Pointer for our sprite. This locates the sprite in memory. This data block calculates the sprite read into memory locations 12288 and forward by using this formula 64*192 = 12288. The value 192 is defined in the next section of code.
Line 85 shows p=p+1:ifp>194thenp=192. This is a simple loop that counts from 192 through 194. After the value is greater than 194 (>194) the loops resets the variable back to 192. Much earlier this was defined in line 10 and set the p variable equal to 192. The purpose of this code is to track the animation frames of the sprite which are read into memory location 2040 (Sprite Shape Data Pointer) to switch out the alternating frames. This creates a nice illusion since the frames shift very quickly. Finally in line 90 the next loop completes the x loop to begin the next sprite movement. Then the END shuts down the game. Everything beyond this is the shape data for all of the mouse’s animation frames.
In closing, the video below demonstrates this program in action. I also explain how to expand the sprite vertically and horizontally as an extra bonus.