Last active
August 25, 2018 21:45
-
-
Save murilopolese/b16add15ad507ce533909ecbf2df0af6 to your computer and use it in GitHub Desktop.
Pixel Kit Games!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PixelKit as kit | |
from time import sleep | |
from random import randint as random | |
world = [[247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247],[3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3],[247,247,247,247,52,247,247,247,247,52,247,247,52,247,247,247,247,247,247,52,247,247,52,247,247,247,247,247,52,247,247,247],[247,247,247,247,52,247,247,247,247,52,247,247,52,52,52,3,3,52,247,52,52,52,52,247,247,247,247,247,52,247,247,247],[247,52,52,52,52,52,52,247,247,52,52,52,52,247,52,3,3,52,52,52,247,247,52,247,247,52,52,52,52,52,52,247],[247,52,247,247,247,247,52,247,247,52,247,247,52,247,247,247,247,247,247,52,247,247,52,247,247,52,247,247,247,247,52,247],[3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3],[247,247,52,247,247,52,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,52,247,247,52,247,247],[247,247,52,247,247,52,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,52,247,247,52,247,247],[3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3],[247,52,247,247,247,247,52,247,247,52,247,247,52,247,247,247,52,247,247,52,247,247,52,247,247,52,247,247,247,247,52,247],[247,52,52,52,52,52,52,247,247,52,247,247,52,52,52,3,3,247,247,52,52,52,52,247,247,52,52,52,52,52,52,247],[247,247,247,52,247,247,247,247,247,52,52,52,52,247,247,3,3,52,52,52,247,247,52,247,247,247,247,52,247,247,247,247],[247,247,247,52,247,247,247,247,247,52,247,247,52,247,247,52,247,247,247,52,247,247,52,247,247,247,247,52,247,247,247,247],[3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3],[247,247,247,247,247,247,247,247,247,247,247,247,3,247,247,247,247,247,247,247,3,247,247,247,247,247,247,247,247,247,247,247],[247,52,52,52,52,52,52,52,247,247,247,247,3,247,247,247,247,247,247,247,3,247,247,247,52,52,52,52,52,52,52,247],[247,52,247,247,247,52,247,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,247,52,247,247,247,52,247],[247,52,247,247,247,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247],[3,52,52,247,247,52,52,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,52,52,247,247,52,52,3],[247,247,52,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,247,52,247,52,247,247,52,247,247],[247,247,52,247,247,52,247,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,247,52,247,247,52,247,247],[247,52,52,52,52,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,52,52,52,52,247],[247,52,247,247,247,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247],[247,52,247,247,247,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,247,247,247,52,247],[247,52,52,52,52,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,52,52,52,52,247],[247,247,52,247,247,52,247,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,247,52,247,247,52,247,247],[247,247,52,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,247,52,247,52,247,247,52,247,247],[3,52,52,247,247,52,52,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,52,52,247,247,52,52,3],[247,52,247,247,247,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247],[247,52,247,247,247,52,247,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,247,52,247,247,247,52,247],[247,3,247,247,247,3,247,3,247,247,247,247,3,247,247,247,247,247,247,247,3,247,247,247,3,247,3,247,247,247,3,247],[247,3,247,247,247,3,247,3,247,247,247,247,3,247,247,247,247,247,247,247,3,247,247,247,3,247,3,247,247,247,3,247],[247,52,247,247,247,52,247,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,247,52,247,247,247,52,247],[247,52,247,247,247,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247],[3,52,52,247,247,52,52,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,52,52,247,247,52,52,3],[247,247,52,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,247,52,247,52,247,247,52,247,247],[247,247,52,247,247,52,247,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,247,52,247,247,52,247,247],[247,52,52,52,52,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,52,52,52,52,247],[247,52,247,247,247,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247],[247,52,247,247,247,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,247,247,247,52,247],[247,52,52,52,52,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,52,52,52,52,247],[247,247,52,247,247,52,247,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,247,52,247,247,52,247,247],[247,247,52,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,247,52,247,52,247,247,52,247,247],[3,52,52,247,247,52,52,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,52,52,247,247,52,52,3],[247,52,247,247,247,52,247,52,247,247,52,247,52,247,52,247,247,247,52,247,52,247,52,247,52,247,52,247,247,247,52,247],[247,52,247,247,247,52,247,52,247,52,52,52,52,52,52,247,247,52,52,52,52,52,52,247,52,247,52,247,247,247,52,247],[247,52,52,52,52,52,52,52,247,247,247,247,3,247,247,247,247,247,247,247,3,247,247,247,52,52,52,52,52,52,52,247],[247,247,247,247,247,247,247,247,247,247,247,247,3,247,247,247,247,247,247,247,3,247,247,247,247,247,247,247,247,247,247,247],[3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3],[247,247,247,247,52,247,247,247,247,52,247,247,52,247,247,247,247,247,247,52,247,247,52,247,247,247,247,247,52,247,247,247],[247,247,247,247,52,247,247,247,247,52,247,247,52,52,52,3,3,52,247,52,52,52,52,247,247,247,247,247,52,247,247,247],[247,52,52,52,52,52,52,247,247,52,52,52,52,247,52,3,3,52,52,52,247,247,52,247,247,52,52,52,52,52,52,247],[247,52,247,247,247,247,52,247,247,52,247,247,52,247,247,247,247,247,247,52,247,247,52,247,247,52,247,247,247,247,52,247],[3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3],[247,247,52,247,247,52,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,52,247,247,52,247,247],[247,247,52,247,247,52,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,52,247,247,52,247,247],[3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3],[247,52,247,247,247,247,52,247,247,52,247,247,52,247,247,247,247,247,247,52,247,247,52,247,247,52,247,247,247,247,52,247],[247,52,52,52,52,52,52,247,247,52,247,247,52,52,52,3,3,52,247,52,52,52,52,247,247,52,52,52,52,52,52,247],[247,247,247,52,247,247,247,247,247,52,52,52,52,247,52,3,3,52,52,52,247,247,52,247,247,247,247,52,247,247,247,247],[247,247,247,52,247,247,247,247,247,52,247,247,52,247,247,247,247,247,247,52,247,247,52,247,247,247,247,52,247,247,247,247],[3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3,3,52,52,52,52,52,52,3],[247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247]] | |
width = int(16*4) | |
height = int(8*4) | |
colors = { | |
'52': [0, 0, 0], # path | |
'3': [4, 0, 3], # portal | |
'247': [5, 0, 10], # wall | |
'player': [10, 10, 0], | |
'heading': [10, 5, 0], | |
'treasure': [25, 0, 0], | |
'npc': [15, 0, 15], | |
'npc_heading': [5, 10, 5] | |
} | |
UP = [0, -1] | |
DOWN = [0, 1] | |
LEFT = [-1, 0] | |
RIGHT = [1, 0] | |
dirs = [UP, RIGHT, DOWN, LEFT] | |
heading = 1 | |
game_over = False | |
p_pos = [1, 4] # player position | |
p_dir = dirs[heading] # player direction | |
w_pos = [0, 0] # world position | |
t_pos = [] | |
npcs = [] # [x, y, heading] | |
score = 0 | |
def rect(x, y, width, height, color): | |
for h in range(y, y+height): | |
for w in range(x, x+width): | |
kit.setPixel(w, h, color) | |
def draw_world(w, x, y): | |
for wx in range(0, 16): | |
for wy in range(0, 8): | |
nx = ((x*16) + wx + width) % width | |
ny = ((y*8) + wy + height) % height | |
d = str(w[nx][ny]) | |
if d in colors.keys(): | |
c = colors[d] | |
for t in t_pos: | |
if nx == t[0] and ny == t[1]: | |
c = colors['treasure'] | |
else: | |
c = colors['3'] | |
kit.setPixel(wx, wy, c) | |
def draw_player(p_pos): | |
x = p_pos[0] | |
y = p_pos[1] | |
np = [ x % 16, y % 8 ] | |
nd = [ | |
(x + p_dir[0]) % 16, | |
(y + p_dir[1]) % 8 | |
] | |
kit.setPixel(np[0], np[1], colors['player']) | |
kit.setPixel(nd[0], nd[1], colors['heading']) | |
def draw_npcs(npcs, w_pos): | |
x = w_pos[0] | |
y = w_pos[1] | |
for npc in npcs: | |
npc_quadrant = calc_w_pos(npc[0], npc[1]) | |
if npc_quadrant[0] == w_pos[0] and npc_quadrant[1] == w_pos[1]: | |
np = [ npc[0] % 16, npc[1] % 8 ] | |
nd = [ | |
(npc[0] + dirs[npc[2]][0]) % 16, | |
(npc[1] + dirs[npc[2]][1]) % 8 | |
] | |
kit.setPixel(np[0], np[1], colors['npc']) | |
kit.setPixel(nd[0], nd[1], colors['npc_heading']) | |
def add(a, b): | |
return [ a[0]+b[0], a[1]+b[1] ] | |
def calc_w_pos(x, y): | |
wx = int(x / 16) % 4 | |
wy = int(y / 8) % 4 | |
return [wx, wy] | |
def get_random_position(): | |
return [random(0, width-1), random(0, height-1)] | |
def place_treasure(w): | |
nt_pos = get_random_position() | |
if w[nt_pos[0]][nt_pos[1]] != 52: | |
return place_treasure(w) | |
else: | |
return nt_pos | |
def draw_treasure_map(p_pos, t_pos): | |
kit.clear() | |
p_quad = calc_w_pos(p_pos[0], p_pos[1]) | |
rect(p_quad[0]*4, p_quad[1]*2, 4, 2, colors['player']) | |
for t in t_pos: | |
t_quad = calc_w_pos(t[0], t[1]) | |
rect(t_quad[0]*4, t_quad[1]*2, 4, 2, colors['treasure']) | |
for i in range(0, score): | |
kit.setPixel(i%16, int(i/16), colors['heading']) | |
kit.render() | |
sleep(1) | |
def left(): | |
global heading | |
global p_dir | |
heading = (heading - 1 + 4) % 4 | |
p_dir = dirs[heading] | |
def right(): | |
global heading | |
global p_dir | |
heading = (heading + 1 + 4) % 4 | |
p_dir = dirs[heading] | |
kit.onButtonB = right | |
kit.onButtonA = left | |
t_pos.append(place_treasure(world)) | |
draw_treasure_map(p_pos, t_pos) | |
npcs.append([15, 5, 2]) | |
while not game_over: | |
kit.checkControls() | |
# Calculate which world position/quadrant player is | |
w_pos = calc_w_pos(p_pos[0], p_pos[1]) | |
# Draw the correct section of the world | |
draw_world(world, w_pos[0], w_pos[1]) | |
# Player is always visible so always draw player | |
draw_player(p_pos) | |
# Draw npcs if they are on the same world position/quadrant | |
draw_npcs(npcs, w_pos) | |
# Calculate player next step | |
np_pos = add(p_pos, p_dir) | |
np_pos[0] %= width | |
np_pos[1] %= height | |
state = world[np_pos[0]][np_pos[1]] | |
# Calculate npcs next move | |
for i, npc in enumerate(npcs): | |
n_pos = add(npc, dirs[npc[2]]) | |
n_pos[0] %= width | |
n_pos[1] %= height | |
n_state = world[n_pos[0]][n_pos[1]] | |
# Move npc if next step is steppable | |
if (n_state == 52 or n_state == 3): | |
npcs[i] = [n_pos[0], n_pos[1], npc[2]] | |
else: | |
if random(0, 10) > 8: | |
npcs[i][2] = (npc[2] - 1) % 4 | |
else: | |
npcs[i][2] = (npc[2] + 1) % 4 | |
# Randomize heading | |
if random(0, 10) > 8: | |
npcs[i][2] = (npc[2] - 1) % 4 | |
# Check if player os on an npc | |
for npc in npcs: | |
if npc[0] == np_pos[0] and npc[1] == np_pos[1]: | |
game_over = True | |
# Move player if next step is steppable | |
if (state == 52 or state == 3): | |
p_pos = np_pos | |
# Check if user is on top of a treasure | |
for i, t in enumerate(t_pos): | |
if p_pos[0] == t[0] and p_pos[1] == t[1]: | |
score += 1 | |
t_pos.pop(i) | |
if score < 7: | |
t_pos.append(place_treasure(world)) | |
x = get_random_position() | |
world[x[0]][x[1]] = 247 | |
elif score < 15: | |
if len(t_pos) == 0: | |
t_pos.append(place_treasure(world)) | |
t_pos.append(place_treasure(world)) | |
elif score < 23: | |
if len(t_pos) == 0: | |
for i in range(0, 3): | |
t_pos.append(place_treasure(world)) | |
n_pos = place_treasure(world) | |
npcs.append([n_pos[0], n_pos[1], 1]) | |
elif score < 32: | |
if len(t_pos) == 0: | |
for i in range(0, 4): | |
t_pos.append(place_treasure(world)) | |
for i in range(0, 2): | |
n_pos = place_treasure(world) | |
npcs.append([n_pos[0], n_pos[1], 1]) | |
else: | |
kit.clear() | |
while True: | |
kit.setPixel(random(0, 15), random(0, 7), [random(0, 30), random(0, 30), random(0, 30)]) | |
kit.render() | |
sleep(0.01) | |
draw_treasure_map(p_pos, t_pos) | |
kit.render() | |
sleep(0.1) | |
kit.clear() | |
for i in range(0, score): | |
kit.setPixel(i%16, int(i/16), colors['heading']) | |
kit.render() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PixelKit as kit | |
from random import randint | |
from time import sleep | |
from bresenham import bresenham | |
from math import sin, cos | |
PI = 3.1416 | |
colors = [ | |
(0, 0, 0), # 0 void | |
(0, 10, 0), # 1 grass | |
(0, 5, 7), # 2 sky | |
(10, 0, 5), # 3 berry 1 | |
(10, 3, 3), # 4 berry 2, | |
(10, 9, 0), # 5 love, | |
] | |
def line(x1, y1, x2, y2, color): | |
for pixel in bresenham(x1, y1, x2, y2): | |
try: | |
kit.setPixel(pixel[0], pixel[1], color) | |
except: | |
pass | |
def rect(x, y, width, height, color): | |
for h in range(y, y+height): | |
for w in range(x, x+width): | |
try: | |
kit.setPixel(w, h, color) | |
except: | |
pass | |
def generate_terrain(size=5): | |
terrain = [] | |
for i in range(0, size): | |
terrain.append(randint(4, 7)) | |
return terrain | |
def draw_terrain(terrain, to=7): | |
for i in range(0, len(terrain)-1): | |
x1 = hills[i] | |
y1 = terrain[i] | |
x2 = hills[i+1] | |
y2 = terrain[i+1] | |
for surface in bresenham(x1, y1, x2, y2): | |
line(surface[0], surface[1], surface[0], to, colors[1]) | |
def get(x, y): | |
if x > -1 and x < 16 and y > -1 and y < 8: | |
i = kit.getIndexFromCoordinate(int(x), int(y)) | |
return kit.np[i] | |
else: | |
return colors[2] | |
def launch(): | |
global turn | |
global love | |
global v | |
c = 0 | |
hit = False | |
while not hit: | |
c += 1 | |
if love[0] > -1 and love[0] < 16 and love[1] > -1 and love[1] < 8: | |
x1 = int(love[0]) | |
y1 = int(love[1]) | |
x2 = x1+int(v[0]*power) | |
y2 = y1+int(v[1]*power) | |
line(x1, y1, x2, y2, colors[5]) | |
love[0] += v[0]*power | |
love[1] += v[1]*power | |
v[0] += g[0] | |
v[1] += g[1] | |
if love[0] > 15 or love[0] < 0 or love[1] > 7: | |
hit = True | |
state = get(love[0], love[1]) | |
if state not in [ colors[2], colors[5] ]: | |
hit = True | |
kit.render() | |
sleep(0.1) | |
if c > 20: | |
hit = True | |
bang = get(berry1[0], berry1[1]) == get(berry2[0], berry2[1]) | |
if bang: | |
print('BANG') | |
for i in range(0, 16): | |
kit.setBackground(colors[3]) | |
kit.render() | |
sleep(0.01) | |
kit.setBackground(colors[4]) | |
kit.render() | |
sleep(0.01) | |
setup() | |
turn += 1 | |
else: | |
print('GIMME SOME LOVE PLS') | |
def do_launch(): | |
launch() | |
print('launched') | |
def power_up(): | |
global power | |
power = (power + 0.25) % 5 | |
def power_down(): | |
global power | |
power = (power - 0.25) % 5 | |
def setup(): | |
global terrain | |
global berry1 | |
global berry2 | |
terrain = generate_terrain(size) | |
berry1 = [hills[1], terrain[1]] | |
berry2 = [hills[size-2], terrain[size-2]] | |
hills = [0, 2, 8, 13, 15] | |
size = len(hills) | |
v = [0,0] | |
g = [0, 0.2] | |
power = 2 | |
turn = 0 | |
kit.onButtonB = power_up | |
kit.onButtonA = power_down | |
setup() | |
while True: | |
kit.checkControls() | |
if kit.joystickClick.value() == 0: | |
launch() | |
kit.setBackground(colors[2]) | |
draw_terrain(terrain) | |
d = (kit.dialValue / 4095) | |
a = -d * PI - PI/2 | |
v = [sin(a), cos(a)] | |
if turn % 2 == 0: | |
love = [berry1[0], berry1[1]] | |
x1 = berry1[0] | |
y1 = berry1[1] | |
else: | |
love = [berry2[0], berry2[1]] | |
x1 = berry2[0] | |
y1 = berry2[1] | |
x2 = max( min( x1+int(4*v[0]), 15 ), 0) | |
y2 = max( min( y1+int(4*v[1]), 7 ), 0) | |
line(x1, y1, x2, y2, colors[5]) | |
kit.setPixel(berry1[0], berry1[1], colors[3]) | |
kit.setPixel(berry2[0], berry2[1], colors[4]) | |
for i in range(0, power*4): | |
kit.setPixel(i, 0, colors[5]) | |
kit.render() | |
sleep(0.1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from machine import Pin, ADC | |
from neopixel import NeoPixel | |
# Hardware information: | |
# Pin numbers for each hardware connected to the PixelKit ESP32 | |
NEOPIXEL_PIN = 4 | |
SIZE = 128 # Amount of leds | |
WIDTH = 16 # Number of columns | |
HEIGHT = 8 # Number of lines | |
DIAL_PIN = 36 | |
JOYSTICK_UP_PIN = 35 | |
JOYSTICK_DOWN_PIN = 34 | |
JOYSTICK_LEFT_PIN = 26 | |
JOYSTICK_RIGHT_PIN = 25 | |
JOYSTICK_CLICK_PIN = 27 | |
BUTTON_B_PIN = 18 | |
BUTTON_A_PIN = 23 | |
BUTTON_NONE_PIN = 5 # dunno what is this | |
# Hardware instances | |
# Objects representing the available hardware on the PixelKit | |
neopixel_pin = Pin(NEOPIXEL_PIN, Pin.OUT) | |
np = NeoPixel(neopixel_pin, SIZE) | |
np.timing = 1 # This will set the neopixel frequency correctly | |
joystickUp = Pin(JOYSTICK_UP_PIN, Pin.IN) | |
joystickDown = Pin(JOYSTICK_DOWN_PIN, Pin.IN) | |
joystickLeft = Pin(JOYSTICK_LEFT_PIN, Pin.IN) | |
joystickRight = Pin(JOYSTICK_RIGHT_PIN, Pin.IN) | |
joystickClick = Pin(JOYSTICK_CLICK_PIN, Pin.IN) | |
buttonA = Pin(BUTTON_A_PIN, Pin.IN) | |
buttonB = Pin(BUTTON_B_PIN, Pin.IN) | |
buttonNone = Pin(BUTTON_NONE_PIN, Pin.IN) | |
dial = ADC(Pin(DIAL_PIN)) | |
dial.atten(ADC.ATTN_11DB) | |
# Hardware values | |
# Values based on the available hardware | |
dialValue = dial.read() | |
isPressingUp = False | |
isPressingDown = False | |
isPressingLeft = False | |
isPressingRight = False | |
isPressingClick = False | |
isPressingA = False | |
isPressingB = False | |
# Group all the other functions to check the hardware | |
def checkControls(): | |
checkJoystick() | |
checkButtons() | |
checkDial() | |
# Checks the joystick, "debounce" the presses and calls the | |
# function related to which joystick button was pressed | |
def checkJoystick(): | |
global isPressingUp | |
global isPressingDown | |
global isPressingLeft | |
global isPressingRight | |
global isPressingClick | |
if joystickUp.value() == 0 and not isPressingUp: | |
isPressingUp = True | |
onJoystickUp() | |
if joystickUp.value() != 0 and isPressingUp: | |
isPressingUp = False | |
if joystickDown.value() == 0 and not isPressingDown: | |
isPressingDown = True | |
onJoystickDown() | |
if joystickDown.value() != 0 and isPressingDown: | |
isPressingDown = False | |
if joystickLeft.value() == 0 and not isPressingLeft: | |
isPressingLeft = True | |
onJoystickLeft() | |
if joystickLeft.value() != 0 and isPressingLeft: | |
isPressingLeft = False | |
if joystickRight.value() == 0 and not isPressingRight: | |
isPressingRight = True | |
onJoystickRight() | |
if joystickRight.value() != 0 and isPressingRight: | |
isPressingRight = False | |
if joystickClick.value() == 0 and not isPressingClick: | |
isPressingClick = True | |
onJoystickClick() | |
if joystickClick.value() != 0 and isPressingClick: | |
isPressingClick = False | |
# Checks the buttons, "debounce" the presses and calls the | |
# function related to which button was pressed | |
def checkButtons(): | |
global isPressingA | |
global isPressingB | |
if buttonA.value() == 0 and not isPressingA: | |
isPressingA = True | |
onButtonA() | |
if buttonA.value() != 0 and isPressingA: | |
isPressingA = False | |
if buttonB.value() == 0 and not isPressingB: | |
isPressingB = True | |
onButtonB() | |
if buttonB.value() != 0 and isPressingB: | |
isPressingB = False | |
# Checks the dial value and only set the hardware value and call the | |
# function related with the dial if the new value is different from the previous | |
def checkDial(): | |
global dialValue | |
newValue = dial.read() | |
if newValue != dialValue: | |
dialValue = dial.read() | |
onDial(dialValue) | |
# Called when those hardware change values | |
def onJoystickUp(): | |
return False | |
def onJoystickDown(): | |
return False | |
def onJoystickLeft(): | |
return False | |
def onJoystickRight(): | |
return False | |
def onJoystickClick(): | |
return False | |
def onButtonA(): | |
return False | |
def onButtonB(): | |
return False | |
def onDial(dialValue): | |
return False | |
# NeoPixel values are stored in a unidimensional array so to get `x` and `y` | |
# coordinates it's needed some math to break the values into rows | |
def getIndexFromCoordinate(x, y): | |
return ((y) * WIDTH) + (x) | |
# Set a pixel `color` on coordinates `x` and `y`. This will only set the value | |
# on the "buffer" (`np`) and won't light any LED by itself. This operation is | |
# as fast as setting a value to an array | |
def setPixel(x, y, color=[0, 10, 0]): | |
index = getIndexFromCoordinate(x, y) | |
np[index] = color | |
# Set the entire screen to a given color. This will only set the value on the | |
# "buffer" (`np`) and won't light any LED by itself. This operation is as fast | |
# as setting a value to an array | |
def setBackground(color=[10,10,0]): | |
np.fill(color) | |
# `setBackground` to black color (turn all the LED off) | |
def clear(): | |
setBackground([0, 0, 0]) | |
# Send the "buffer" (`np`) values to the hardware. This operation is slower | |
# since it requires to send the information to the actual hardware and should be | |
# called as little as possible. | |
def render(): | |
np.write() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
blockI = [ | |
[ | |
[0, 1, 0, 0], | |
[0, 1, 0, 0], | |
[0, 1, 0, 0], | |
[0, 1, 0, 0] | |
], | |
[ | |
[0, 0, 0, 0], | |
[1, 1, 1, 1], | |
[0, 0, 0, 0], | |
[0, 0, 0, 0] | |
] | |
] | |
blockS = [ | |
[ | |
[0, 1, 1], | |
[1, 1, 0], | |
[0, 0, 0] | |
], | |
[ | |
[1, 0, 0], | |
[1, 1, 0], | |
[0, 1, 0] | |
] | |
] | |
blockZ = [ | |
[ | |
[1, 1, 0], | |
[0, 1, 1], | |
[0, 0, 0] | |
], | |
[ | |
[0, 0, 1], | |
[0, 1, 1], | |
[0, 1, 0] | |
] | |
] | |
blockL = [ | |
[ | |
[1, 0, 0], | |
[1, 0, 0], | |
[1, 1, 0] | |
], | |
[ | |
[0, 0, 0], | |
[0, 0, 1], | |
[1, 1, 1] | |
], | |
[ | |
[0, 1, 1], | |
[0, 0, 1], | |
[0, 0, 1] | |
], | |
[ | |
[1, 1, 1], | |
[1, 0, 0], | |
[0, 0, 0] | |
] | |
] | |
blockJ = [ | |
[ | |
[0, 0, 1], | |
[0, 0, 1], | |
[0, 1, 1] | |
], | |
[ | |
[1, 1, 1], | |
[0, 0, 1], | |
[0, 0, 0] | |
], | |
[ | |
[1, 1, 0], | |
[1, 0, 0], | |
[1, 0, 0] | |
], | |
[ | |
[0, 0, 0], | |
[1, 0, 0], | |
[1, 1, 1] | |
], | |
] | |
blockT = [ | |
[ | |
[0, 0, 0], | |
[0, 1, 0], | |
[1, 1, 1] | |
], | |
[ | |
[0, 1, 0], | |
[1, 1, 0], | |
[0, 1, 0] | |
], | |
[ | |
[0, 0, 0], | |
[1, 1, 1], | |
[0, 1, 0] | |
], | |
[ | |
[0, 1, 0], | |
[0, 1, 1], | |
[0, 1, 0] | |
], | |
] | |
blockO = [ | |
[ | |
[1, 1], | |
[1, 1] | |
] | |
] | |
blocks = [blockI, blockS, blockZ, blockL, blockJ, blockT, blockO] | |
import pixelKit as kit | |
from random import randint | |
from time import sleep | |
res = 50 | |
w = 8 | |
h = 16 | |
colors = [ | |
(0, 0, 0), | |
(255, 0, 0), | |
(255, 255, 0), | |
(0, 255, 0), | |
(0, 255, 255), | |
(0, 0, 255), | |
(255, 0, 255) | |
] | |
# [0]*8 is a shortcut to [0, 0, 0, 0, 0, 0, 0, 0] | |
stage = [ | |
[0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, | |
[0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8 | |
] | |
def setPixel(x, y, c): | |
_c = (int(c[0]/10), int(c[1]/10), int(c[2]/10)) | |
kit.setPixel(15-y, x, _c) | |
def drawStage(): | |
for y, sLine in enumerate(stage): | |
for x, value in enumerate(sLine): | |
if value != 0: | |
setPixel(x, y, colors[value]) | |
def drawBlock(px, py, block): | |
for y, bLine in enumerate(block): | |
for x, value in enumerate(bLine): | |
if value == 1: | |
setPixel(px+x, py+y, colors[currentColor]) | |
def checkWallCollision(px, py, block): | |
for y, bLine in enumerate(block): | |
for x, value in enumerate(bLine): | |
if value == 1: | |
nx = px+x | |
if nx < 0: | |
raise Exception('Hit left wall') | |
if nx >= w: | |
raise Exception('Hit right wall') | |
def checkFloorCollision(px, py, block): | |
for y, bLine in enumerate(block): | |
for x, value in enumerate(bLine): | |
if value == 1: | |
ny = py+y | |
if ny >= h: | |
raise Exception('Hit floor') | |
def checkStageCollision(px, py, block): | |
for y, bLine in enumerate(block): | |
for x, value in enumerate(bLine): | |
if value == 1: | |
nx = px+x | |
ny = py+y | |
if stage[ny][nx] != 0: | |
raise Exception('Hit stage') | |
def clearLines(): | |
for y, sLine in enumerate(stage): | |
count = 0 | |
# count how many blocks in the line | |
for value in sLine: | |
if value != 0: | |
count += 1 | |
# if line is filled | |
if count == 8: | |
# remove the line | |
del stage[y] | |
# prepend an emtpy line | |
stage.insert(0, [0]*8) | |
def newBlock(): | |
global currentBlock | |
global currentRotation | |
global currentColor | |
global posX | |
global posY | |
global gameOver | |
posX = 3 | |
posY = 0 | |
currentBlock = randint(0, len(blocks)-1) | |
currentRotation = randint(0, len(blocks[currentBlock])-1) | |
currentColor = randint(1, len(colors)-1) | |
try: | |
checkStageCollision(posX, posY, blocks[currentBlock][currentRotation]) | |
except Exception as e: | |
print(e) | |
stamp(posX, posY, blocks[currentBlock][currentRotation]) | |
gameOver = True | |
def stamp(px, py, block): | |
global stage | |
for y, bLine in enumerate(block): | |
for x, value in enumerate(bLine): | |
if value: | |
stage[py+y][px+x] = currentColor | |
def moveDown(b): | |
global posY | |
try: | |
nY = posY + 1 | |
checkFloorCollision(posX, nY, b) | |
checkStageCollision(posX, nY, b) | |
posY = nY | |
return True | |
except Exception as e: | |
print(e) | |
stamp(posX, posY, b) | |
sleep(0.2) | |
clearLines() | |
newBlock() | |
return False | |
gameOver = False | |
t = 0 | |
posX = 3 | |
posY = -1 | |
debounceButton = False | |
currentBlock = 0 | |
currentRotation = 0 | |
currentColor = 0 | |
key_up = False | |
key_down = False | |
key_left = False | |
key_right = False | |
key_pressed = key_up or key_down or key_left or key_right | |
def setup(): | |
global stage | |
global gameOver | |
stage = [ | |
[0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, | |
[0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8, [0]*8 | |
] | |
gameOver = False | |
newBlock() | |
def draw(): | |
global posY | |
global posX | |
global debounceButton | |
global key_up | |
global key_down | |
global key_left | |
global key_right | |
kit.checkControls() | |
key_up = kit.joystickRight.value() == 0 | |
key_down = kit.joystickLeft.value() == 0 | |
key_left = kit.joystickUp.value() == 0 | |
key_right = kit.joystickDown.value() == 0 | |
key_pressed = key_up or key_down or key_left or key_right | |
if not gameOver: | |
global t | |
t += 1 | |
kit.setBackground(colors[0]) | |
if key_pressed and not debounceButton: | |
debounceButton = True | |
controls() | |
if not key_pressed: | |
debounceButton = False | |
b = blocks[currentBlock][currentRotation] | |
drawStage() | |
drawBlock(posX, posY, b) | |
if t % 10 == 0: | |
moveDown(b) | |
else: | |
drawStage() | |
if kit.joystickClick.value() == 0: | |
setup() | |
kit.render() | |
sleep(0.1) | |
def controls(): | |
global posX | |
global posY | |
global currentRotation | |
if key_left: | |
try: | |
b = blocks[currentBlock][currentRotation] | |
checkWallCollision(posX-1, posY, b) | |
checkStageCollision(posX-1, posY, b) | |
posX -= 1 | |
except Exception as e: | |
print(e) | |
if key_right: | |
try: | |
b = blocks[currentBlock][currentRotation] | |
checkWallCollision(posX+1, posY, b) | |
checkStageCollision(posX+1, posY, b) | |
posX += 1 | |
except Exception as e: | |
print(e) | |
if key_up: | |
try: | |
r = (currentRotation + 1) % len(blocks[currentBlock]) | |
b = blocks[currentBlock][r] | |
checkWallCollision(posX, posY, b) | |
checkStageCollision(posX, posY, b) | |
currentRotation = r | |
except Exception as e: | |
print(e) | |
if key_down: | |
b = blocks[currentBlock][currentRotation] | |
while moveDown(b): | |
sleep(0.01) | |
# Start runtime | |
setup() | |
while True: | |
draw() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment