udamonic.com
  • Start
    • What is a Scamp?
    • Getting Started
    • Getting Started (Windows)
  • Learn
    • What is Forth?
    • Arithmetic
    • The Stack
    • Creating Words
    • Compilation Tricks
    • Decompilation
    • Comments
    • Characters and Strings
    • Accessing Memory
    • Constants, Variables and Values
    • Flow Control
    • Loops
    • Data Structures
    • Doubles, Triples and Quads
    • FlashForth Dictionary Reference
    • Scamp Dictionary Reference
  • Extras
    • Interrupts
    • Timers
    • Multitasking
    • Delays and Tick Count
    • Processor Words
    • Starting up with turnkey
    • Changing the Prompt
    • Formatting Text on Screen
  • Interfacing
    • Using the LED Array
    • Temperature Sensor
    • Input/Output
    • Analog Input
    • Serial >
      • Serial Communication
      • Scamp2 UART Pins
    • I2C >
      • I2C Overview
      • I2C Commands
    • SPI
    • PWM
    • Peripheral Pin Select
    • Input Capture
    • Digital Signal Modulator
  • Create
    • Creating PCBs >
      • Designing PCBs
      • Fabricating PCBs
      • Soldering
    • Sensing >
      • Measuring Temperature
    • LEDs >
      • Adding LEDs
      • LED arc-welder effect
    • Displays >
      • Adding a 7 Segment Display
      • Adding a Touch LCD
      • Touch LCD GUI
      • Game of Pong
    • Adding Extra GPIO
    • Adding a Low Side Switch
    • FizzBuzz
    • Adding MRAM
    • Model Train Control
    • Adding a Real Time Clock
    • Scamp Projects on Youtube
  • Resources
  • Store
  • About
  • Contact

Game of Pong
​

(... in less than 1K of compiled code)
With the Nextion NX3224K024 attached to the Scamp, we can create a simple game... the classic game of Pong.

For this, as well as the LCD you will need pot connected to pin 2 of your Scamp to use as a paddle/bat. You will also need the LCD words added to your Scamp's dictionary. 
Connect the center pin of your pot to pin 2 of the Scamp, and the left pin to GND and the right pin to 3V3​. Add a knob to your pot to make it nicer to use.
Picture

Source Code
​

For this game, we will use variables to store the current coordinates of the ball, the rate of movement of the ball in the x and y axes, the location of where the bat was, the location of where the bat now is, and a flag to indicate a miss.
variable ballx    \ ball x location
variable bally    \ ball y location
variable xdir     \ delta x
variable ydir     \ delta y
variable oldbat   \ previous bat location
variable newbat   \ current bat location
variable crash    \ flag 
The next word draws a yellow ($ff00​) paddle on the screen. It takes a value from the stack (y screen coordinate).
: paddle   ( y -- )
  $ff00 swap        \ swap color
  15 swap 40 swap   \ width height
  0 swap            \ x coord
  area              \ draw it
;  
You can test it by typing 50 paddle. Make sure you've run setbaud and 0 lcdcls first. 

The next word samples the pot for its current value and scales this 12-bit number down to the vertical screen size of the LCD (allowing for the height of the paddle). This value is then stored to the variable holding the current bat location. 
: gety              \ gets current location of bat
    sample 19 u/    \ scale it 
    dup 208 > if    \ if it's greater than 208
       drop 209     \ just make it 209
    then
    newbat !        \ store it the bat location variable
;   
The following word initializes everything for the game. It increases the baud rate of the LCD, sets up the analog input, clears the LCD with a black background and sets up the variables.
​: ponginit   
    fastbaud
    2 analog              \ control pot connected to pin 2
    2 channel
    0 lcdcls              \ clear the screen, black background
    gety                  \ initial y coord
    newbat @ oldbat !     
    newbat @ paddle       \ draw paddle at starting position
    100 ballx !           \ starting x position
    random 280 u/ bally ! \ random y position
    0 crash !             \ clear the miss flag
;  
Type ponginit to initialize things, so that you can test as you go.

Next we create a word to clear the screen and display "GAME OVER" in red letters.
: gameover      \ clear screen and print "GAME OVER"
    0 lcdcls
    lcd 
    ." xstr 80,100,150,40,0,RED,BLACK,1,1,1,"
    34 emit 
    ." GAME OVER" 
    34 emit 
    eoc console 
; 
Type gameover and you should see a message appear on the screen.

As the bat moves we need to erase the pixels of the bat at its previous location. Since the bat lives in the left most part of the screen, we can cheat and just draw black rectangles above and below the current bat location. This word does just that:
: erasebat                      \ removes old bat 
       newbat @ 209 < if        \ if not at bottom erase below
         0                      \ color
         15                     \ width
         239 newbat @ 40 + -    \ required height
         0                      \ x
         newbat @ 40 +          \ y
         area
      then 
      newbat @ 0 > if           \ if not at top erase above
         0                      \ color
         15                     \ width
         newbat @  1 -          \ required height
         0                      \ x
         0                      \ y starting pos
         area
      then 
; 
The next three words draw the bat and ball at their current positions, and erase the ball. 
: bat                     \ draw the bat
    gety                  \ read pot
    newbat @ oldbat @     \ compare with previous position
    <> if                 \ bat has moved?
       newbat @ 
       dup paddle         \ draw bat at new position
       erasebat           \ erase old bat pixels
       oldbat !           \ set to the (new) old position
    then
; 

: ball                    \ draw the ball
     $ffff                \ ball color
     5                    \ radius
     ballx @ bally @      \ get location
     filledcircle
; 

: eraseball               \ draw black ball to erase old one
     0 5 ballx @ bally @ filledcircle
; 
Next we need words to update the ball location:
: movex                 \ new ball x position
    xdir @ ballx @ + 
    dup
    11 314 within       \ check it's within valid boundaries
    if
       ballx !
    else                \ change direction
       drop
       xdir @ negate xdir ! 
    then 
 ;

: movey                 \ new ball y position
    ydir @ bally @ + 
    dup
    6 234 within        \ check it's within valid boundaries
    if
       bally !
    else                \ change direction
       drop
       ydir @ negate ydir !  
    then 
; 
If we're at the left side of the screen, we need to check if the bat is within the same y location. This word does that:
: miss?
    ballx @ 25 <           \ if we're at the left side
    if
       bally @             \ get current y location of ball 
       newbat @ 10 - dup   \ next to the bat?
       50 + within 0=
       if                  \ no
          1 crash !        \ flag a miss
          7 emit           \ beep
          gameover         \ print game over
       then
    then
;   
Putting it all together:
: pong                     \ the game
   ponginit                \ set everything up
   10 xdir !               \ ball speed in x direction
   5 ydir !                \ ball speed in x direction
   1500 ms 7 emit          \ wait 1.5 secs then beep
   begin
      bat                  \ draw the bat
      eraseball            \ erase the old ball
      movex movey ball     \ move the ball and draw it
      miss?                \ was it a miss?
   crash @ key? or until   \ keep going until a miss or key press
;   
 
To run, type pong at the prompt.

​This is a very quick version. Experiment with the code. I'm sure you can polish it to make it even better. 

​And just note that the entire game only uses 874 bytes of flash and 14 bytes of RAM. Forth is very efficient!

Site powered by Weebly. Managed by Hostwinds
  • Start
    • What is a Scamp?
    • Getting Started
    • Getting Started (Windows)
  • Learn
    • What is Forth?
    • Arithmetic
    • The Stack
    • Creating Words
    • Compilation Tricks
    • Decompilation
    • Comments
    • Characters and Strings
    • Accessing Memory
    • Constants, Variables and Values
    • Flow Control
    • Loops
    • Data Structures
    • Doubles, Triples and Quads
    • FlashForth Dictionary Reference
    • Scamp Dictionary Reference
  • Extras
    • Interrupts
    • Timers
    • Multitasking
    • Delays and Tick Count
    • Processor Words
    • Starting up with turnkey
    • Changing the Prompt
    • Formatting Text on Screen
  • Interfacing
    • Using the LED Array
    • Temperature Sensor
    • Input/Output
    • Analog Input
    • Serial >
      • Serial Communication
      • Scamp2 UART Pins
    • I2C >
      • I2C Overview
      • I2C Commands
    • SPI
    • PWM
    • Peripheral Pin Select
    • Input Capture
    • Digital Signal Modulator
  • Create
    • Creating PCBs >
      • Designing PCBs
      • Fabricating PCBs
      • Soldering
    • Sensing >
      • Measuring Temperature
    • LEDs >
      • Adding LEDs
      • LED arc-welder effect
    • Displays >
      • Adding a 7 Segment Display
      • Adding a Touch LCD
      • Touch LCD GUI
      • Game of Pong
    • Adding Extra GPIO
    • Adding a Low Side Switch
    • FizzBuzz
    • Adding MRAM
    • Model Train Control
    • Adding a Real Time Clock
    • Scamp Projects on Youtube
  • Resources
  • Store
  • About
  • Contact