# Pong game on Raspberry Pi Pico with a OLED and two Potentimeters
from machine import Pin, PWM, SPI, I2C
import ssd1306
from utime import sleep
import random # random direction for new ball

i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
CS = machine.Pin(1)
DC = machine.Pin(4)
RES = machine.Pin(5)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# connect the center tops of the potentiometers to ADC0 and ADC1
pot_pin_1 = machine.Pin(14, Pin.IN)
pot_pin_2 = machine.Pin(15, Pin.IN) # make them the same for testing

# lower right corner with USB connector on top
SPEAKER_PIN = 16
# create a Pulse Width Modulation Object on this pin
speaker = PWM(Pin(SPEAKER_PIN))

# globals variables
# static variables are constants are uppercase variable names
WIDTH = 128
HALF_WIDTH = int(WIDTH / 2)
HEIGHT = 64
HALF_HEIGHT = HEIGHT
BALL_SIZE = 3 # 2X2 pixels
PAD_WIDTH = 2
PAD_HEIGHT = 32
HALF_PAD_WIDTH = int(PAD_WIDTH / 2)
HALF_PAD_HEIGHT = int(PAD_HEIGHT / 2)
POT_MIN = 3000
POT_MAX = 65534
MAX_ADC_VALUE = 65534 # Maximum value from the Analog to Digital Converter is 2^16 - 1
# dynamic global variables use lowercase
paddle1_vel = 0
paddle2_vel = 0
l_score = 0
r_score = 0
# continiuous update of the paddle and ball
# play_startup_sound()
# start with the ball in the center
ball_x = int(WIDTH / 2)
ball_y = int(HEIGHT / 2)
# set the initial directinon to down to the right
ball_x_dir = 1
ball_y_dir = 1

def play_startup_sound():
    speaker.duty_u16(1000)
    speaker.freq(600)
    sleep(.25)
    speaker.freq(800)
    sleep(.25)
    speaker.freq(1200)
    sleep(.25)
    speaker.duty_u16(0)

def play_bounce_sound():
    speaker.duty_u16(2512)
    speaker.freq(1000)
    sleep(.25)
    speaker.duty_u16(0)

def play_score_sound():
    speaker.duty_u16(2512)
    speaker.freq(600)
    sleep(.25)
    speaker.freq(800)
    sleep(.25)
    speaker.duty_u16(0)

# note that OLEDs have problems with screen burn it - don't leave this on too long!
def border(WIDTH, HEIGHT):
    oled.rect(0, 0, WIDTH, HEIGHT, 1)


# Takes an input number value and a range between high-and-low and returns it scaled to the new range
def valmap(value, istart, istop, ostart, ostop):
  return int(ostart + (ostop - ostart) * ((value - istart) / (istop - istart)))

# draw a vertical bar
def draw_paddle(paddle_no, paddle_center):
    if paddle_no == 1:
         x = 0
    else:
         x = WIDTH - 2
    y = paddle_center - HALF_PAD_HEIGHT
    oled.fill_rect(x,  y, PAD_WIDTH, PAD_HEIGHT, 1) # fill with 1s

def draw_ball():
    oled.fill_rect(ball_x, ball_y, BALL_SIZE, BALL_SIZE, 1) # square balls for now

# The main event loop

pot_val_1=32
pot_val_2=32
while True:
    oled.fill(0) # clear screen
    oled.vline(int(WIDTH / 2), 0, HEIGHT,  1)
    # border(WIDTH, HEIGHT)
    # read both the pot values
    print("Player 1:",pot_val_1)
    print("Player 2:",pot_pin_2.value())
    
    pot_val_1+=1 if pot_pin_1.value() ==1 else -1
    if pot_val_1<0:
        pot_val_1=0
    elif pot_val_1+PAD_HEIGHT> 64:
        pot_val_1=64-PAD_HEIGHT
    
    pot_val_2+=1 if pot_pin_2.value() ==1 else -1
    if pot_val_2<0:
        pot_val_2=0
    elif pot_val_2+PAD_HEIGHT> 64:
        pot_val_2=64-PAD_HEIGHT
        

#     if ball_x_dir==-1:
#         pot_val_1 = ball_y- HALF_PAD_HEIGHT
#     else:
#         pot_val_2 = ball_y- HALF_PAD_HEIGHT

    draw_paddle(1, pot_val_1 + HALF_PAD_HEIGHT)
    draw_paddle(2, pot_val_2 + HALF_PAD_HEIGHT)
    draw_ball()

    #update ball position with the current directions
    ball_x = ball_x + ball_x_dir
    ball_y = ball_y + ball_y_dir

    # update the ball direction if we are at the top or bottom edge
    if ball_y < 0:
        ball_y_dir = 1
        #play_bounce_sound()
    if ball_y > HEIGHT - 3:
        ball_y_dir = -1
        #play_bounce_sound()

    # if it hits the paddle bounce else score
    if ball_x < 1:
#         top_paddle = pot_val_1 - HALF_PAD_HEIGHT
#         bottom_paddle = pot_val_1 + HALF_PAD_HEIGHT
        top_paddle = pot_val_1
        bottom_paddle = pot_val_1 + PAD_HEIGHT
        if ball_y >= top_paddle and ball_y <= bottom_paddle:
            # we have a hit
            ball_x_dir = 1
            ball_x = 2
            play_bounce_sound()
            print('paddle hit on left edge', pot_val_1, top_paddle, bottom_paddle)
        else:
            # we have a score for the right player
            play_score_sound()
            r_score += 1
            ball_x = int(WIDTH / 2)
            ball_y = int(HEIGHT / 2)
            ball_x_dir = random.randint(-1, 2)
            if ball_x_dir == 0:
                ball_x_dir = 1
            ball_y_dir = random.randint(-1, 2)
            print('score on left edge', pot_val_1, top_paddle, bottom_paddle)
            sleep(.25)

    if ball_x > WIDTH - 3:
        ball_x = WIDTH - 4
#         top_paddle = pot_val_2 - HALF_PAD_HEIGHT
#         bottom_paddle = pot_val_2 + HALF_PAD_HEIGHT
        top_paddle = pot_val_2
        bottom_paddle = pot_val_2 + PAD_HEIGHT
        if ball_y > top_paddle and ball_y < bottom_paddle:
            ball_x_dir = -1
            play_bounce_sound()
            print('bounce on right paddle', pot_val_1, top_paddle, bottom_paddle)
        else:
            l_score += 1
            play_score_sound()
            ball_x = int(WIDTH / 2)
            ball_y = int(HEIGHT / 2)
            ball_x_dir = random.randint(-1, 2)
            if ball_x_dir == 0:
                ball_x_dir = 1
            ball_y_dir = random.randint(-1, 2)
            play_bounce_sound()
            print('score on right edge', pot_val_1, top_paddle, bottom_paddle)
            sleep(.25)

    oled.text(str(l_score), HALF_WIDTH - 20, 5, 1)

    oled.text(str(r_score), HALF_WIDTH + 5, 5, 1)
    sleep(.05)
    oled.show()
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT