#Neopixel
#https://docs.micropython.org/en/latest/library/neopixel.html
#https://docs.micropython.org/en/latest/esp8266/tutorial/neopixel.html
#Exemplo do uso de canvas: https://wokwi.com/projects/330751728413573715
#Outro exemplo: https://github.com/wokwi/wokwi-features/issues/237
#Exemplos da bilbioteca: https://wokwi.com/arduino/libraries/Adafruit_NeoPixel
#Tetris online: https://tetris.com/play-tetris
import time
import machine
import sys
from like_tetris import like_tetris
from like_snake import like_snake
from machine import Pin
from machine import ADC
from machine import Timer
import random
x = 0
y = 0
move = 'stop'
def ler_joystick(t):
global move #Faz aceso a variável global declarada fora do método
x = joyHor.read()
y = joyVer.read()
if x > 3000:
move = 'esquerda'
elif x < 1000:
move = 'direita'
elif y > 3000:
move = 'cima'
elif y < 1000:
move = 'baixo'
#else:
# move = 'stop'
#print('V =', y)
#print('H =', x)
#print('M =', move)
timer0 = Timer(0)
timer0.init(period=100, mode=Timer.PERIODIC, callback=ler_joystick)
def desenha_caractere(obj, carac, tam, cor):
#Caracteres do display de 7 segmentos
vetor = [
0x3F,
0x06,
0x5B,
0x4F,
0x66,
0x6D,
0x7D,
0x07,
0x7F,
0x6F,
0x77,
0x7C,
0x39,
0x5E,
0x79,
0x71,
]
#Segmentos 7x13
ag = [[1,0],[5,0]]
bg = [[6,1],[6,5]]
cg = [[6,7],[6,11]]
dg = [[1,12],[5,12]]
eg = [[0,7],[0,11]]
fg = [[0,1],[0,5]]
gg = [[1,6],[5,6]]
#Segmentos 6x11
am = [[1,0],[4,0]]
bm = [[5,1],[5,4]]
cm = [[5,6],[5,9]]
dm = [[1,10],[4,10]]
em = [[0,6],[0,9]]
fm = [[0,1],[0,4]]
gm = [[1,5],[4,5]]
#Segmentos 5x9
ap = [[1,0],[3,0]]
bp = [[4,1],[4,3]]
cp = [[4,5],[4,7]]
dp = [[1,8],[3,8]]
ep = [[0,5],[0,7]]
fp = [[0,1],[0,3]]
gp = [[1,4],[3,4]]
#Lista com os 3 tamanhos (G, M e P)
seg = [[ag,bg,cg,dg,eg,fg,gg],[am,bm,cm,dm,em,fm,gm],[ap,bp,cp,dp,ep,fp,gp]];
x = vetor[carac]
s = 0;
while x != 0:
if x & 0x01:
#obj.linha_od(seg[s][0], seg[s][1], cor, 1)
obj.linha_od(seg[tam][s][0], seg[tam][s][1], cor, 1)
x = x >> 1
s += 1
botaoEsq = Pin(34, Pin.IN, Pin.PULL_UP) #Pull-up interno não funcionou
botaoDir = Pin(21, Pin.IN, Pin.PULL_UP)
botaoRot = Pin(25, Pin.IN, Pin.PULL_UP)
botaoSel = Pin(35, Pin.IN, Pin.PULL_UP)
joyVer = ADC(Pin(32))
joyVer.atten(ADC.ATTN_11DB)
joyHor = ADC(Pin(33))
joyHor.atten(ADC.ATTN_11DB)
linhas = 15 #O objeto canvas no Wokwi só funciona com linhas pares
colunas = 10 #O objeto canvas no Wokwi só funciona com linhas pares
posicao = (0,0)
#tt = like_tetris(machine.Pin(4), colunas, linhas, "t_linha")
tt = like_tetris(machine.Pin(4), colunas, linhas, "t_linha_zig_zag")
tt.fill((0,0,0))
while True:
#Teste 1 - Desloca um pixel dentre os pontos de origem e destino por tempo
'''
tt.limpa_matriz((255,255,255))
time.sleep_ms(1000)
tt.desloca_od([9,12], [1,15], (255,255,255), (255,0,0), 100)
time.sleep_ms(100)
tt.desloca_od([1,12], [9,15], (255,255,255), (255,0,0), 100)
time.sleep_ms(100)
tt.desloca_od([1,5], [9,12], (255,255,255), (255,0,0), 100)
time.sleep_ms(100)
#Teste 2 - Desloca um ponto a partir da última posição (rodar com o teste 5)
tt.desloca_delta((0,1), (255,255,255), (0,255,0), 100)
tt.desloca_delta((0,1), (255,255,255), (0,255,0), 100)
tt.desloca_delta((0,1), (255,255,255), (0,255,0), 100)
#'''
#Teste 3 - Desenho de linhas usando origem e destino e delta
'''
tt.limpa_matriz((255,255,255))
time.sleep_ms(100)
tt.linha_od((0,0), (9,9), (255,0,0), 0)
tt.linha_delta((-9,9), (255,0,0), 0) #A classe salva a posição final da ultima linha
time.sleep_ms(100)
#'''
#Teste 4 - Desenha todos os modelos de blocos
'''
bloco = tt.cria_bloco((2,0),0,(255,0,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco((1,2),1,(255,0,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco((5,2),2,(255,0,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco((2,5),3,(255,0,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco((2,8),4,(255,0,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco((1,11),5,(255,0,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco((5,11),6,(255,0,0))
tt.desenha_bloco(bloco)
print(bloco)
time.sleep_ms(1000)
#'''
#Teste 5 - Deslocamento de bloco e verificação de fim da matriz
'''
bloco = tt.cria_bloco([0,0],2,(255,0,0))
while True:
if tt.desenha_bloco(bloco) == False:
print('Acabou a matriz')
bloco = tt.cria_bloco([0,0],2,(255,0,0))
print(bloco)
time.sleep_ms(100)
tt.apaga_bloco(bloco, (0,0,0))
bloco = tt.desloca_bloco(bloco, [1,1])
#'''
#Teste 6 - Testa deslocamento e ocupação de posição manual
'''
bloco = tt.cria_bloco([0,0],2,(255,255,0))
if tt.testa_ocupacao(bloco, (0,0,0)) == False:
tt.desenha_bloco(bloco)
time.sleep_ms(1000)
else:
print('FIM')
sys.exit()
while True:
#Desloca
bloco2 = tt.desloca_bloco(bloco, [0,1])
print('bloco =', bloco)
print('bloco2 =', bloco2)
#Apaga bloco1
tt.apaga_bloco(bloco, (0,0,0))
#Testa
if tt.testa_ocupacao(bloco2, (0,0,0)) == False:
#Desenha bloco2
tt.desenha_bloco(bloco2)
#Atualiza bloco
bloco = bloco2
#Atraso
time.sleep_ms(200)
else:
#Desenha bloco1 novamente
tt.desenha_bloco(bloco)
break
#'''
#Teste 7 - Testa deslocamento e ocupação de posição por método
'''
bloco = tt.cria_bloco([0,0],1,(255,0,0))
if tt.testa_ocupacao(bloco, (0,0,0)) == False:
tt.desenha_bloco(bloco)
time.sleep_ms(500)
estado = True
while estado == True:
print('blocoR =', bloco)
#Atraso
time.sleep_ms(200)
#Novo movimento
estado, bloco = tt.movimento_completo(bloco, (0,0,0))
#'''
#Teste 8 - Referência de listas
'''
bloco = [[0,0],[1,1]]
bloco2 = bloco
print('bloco =', bloco)
print('bloco2 =', bloco2)
bloco2[1] = [3,3]
print('bloco =', bloco)
print('bloco2 =', bloco2)
time.sleep_ms(20000)
#'''
#Teste 9 - Teste rotação dos blocos e choque com os limites da matriz
'''
bloco = tt.cria_bloco([0,0],0,(255,0,0))
bloco_aux = bloco
if tt.testa_ocupacao(bloco, (0,0,0)) == False:
tt.desenha_bloco(bloco)
time.sleep_ms(500)
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
estado = True
while estado == True:
print('blocoR =', bloco)
#Rotaciona o bloco
bloco = tt.rotaciona_bloco(bloco)
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco_aux = tt.ajusta_posicao_bloco(bloco)
#Desenha o bloco
#tt.desenha_bloco(bloco) #Bloco original
tt.desenha_bloco(bloco_aux) #Bloco ajustado
#Atraso
time.sleep_ms(500)
#Apaga o bloco auxiliar (importante quando tem ajuste de posição)
tt.apaga_bloco(bloco_aux, (0,0,0))
#'''
#Teste 10 - Mover um bloco por botões
'''
cor_fundo = (0,0,0)
tt.limpa_matriz(cor_fundo)
while True:
bloco = tt.cria_bloco([5,0],1,(255,255,0))
if tt.testa_ocupacao(bloco, (0,0,0)) == False:
tt.desenha_bloco(bloco)
time.sleep_ms(1000)
estado = True
while estado == True:
#Novo movimento
estado, bloco = tt.movimento_completo(bloco, cor_fundo)
if botaoEsq.value() == 0:
print('botaoEsq = 0') #Pull-up interno não funcionou
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Desloca
bloco = tt.desloca_bloco(bloco, [-1,0])
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco = tt.ajusta_posicao_bloco(bloco)
#Desenha o bloco
tt.desenha_bloco(bloco)
if botaoDir.value() == 0:
print('botaoDir = 0')
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Desloca
bloco = tt.desloca_bloco(bloco, [1,0])
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco = tt.ajusta_posicao_bloco(bloco)
#Desenha o bloco
tt.desenha_bloco(bloco)
if botaoRot.value() == 0:
print('botaoRot = 0')
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Rotaciona o bloco
bloco = tt.rotaciona_bloco(bloco)
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco_aux = tt.ajusta_posicao_bloco(bloco)
#Desenha o bloco
#tt.desenha_bloco(bloco) #Bloco original
tt.desenha_bloco(bloco_aux) #Bloco ajustado
time.sleep_ms(500)
print('Fim')
while True:
time.sleep_ms(500)
#'''
#Teste 11 - Mover um bloco por botões, novo ajuste
'''
cor_fundo = (0,0,0)
tt.limpa_matriz(cor_fundo)
#Pré-ocupa algumas linhas parcialmente
bloco = tt.cria_bloco([0,14],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([0,13],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([0,12],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([6,14],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([6,13],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([6,12],0,(255,255,0))
tt.desenha_bloco(bloco)
while True:
#1-Cria um novo bloco
bloco = tt.cria_bloco([5,0],0,(255,255,0))
#2-Teste se a posição já está ocupada
if tt.testa_ocupacao(bloco, (0,0,0)) == False:
tt.desenha_bloco(bloco)
time.sleep_ms(1000)
else:
print('FIM DO JOGO')
sys.exit()
#3-Inicia um loop de descida do bloco
estado = True
while estado == True:
#Debug - mostra o bloca a ser movido
print('bloco a ser movido =', bloco)
#Novo movimento
estado, bloco = tt.movimento_completo(bloco, cor_fundo)
#Atraso entre um novo movimento
time.sleep_ms(500)
#Testa se o movimento foi possível
if estado == False:
break #Interrompe o laço
#Testa os botões
#Botão esquerdo
if botaoEsq.value() == 0:
print('botaoEsq = 0') #Pull-up interno não funcionou
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Desloca
bloco2 = tt.desloca_bloco(bloco, [-1,0])
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco2 = tt.ajusta_posicao_bloco(bloco2)
#Testa
if tt.testa_ocupacao(bloco2, cor_fundo) == False:
#Desenha bloco2
tt.desenha_bloco(bloco2)
#Atualiza o bloco1
bloco = bloco2
else:
#Desenha bloco1
tt.desenha_bloco(bloco)
#Botão direito
if botaoDir.value() == 0:
print('botaoDir = 0')
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Desloca
bloco2 = tt.desloca_bloco(bloco, [+1,0])
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco2 = tt.ajusta_posicao_bloco(bloco2)
#Testa
if tt.testa_ocupacao(bloco2, cor_fundo) == False:
#Desenha bloco2
tt.desenha_bloco(bloco2)
#Atualiza o bloco1
bloco = bloco2
else:
#Desenha bloco1
tt.desenha_bloco(bloco)
#Botão de rotação
if botaoRot.value() == 0:
print('botaoRot = 0')
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Rotaciona o bloco
bloco2 = tt.rotaciona_bloco(bloco)
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco2 = tt.ajusta_posicao_bloco(bloco2)
#Testa
if tt.testa_ocupacao(bloco2, cor_fundo) == False:
#Desenha bloco2
tt.desenha_bloco(bloco2)
#Atualiza o bloco1
bloco = bloco2
else:
#Desenha bloco1
tt.desenha_bloco(bloco)
#4-Verifica o preenchimento de linhas
tt.testa_preenchimento_linha(cor_fundo)
#'''
#Teste 12 - Tetris completo - move bloco por botões com sorteio de tipo e cor
#'''
cor_fundo = (0,0,0)
tt.limpa_matriz(cor_fundo)
#Pré-ocupa algumas linhas parcialmente
bloco = tt.cria_bloco([0,14],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([0,13],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([0,12],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([6,14],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([6,13],0,(255,255,0))
tt.desenha_bloco(bloco)
bloco = tt.cria_bloco([6,12],0,(255,255,0))
tt.desenha_bloco(bloco)
while True:
#0-Sorteia o tipo de bloco e cor
tipo = random.randint(0,6)
cvm = random.randint(0,1) * 255
cvd = random.randint(0,1) * 255
caz = random.randint(0,1) * 255
if cvm==0 and cvd==0 and caz==0:
cvm = 255
cvd = 255
caz = 255
#1-Cria um novo bloco
bloco = tt.cria_bloco([5,0],tipo,(cvm,cvd,caz))
#2-Teste se a posição já está ocupada
if tt.testa_ocupacao(bloco, (0,0,0)) == False:
tt.desenha_bloco(bloco)
time.sleep_ms(1000)
else:
print('FIM DO JOGO')
sys.exit()
#3-Inicia um loop de descida do bloco
estado = True
while estado == True:
#Debug - mostra o bloca a ser movido
print('bloco a ser movido =', bloco)
#Novo movimento
estado, bloco = tt.movimento_completo(bloco, cor_fundo)
#Atraso entre um novo movimento
time.sleep_ms(500)
#Testa se o movimento foi possível
if estado == False:
break #Interrompe o laço
#Testa os botões
#Botão esquerdo
if botaoEsq.value() == 0:
print('botaoEsq = 0') #Pull-up interno não funcionou
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Desloca
bloco2 = tt.desloca_bloco(bloco, [-1,0])
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco2 = tt.ajusta_posicao_bloco(bloco2)
#Testa
if tt.testa_ocupacao(bloco2, cor_fundo) == False:
#Desenha bloco2
tt.desenha_bloco(bloco2)
#Atualiza o bloco1
bloco = bloco2
else:
#Desenha bloco1
tt.desenha_bloco(bloco)
#Botão esquerdo
if botaoDir.value() == 0:
print('botaoDir = 0')
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Desloca
bloco2 = tt.desloca_bloco(bloco, [+1,0])
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco2 = tt.ajusta_posicao_bloco(bloco2)
#Testa
if tt.testa_ocupacao(bloco2, cor_fundo) == False:
#Desenha bloco2
tt.desenha_bloco(bloco2)
#Atualiza o bloco1
bloco = bloco2
else:
#Desenha bloco1
tt.desenha_bloco(bloco)
#Botão de rotação
if botaoRot.value() == 0:
print('botaoRot = 0')
#Apaga o bloco
tt.apaga_bloco(bloco, (0,0,0))
#Rotaciona o bloco
bloco2 = tt.rotaciona_bloco(bloco)
#Faz ajuste de posição (testa se o bloco ficou partido em duas partes após
#rotacionar ou deslocar)
bloco2 = tt.ajusta_posicao_bloco(bloco2)
#Testa
if tt.testa_ocupacao(bloco2, cor_fundo) == False:
#Desenha bloco2
tt.desenha_bloco(bloco2)
#Atualiza o bloco1
bloco = bloco2
else:
#Desenha bloco1
tt.desenha_bloco(bloco)
#4-Verifica o preenchimento de linhas
tt.testa_preenchimento_linha(cor_fundo)
#'''
#Teste 13 - Caracteres
'''
cor_fundo = (0,0,0)
cores = [(255,0,0), (0,255,0), (0,0,255), (255,255,255)]
tt.limpa_matriz(cor_fundo)
tam = 0;
cor = 0;
while True:
carac = 0;
while carac<16:
tt.limpa_matriz(cor_fundo)
desenha_caractere(tt, carac, tam, cores[cor])
carac = carac+1
time.sleep_ms(200)
if botaoRot.value() == 0:
tam = (tam+1)%3
if botaoEsq.value() == 0:
cor = (cor+1)%4
cor = (cor+1)%4
#'''
#Teste 14 - Leitura do joystick
'''
cor_fundo = (0,0,0)
cores = [(255,0,0), (0,255,0), (0,0,255), (255,255,255)]
tt.limpa_matriz(cor_fundo)
tam = 0;
cor = 0;
while True:
print('Vertical = ', joyVer.read())
print('Horizontal = ', joyHor.read())
time.sleep_ms(300);
#'''
#Teste 15 - Teste Snake
'''
cor_cobra = (0,255,0)
cor_cabeca = (255,0,0)
cor_fruta = (0,0,255)
#(pino, col, lin, cor_cobra, cor_cabeca, cor_fruta, tipo_mat="t_linha"):
snake = like_snake(machine.Pin(4), colunas, linhas, cor_cobra, cor_cabeca, cor_fruta, "t_linha_zig_zag")
snake.fill((0,0,0))
while True:
snake.sorteia_pos_fruta()
snake.sorteia_pos_cobra()
time.sleep_ms(1000)
#'''
#Teste 16 - Snake
'''
cor_cobra = (0,255,0)
cor_cabeca = (255,0,0)
cor_fruta = (0,0,255)
cor_fundo = (0,0,0)
#(pino, col, lin, cor_cobra, cor_cabeca, cor_fruta, tipo_mat="t_linha"):
snake = like_snake(machine.Pin(4), colunas, linhas, cor_cobra, cor_cabeca, cor_fruta, "t_linha_zig_zag")
snake.fill((0,0,0))
print('**** Início do Jogo *****')
snake.sorteia_pos_fruta()
snake.sorteia_pos_cobra()
time.sleep_ms(1000)
while True:
print('Move loop =', move)
dc = snake.desloca_cobra(move)
#print('Desloca =', dc)
if dc == True:
cf = snake.comeu_fruta()
#print('Comeu =', cf)
if cf == True:
snake.sorteia_pos_fruta()
else:
time.sleep_ms(1000)
snake.limpa_matriz(cor_fundo)
snake.desenha_pontuacao()
time.sleep_ms(2000)
move = 'stop' #Garante que o jogo começa com a cobra parada
snake.reinicia_jogo()
time.sleep_ms(300)
#'''
FPS: 0
Power: 0.00W
Power: 0.00W