You're browsing the old v2.x documentation. This version is no longer maintained. Click here to go the v3.x documentation.

Step 3.3.1: The update loop

This loop is responsive for a updating the falling piece as long as it doesn't hit the bottom. Its algorithm is very simple:

  1. Draw the piece
  2. Check if there was input from joystick
  3. Check if move is possible
  4. If possible, move piece
  5. Do the above 3 more times
  6. Fall the piece by one position if possible or exit if not

Please read the following code. We'll discuss it bellow.

REM -- The update loop
  REM -- Draw the shape
  CALL draw_shape(shape, piece_x!, piece_y!, shape_color!, 1)
  REM -- The player has four chances to move the piece
  REM -- before it falls one position
  FOR i! = 0 TO 3
    REM -- Check if there's input from joystick
    IF PEEK!(JOY_PORT1) <> 255 THEN
      REM -- Copy piece position to temp variables to be able
      REM -- to check for overlapping without actually
      REM -- updating the piece
      tmp_x! = piece_x! : tmp_y! = piece_y! : tmp_r! = piece_r!
      REM -- Check what input comes from joystick
      IF joy_1_left!()  = 1 THEN DEC tmp_x!
      IF joy_1_right!() = 1 THEN INC tmp_x!
      IF joy_1_down!()  = 1 THEN INC tmp_y!
      IF joy_1_fire!()  = 1 THEN \tmp_r! = (\piece_r! + 1) & %00000011
      REM -- Check if move is possible
      IF overlaps!(shape_no!, tmp_r!, tmp_x!, tmp_y!) = 0 THEN
        REM -- It is possible, erase the piece off of screen
        CALL draw_shape(shape, piece_x!, piece_y!, shape_color!, 0)      
        REM -- Update piece position and shape and draw again
        piece_x! = tmp_x! : piece_y! = tmp_y! : piece_r! = tmp_r!
        shape = get_shape(shape_no!, piece_r!)
        CALL draw_shape(shape, piece_x!, piece_y!, shape_color!, 1)      
    FOR j! = 0 TO delay! : WATCH VICII_RASTER, 255 : NEXT
  REM -- Erase the shape
  CALL draw_shape(shape, piece_x!, piece_y!, shape_color!, 0)
  REM -- Fall piece by one
  INC piece_y!
UNTIL overlaps!(shape_no!, piece_r!, piece_x!, piece_y!) = 1

The code is wrapped in a REPEAT ... UNTIL block that means it is a post-test loop. The loop is executed at least once, checking the exit condition at the end. If the condition evaluates to true, the loop exits immediately.

The CALL statement calls a procedure.

We haven't defined the constant JOY_PORT1 and there are no such functions in XC=BASIC as joy_1_left!(). This is because these are not part of the XC=BASIC core language but provided by an external library, or extension. Here's what you need to do before being able to use joystic functions:

  • Download the file xcb-ext-joystick.bas from GitHub and put it in a directory that's accessible from within the source file's directory. For example if the path to your source file is /home/mark/xcbasic-tutorial/tetris.bas then you might want to add the extension to /home/mark/xcbasic-tutorial/inc/xcb-ext-joystick.bas
  • Use the INCLUDE statement to read the extension and make it part of your program:
REM -- Put this line at the top of your program
INCLUDE "inc/xcb-ext-joystick.bas"

The path specified in the INCLUDE statement must be a path relative to the current source file.

All the rest should be straigth forward. We have only implemented what we previously designed using calls to the procedures previously defined.