;*************************************************************** ; ; Sprite With Collision Prevention and pfrowheight=7 ; ; Example program by Duane Alan Hahn (Random Terrain) using ; hints, tips, code snippets, and more from AtariAge members ; such as batari, SeaGtGruff, RevEng, Robert M, Nukey Shay, ; Atarius Maximus, jrok, supercat, GroovyBee, and bogax. ; ;``````````````````````````````````````````````````````````````` ; ; Instructions: ; ; Use the joystick to move the sprite. Press the reset switch ; to reset the program and toggle between two screens. Notice ; how the sprite smoothly glides along the walls when the ; sprite is moved diagonally. It doesn't stick or bounce. ; ;``````````````````````````````````````````````````````````````` ; ; If this program will not compile for you, get the latest ; version of batari Basic: ; ; http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#gettingstarted ; ;*************************************************************** ;*************************************************************** ; ; Division and multiplication module. ; include div_mul.asm ;*************************************************************** ; ; Variable aliases go here (DIMs). ; ; You can have more than one alias for each variable. ; If you use different aliases for bit operations, ; it's easier to understand and remember what they do. ; ; I start variable aliases with one underscore so I won't ; have to worry that I might be using bB keywords by mistake. ; I also start labels with two underscores for the same ; reason. The second underscore also makes labels stand out ; so I can tell at a glance that they are labels and not ; variables. ; ; Use bit operations any time you need a simple off/on ; variable. One variable essentially becomes 8 smaller ; variables when you use bit operations. ; ; I start my bit aliases with "_Bit" then follow that ; with the bit number from 0 to 7, then another underscore ; and the name. Example: _Bit0_Reset_Restrainer ; ;``````````````````````````````````````````````````````````````` ; Bits that do various jobs. ; dim _BitOp_01 = y dim _Bit0_Reset_Restrainer = y dim _Bit4_Toggle_Screen = y ;``````````````````````````````````````````````````````````````` ; Makes better random numbers. ; dim rand16 = z ;*************************************************************** ; ; Defines the edges of the playfield for an 8 x 8 sprite. ; If your sprite is a different size, you`ll need to adjust ; the numbers. ; const _P_Edge_Top = 12 const _P_Edge_Bottom = 77 const _P_Edge_Left = 1 const _P_Edge_Right = 152 ;*************************************************************** ; ; Disables the score. (We don't need it in this program.) ; const noscore = 1 ;*************************************************************** ; ; Makes playfield pixels that aren't as tall. ; const pfrowheight=7 ;*************************************************************** ;*************************************************************** ; ; PROGRAM START/RESTART ; ; __Start_Restart ;*************************************************************** ; ; Mutes volume of both sound channels. ; AUDV0 = 0 : AUDV1 = 0 ;*************************************************************** ; ; Clears 24 of the normal 26 variables (fastest way). ; The variable y holds a bit that should not be cleared. The ; variable z is used for random numbers in this program and ; clearing it would mess up those random numbers. ; asm LDA #0 STA a STA b STA c STA d STA e STA f STA g STA h STA i STA j STA k STA l STA m STA n STA o STA p STA q STA r STA s STA t STA u STA v STA w STA x end ;*************************************************************** ; ; Clears 7 of the 8 bits. The 4th bit toggles the playfield ; when the reset switch is pressed in this example, so we ; have to leave it alone. ; _BitOp_01 = _BitOp_01 & %00010000 ;*************************************************************** ; ; Sets starting position of player0. ; player0x = 77 : player0y = 48 ;*************************************************************** ; ; Sets playfield color. ; COLUPF = $2C ;*************************************************************** ; ; Sets background color. ; COLUBK = 0 ;*************************************************************** ; ; Restrains the reset switch for the main loop. ; ; This bit fixes it so the reset switch becomes inactive if ; it hasn't been released after being pressed once. ; _Bit0_Reset_Restrainer{0} = 1 ;*************************************************************** ; ; Defines shape of Player0 sprite. ; player0: %11111111 %11111111 %11111111 %11000011 %10111101 %11111111 %11011011 %11111111 %11111111 %11111111 %11111111 end ;*************************************************************** ; ; Toggles the playfield. ; _Bit4_Toggle_Screen = _Bit4_Toggle_Screen ^ %00010000 if _Bit4_Toggle_Screen{4} then goto __Skip_Playfield_01 playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X..............................X X..............................X X..XXX..XXXXXXX..XXXXXXX..XXX..X X..............................X X..............................X X..............................X X..XXX..XXXXXXX..XXXXXXX..XXX..X X..............................X X..............................X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end goto __Skip_Playfield_02 __Skip_Playfield_01 playfield: ................................ ................................ ....XXXXXXXXXX....XXXXXXXXXX.... ....X......................X.... ....X......................X.... ....X......................X.... ................................ ................................ ....XXXX....XXX..XXX....XXXX.... ................................ ................................ end __Skip_Playfield_02 ;*************************************************************** ;*************************************************************** ; ; MAIN LOOP (MAKES THE PROGRAM GO) ; ; __Main_Loop ;*************************************************************** ; ; Sets color of player0 sprite. ; COLUP0 = $9C ;*************************************************************** ; ; Joy0 up check. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if joystick isn't moved up. ; if !joy0up then goto __Skip_Joy0_Up ;``````````````````````````````````````````````````````````````` ; Skips this section if hitting the edge. ; if player0y <= _P_Edge_Top then goto __Skip_Joy0_Up ;``````````````````````````````````````````````````````````````` ; Stops movement if a playfield pixel is in the way. ; temp5 = (player0x-10)/4 temp6 = (player0y-12)/7 if temp5 < 34 then if pfread(temp5,temp6) then goto __Skip_Joy0_Up temp4 = (player0x-17)/4 if temp4 < 34 then if pfread(temp4,temp6) then goto __Skip_Joy0_Up temp3 = temp5 - 1 if temp3 < 34 then if pfread(temp3,temp6) then goto __Skip_Joy0_Up ;``````````````````````````````````````````````````````````````` ; Moves player0 up. ; player0y = player0y - 1 __Skip_Joy0_Up ;*************************************************************** ; ; Joy0 down check. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if joystick isn't moved down. ; if !joy0down then goto __Skip_Joy0_Down ;``````````````````````````````````````````````````````````````` ; Skips this section if hitting the edge. ; if player0y >= _P_Edge_Bottom then goto __Skip_Joy0_Down ;``````````````````````````````````````````````````````````````` ; Stops movement if a playfield pixel is in the way. ; temp5 = (player0x-10)/4 temp6 = (player0y)/7 if temp5 < 34 then if pfread(temp5,temp6) then goto __Skip_Joy0_Down temp4 = (player0x-17)/4 if temp4 < 34 then if pfread(temp4,temp6) then goto __Skip_Joy0_Down temp3 = temp5 - 1 if temp3 < 34 then if pfread(temp3,temp6) then goto __Skip_Joy0_Down ;``````````````````````````````````````````````````````````````` ; Moves player0 down. ; player0y = player0y + 1 __Skip_Joy0_Down ;*************************************************************** ; ; Joy0 left check. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if joystick isn't moved to the left. ; if !joy0left then goto __Skip_Joy0_Left ;``````````````````````````````````````````````````````````````` ; Skips this section if hitting the edge. ; if player0x <= _P_Edge_Left then goto __Skip_Joy0_Left ;``````````````````````````````````````````````````````````````` ; Stops movement if a playfield pixel is in the way. ; temp5 = (player0y-1)/7 temp6 = (player0x-18)/4 if temp6 < 34 then if pfread(temp6,temp5) then goto __Skip_Joy0_Left temp3 = (player0y-8)/7 if temp6 < 34 then if pfread(temp6,temp3) then goto __Skip_Joy0_Left temp3 = (player0y-11)/7 if temp6 < 34 then if pfread(temp6,temp3) then goto __Skip_Joy0_Left ;``````````````````````````````````````````````````````````````` ; Moves player0 left. ; player0x = player0x - 1 __Skip_Joy0_Left ;*************************************************************** ; ; Joy0 right check. ; ;``````````````````````````````````````````````````````````````` ; Skips this section if joystick isn't moved to the right. ; if !joy0right then goto __Skip_Joy0_Right ;``````````````````````````````````````````````````````````````` ; Skips this section if hitting the edge. ; if player0x >= _P_Edge_Right then goto __Skip_Joy0_Right ;``````````````````````````````````````````````````````````````` ; Stops movement if a playfield pixel is in the way. ; temp5 = (player0y-1)/7 temp6 = (player0x-9)/4 if temp6 < 34 then if pfread(temp6,temp5) then goto __Skip_Joy0_Right temp3 = (player0y-8)/7 if temp6 < 34 then if pfread(temp6,temp3) then goto __Skip_Joy0_Right temp3 = (player0y-11)/7 if temp6 < 34 then if pfread(temp6,temp3) then goto __Skip_Joy0_Right ;``````````````````````````````````````````````````````````````` ; Moves player0 right. ; player0x = player0x + 1 __Skip_Joy0_Right ;*************************************************************** ; ; Displays the screen. ; drawscreen ;*************************************************************** ; ; Reset switch check and end of main loop. ; ; Any Atari 2600 program should restart when the reset ; switch is pressed. It is part of the usual standards ; and procedures. ; ;``````````````````````````````````````````````````````````````` ; Turns off reset restrainer bit and jumps to beginning of ; main loop if the reset switch is not pressed. ; if !switchreset then _Bit0_Reset_Restrainer{0} = 0 : goto __Main_Loop ;``````````````````````````````````````````````````````````````` ; Jumps to beginning of main loop if the reset switch hasn't ; been released after being pressed. ; if _Bit0_Reset_Restrainer{0} then goto __Main_Loop ;``````````````````````````````````````````````````````````````` ; Restarts the program. ; goto __Start_Restart