Skip to content

Instantly share code, notes, and snippets.

@murilopolese
Last active August 25, 2018 21:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save murilopolese/b16add15ad507ce533909ecbf2df0af6 to your computer and use it in GitHub Desktop.
Save murilopolese/b16add15ad507ce533909ecbf2df0af6 to your computer and use it in GitHub Desktop.
Pixel Kit Games!
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()
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)
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()
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