1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 | # Pong game on Raspberry Pi Pico with a OLED and two Potentimeters
from machine import Pin, PWM, SPI
import ssd1306
from utime import sleep
import random # random direction for new ball
spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi=machine.SPI(0,baudrate=100000,sck=spi_sck, mosi=spi_tx)
CS = machine.Pin(1)
DC = machine.Pin(4)
RES = machine.Pin(5)
oled = ssd1306.SSD1306_SPI(128, 64, spi, DC, RES, CS)
# connect the center tops of the potentiometers to ADC0 and ADC1
pot_pin_1 = machine.ADC(26)
pot_pin_2 = machine.ADC(26) # 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 = 8
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(1000)
speaker.freq(900)
sleep(.25)
speaker.duty_u16(0)
def play_score_sound():
speaker.duty_u16(1000)
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 vale and a range between high-and-low and returns it scaled to the new range
# This is similar to the Arduino map() function
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
while True:
oled.fill(0) # clear screen
oled.vline(int(WIDTH / 2), 0, HEIGHT, 1)
# border(WIDTH, HEIGHT)
# read both the pot values
pot_val_1 = pot_pin_1.read_u16()
pot_val_2 = pot_pin_1.read_u16()
# print(pot_val_1)
# scale the values from the max value of the input is a 2^16 or 65536 to 0 to HEIGHT - PAD_HEIGHT
# ideally, it should range from 5 to 58
pot_val_1 = valmap(pot_val_1, POT_MIN, POT_MAX, HALF_PAD_HEIGHT, HEIGHT - HALF_PAD_HEIGHT - 2)
pot_val_2 = valmap(pot_val_2, POT_MIN, POT_MAX, HALF_PAD_HEIGHT, HEIGHT - HALF_PAD_HEIGHT - 2)
# print(pot_val, pot_scaled)
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
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
if ball_y > top_paddle and ball_y < bottom_paddle:
ball_x_dir = -1
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)
oled.show()
|