!  A game of colored balls.
!
!     Every time you bounce a ball off a wall of the same color, the red 
!  score-line at the bottom of the screen will advance by a little.  
!  Every time you bounce a ball off a different-colored wall, the
!  score-line will retreat.  To win, advance the score line all the way
!  to the right edge of the screen.
!
!    This game demonstrates the use of the Developer's Toolkit animation
!  routines.  It uses only Sprite-type objects.  There are two tricky 
!  things to watch for when reading this program.  First, we use sprites
!  for one paddle and up to three balls.  Since the balls must be
!  able to change color independently, we use sprites 1, 3 and 5 (which
!  don't share colors with each other).  This leaves no independent
!  sprite for the paddle (since 6 and 7 are unavailable, as usual).  So
!  we use sprite 2 for the paddle, but use only colors 1 and 2 in the
!  paddle image.  Then we change only color 3 to change the color of the
!  balls.  This way, the image of the paddle won't change color when we 
!  change the color of the ball that shares colors with it.  Whew!
!
!     The other trick is that the left border (object 1) is in color 1 and
!  the right border (object 2) is in color 2.  So we save time by using 
!  object numbers as color numbers when testing for collisions with 
!  identically-colored walls.
!
LIBRARY "libs/animate*","libs/amiga*"
DECLARE DEF makesprite

DIM balls(0:7)                    ! table of ball object numbers
DIM colors(0:7)                   ! matching table of current ball colors

SET mode "low4"
RANDOMIZE

LET screenwidth = 320*32-1        ! animation uses thirty-seconds of a pixel
LET screenheight = 200*32-1

SET window 0,screenwidth,screenheight,0     ! so do we

SET color mix (0) 1,1,1           ! background
SET color mix (1) 0,1,0           ! left wall
SET color mix (2) .5,0,1          ! right wall
SET color mix (3) 1,0,0           ! score line

LET ballwidth = 10*32             ! parameters for object sizes
LET ballheight = 6*32
LET paddlewidth = 10*32
LET halfpaddlewidth = paddlewidth/2
LET paddleheight = 20*32
LET xmin = 6*32                   ! borders for animation 
LET xmax = 314*32
LET ymin = 5*32
LET ymax = 195*32

CALL initanimation                ! initialize animation routines
CALL makestrings(ball$,paddle$)   ! make BOX KEEP strings ball$ and paddle$
CALL makepaddle(paddle)           ! make paddle object
LET nextball = 1
CALL addball                      ! add the first ball -- sprite 1, color 1

SET color 1
BOX AREA 0,xmin,0,ymax            ! draw left wall
SET color 2
BOX AREA xmax,screenwidth,0,ymax  ! draw right wall
CALL setborder(xmin,xmax,ymin,ymax)    ! set collision border

CALL changescore(128*32)          ! initial score (nearly halfway there)

DO

   CALL animate_all(-1,vs1,vs2)   ! animate until there's a collision
   IF vs1 = paddle then LET vs1 = vs2  ! make vs1 the ball object
   FOR i = 1 to 5 step 2          ! get number of this ball
       IF balls(i) = vs1 then EXIT FOR
   NEXT i
   CALL getob_vel(vs1,dx,dy)      ! get current x,y velocities

   SELECT CASE vs2                ! branch on what we hit
   CASE 1,2                       ! left or right wall
        IF colors(i) <> vs2 then  ! compare color# with border object#
           CALL changescore(-300)      ! bad hit
        ELSE
           CALL changescore(50)   ! good hit
        END IF
        IF rnd<.2 then CALL changecolor(i,vs1)   ! flip color sometimes
        LET dx = -dx              ! bounce off wall
   CASE 3,4                       ! top or bottom wall
        LET dy = -dy              ! bounce off wall
   CASE else                      ! paddle
        CALL getob_loc(vs1,x,y)   ! get location too
        CALL getob_loc(paddle,px,py)   ! and location of paddle
        IF x-px > halfpaddlewidth then      ! ball closest to right side
           LET x = px+paddlewidth+1    ! pop ball to right of paddle
           LET dx = abs(dx)       ! x velocity will be positive
        ELSE                      ! ball closest to left side
           LET x = px-ballwidth-33     ! pop ball to left of paddle
           LET dx = -abs(dx)      ! x velocity will be negative
        END IF
        IF y <= ymin+1 then       ! make sure we're not above top border
           LET y = ymin+1
        ELSE if y >= ymax-ballheight-33 then     ! or below bottom border
           LET y = ymax-ballheight-33
        END IF
        LET dy = -dy              ! nothing tricky -- it's hard enough
        CALL setob_loc(vs1,x,y)   ! pop ball to new location
   END SELECT

   CALL setob_vel(vs1,dx,dy)      ! set adjusted velocity
   LET count = count + 1          ! count collisions
   IF (count>100 and nextball=3) or (count>300 and nextball=5) then
      CALL addball                ! add another ball
   END IF

LOOP until key input

CALL endanimation


SUB changescore(delta)
    IF delta>0 then SET color 3 else SET color 0
    BOX AREA score,score+delta,ymax,screenheight      ! change score
    LET score = score + delta     ! remember new score
    IF score < 0 then CALL youlose     ! lost
    IF score > screenwidth then CALL youwin      ! won
END SUB

SUB changecolor(i,sprite)
    IF colors(i) = 2 then         ! flip color from 2 to 1
       CALL setsprite_color(sprite,3,0,1,0)
       LET colors(i) = 1
    ELSE                          ! flip color from 1 to 2
       CALL setsprite_color(sprite,3,.5,0,1)
       LET colors(i) = 2
    END IF
END SUB

SUB addball
    LET colors(nextball) = 2      ! we'll flip to make balls start out color 1
    LET balls(nextball) = makesprite(ball$,nextball,10*32,100*32)
    CALL changecolor(nextball,balls(nextball))   ! set color 1
    CALL setob_mask(balls(nextball),1,2)    ! hits border, paddle
    CALL setob_vel(balls(nextball),32+int(16*rnd),16+int(16*rnd))
    CALL setsprite_color(balls(nextball),2,1,0,0)     ! set border color
    LET nextball = nextball+2     ! 1 to 3, 3 to 5, 5 to more-than-5
END SUB

SUB makepaddle(paddle)
    LET paddle = makesprite(paddle$,2,155*32,185*32)
    CALL setob_mask(paddle,2,0)   ! hits balls only
    CALL setob_mouse(paddle,0,1)  ! tracks mouse in y-axis only
    CALL setsprite_color(paddle,2,1,0,0)    ! border color same as sprites
END SUB

SUB makestrings(ball$,paddle$)
    SET color 1                   ! color 1, paddle only
    BOX AREA 0,paddlewidth,0,paddleheight
    SET color 2                   ! color 2, shared by balls and paddle
    BOX LINES 0,paddlewidth,0,paddleheight
    BOX KEEP 0,paddlewidth,0,paddleheight in paddle$
    BOX CLEAR 0,paddlewidth,0,paddleheight
    BOX CIRCLE 0,ballwidth,0,ballheight
    SET color 3                   ! color 3, balls only
    FLOOD ballwidth/2,ballheight/2
    BOX KEEP 0,ballwidth,0,ballheight in ball$
    BOX CLEAR 0,ballwidth,0,ballheight
END SUB

SUB youlose
    PAUSE 3
    CALL endanimation
    CLEAR
    SET color 2
    PLOT TEXT, at 100*32,100*32: "Sorry, you lose."
    STOP
END SUB

SUB youwin
    PAUSE 3
    CALL endanimation
    CLEAR
    SET color 2
    PLOT TEXT, at 65*32,100*32: "Congratulations, you win."
    STOP
END SUB

END
