;*************************************************************** ; ; Multiple Sprites with Missile ; Kernel Option multisprite ; ; 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 fire button ; to shoot the missile. ; ;``````````````````````````````````````````````````````````````` ; ; 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 ; ;*************************************************************** ;*************************************************************** ; ; Batari Basic Programing Page / Tips ; Page maintained by Randon Terrain (RT) ; ; http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html ; ;``````````````````````````````````````````````````````````````` ;*************************************************************** ; ; Atari Age Batari Basic Forum ; This forum is excellent to post and search for answers to programming problems ; ; http://atariage.com/forums/forum/65-batari-basic/ ; ;``````````````````````````````````````````````````````````````` ;*************************************************************** ; ; Kernel setup. ; includesfile multisprite_bankswitch.inc set tv ntsc set kernel multisprite set romsize 8k set kernel_options player1colors set optimization speed set smartbranching on set optimization noinlinedata set optimization inlinerand include fixed_point_math.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 ; dim jf = a dim p0x = player0x.b ;*************************************************************** ; ; variable "c" is in use for joy0 position check ; dim p0v = d.e dim __var1 = f dim __var2 = g ;*************************************************************** ; ; variable "h" is in use for joy0 fire check ; ;*************************************************************** ; ; temp1/2 in use ; dim colidx = temp1 dim cscon = temp2 ;``````````````````````````````````````````````````````````````` ; "screenheight" ; At this time, the only supported values are 80 and 84, and 80 only works ; for row heights < 8 while 84 only works for row heights < 4. Other values ; for screenheight may be allowed in the future. If you try to use other values ; now, strange things may happen. ; ; "pfheight" ; pfheight is a special variable that specifies the height of ; playfield blocks, minus one. Acceptable values are 31, 15, 7, 3, 1, and 0. ; However pfheight 0 doesn't work properly when sprites are on the screen, ; so it's probably only useful for static displays like title screens. ; ;const screenheight=80 ;pfheight=7 ;*************************************************************** ; ; Clears all normal variables and old playfield variables ; (fastest way). ; a = 0 : b = 0 : c = 0 : d = 0 : e = 0 : f = 0 : g = 0 : h = 0 : i = 0 j = 0 : k = 0 : l = 0 : m = 0 : n = 0 : o = 0 : p = 0 : q = 0 : r = 0 s = 0 : t = 0 : u = 0 : v = 0 : w = 0 : x = 0 : y = 0 : z = 0 ;*************************************************************** ; ; Displays the screen to avoid going over 262. ; drawscreen ;*************************************************************** ; ; Defines shape of player0/1 sprite. ; gosub __Player_L player0: %00000000 %00000000 %00000000 %00000000 %00000000 %00011000 %10111101 %01100110 end ;*************************************************************** ; ; Sets starting position of player0/1 ; player1x = 76 : player1y = 76 p0x = 56 : player0y = 20 jf = $83 : p0v = 0 __var1 = $55 : h =1 ;*************************************************************** ;*************************************************************** ; ; MAIN LOOP (MAKES THE PROGRAM GO) ; ; __Main_Loop ;*************************************************************** ; ; Sets colors. ; COLUP0 = $08 : COLUP1 = $BA : _COLUP1 = $1A : COLUBK= 0 : COLUPF = $4A ;*************************************************************** ; ; get the current sprite configuration ; cscon = jf & $03 if !collision(player0, ball) then no_collision ;*************************************************************** ; ; there are only four possible configurations for player0 ; single copy, near right copy, far right or thee copies ; there will always be a sprite in the left position ; if the left sprite is hit we'll need to adjust player0x ; by either one or two positions to the left and change NUSIZ0 ; to the new configuration ; if the left sprite is not hit we only have to change NUSIZ0 ; there only two possible NUSIZ0 for a hit to a near right copy ; and they are the same as left hit if there are only two copies ; ie there will be one copy ; so we only have to deal (differently) with the case of a hit ; to a far right copy ; ;*************************************************************** ; ; colidx, collision index, which copy did we hit ; colidx = ((ballx - player0x)/4 & $0C) | cscon : bally = 0 if !cscon then jf = $83 : p0x = 56 : p0v = 0.25 : goto no_collision jf = (jf & $40) | scon[colidx] ;*************************************************************** ; ; if position 0 ; if colidx < 4 then player0x = player0x + pos0[cscon] no_collision ;*************************************************************** ; ; remember joy0 position for firing position ; if joy0up then c{1}=1:c{2}=0:c{3}=0:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 if joy0down then c{1}=0:c{2}=1:c{3}=0:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 if joy0left then c{1}=0:c{2}=0:c{3}=1:c{4}=0:c{5}=0:c{6}=0:c{7}=0:c{0}=0 if joy0right then c{1}=0:c{2}=0:c{3}=0:c{4}=1:c{5}=0:c{6}=0:c{7}=0:c{0}=0 ;*************************************************************** ; ; shots up ; if joy0fire && jf && c{1} then ballx = player1x - 4 : bally = player1y - 4 : jf{7} = 0 : h = 0 : then __Missile_U ;*************************************************************** ; ; shoots down ; if joy0fire && jf && c{2} then ballx = player1x - 4 : bally = player1y - 4 : jf{7} = 0 : h = 1 : then __Missile_D ;*************************************************************** ; ; shoots left ; if joy0fire && jf && c{3} then ballx = player1x - 4 : bally = player1y - 4 : jf{7} = 0 : h = 2 : then __Missile_L ;*************************************************************** ; ; shots right ; if joy0fire && jf && c{4} then ballx = player1x - 4 : bally = player1y - 4 : jf{7} = 0 : h = 3 : then __Missile_R ;*************************************************************** ; ; Moves player0 sprite with the joystick while keeping the ; sprite within the playfield area. ; if joy0left && player1x > 20 then player1x = player1x - 1 : gosub __Player_L if joy0right && player1x < 146 then player1x = player1x + 1 : gosub __Player_R if joy0down && player1y > 10 then player1y = player1y - 1 : gosub __Player_D if joy0up && player1y < 76 then player1y = player1y + 1 : gosub __Player_U ;*************************************************************** ; ; left and right boundries for missiles ; if ballx = 20 then bally = 200 if ballx = 146 then bally = 200 ;*************************************************************** ; Determine which way the missile will go ; __Missile_R if jf{7} then skip_missile if h=2 then ballx = ballx - 1 if !bally then jf{7} = 1 __Missile_L if jf{7} then skip_missile if h=3 then ballx = ballx + 1 if !bally then jf{7} = 1 __Missile_U if jf{7} then skip_missile if h=0 then bally = bally + 1 if !bally then jf{7} = 1 __Missile_D if jf{7} then skip_missile if h=1 then bally = bally - 1 if !bally then jf{7} = 1 if ballx = 5 then bally = 200 if ballx = 140 then bally = 200 skip_missile if p0x > 10 && p0x < rlimit[cscon] then move_sprite ;*************************************************************** ; ; we're at a limit, flip the direction bit ; jf = jf ^ $40 ;*************************************************************** ; ; if the velocity is less than 4, accelerate ; if p0v < 4 then p0v = p0v + 0.04 move_sprite if jf{6} then p0x = p0x - p0v else p0x = p0x + p0v ;*************************************************************** ; ; change (jf & $03) | $06 to $0x and $m below to have correct NUSIZx ; example (jf & $06) | $03 is 3 close-spaced copies of player and missile. ; example (jf & $00) | $07 is Quad-sized player. ; RT Page will help select the code: ; http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#nusiz ; ; m = 0 1 pixel wide missile. ; m = 1 2 pixel wide missile. ; m = 2 4 pixel wide missile. ; m = 3 8 pixel wide missile. ; ; x = 0 1 copy of player and missile. ; x = 1 2 close-spaced copies of player and missile. ; x = 2 2 medium-spaced copies of player and missile. ; x = 3 3 close-spaced copies of player and missile. ; x = 4 2 wide-spaced copies of player and missile. ; x = 5 Double-sized player. ; x = 6 3 medium-spaced copies of player and missile. ; x = 7 Quad-sized player. ; NUSIZ0 = (jf & $00) | $07 NUSIZ1 = $10 __var2 = jf ;*************************************************************** ; ; Displays the screen. ; drawscreen goto __Main_Loop data rlimit 152, 136, 120, 120 end data scon $83, $80, $80, $81 $80, $80, $80, $82 $80, $80, $80, $81 end data pos0 $00, $10, $20, $10 end ;*************************************************************** ; ; Defines shape of player0/1 sprite. ; __Player_D player1: %00010000 %00111000 %01111100 %11111110 %00000000 %00000000 %00000000 %00000000 end return __Player_U player1: %11111110 %01111100 %00111000 %00010000 %00000000 %00000000 %00000000 %00000000 end return __Player_R player1: %00100000 %00110000 %00111000 %00111100 %00111000 %00110000 %00100000 %00000000 end return __Player_L player1: %00000100 %00001100 %00011100 %00111100 %00011100 %00001100 %00000100 %00000000 end return