Closed waveform80 closed 8 years ago
And here's an updated bug_simple.py
(I've just used literals instead of the constants here, just for the sake of demo-ing what they actually are):
#!/usr/bin/python3
import time
from sense_hat import SenseHat
import sys
"""
A bug on a colored background, responding to keypresses.
Modify the starting state in the `state` dict.
The background changes colors based on the bug's xy coords.
This version handles keypresses with a SenseStick object.
"""
state = { "bug_x" : 4,
"bug_y" : 4,
"bug_rgb" : (250,250,250) }
sense = SenseHat()
def setscreen():
"""Takes x and y vales and alters screen state"""
global state
x = state["bug_x"]
y = state["bug_y"]
if sense.low_light:
zero = 8
else:
zero = 48
brightness = 255 -zero
g = int(((x * 32)/255) * brightness + zero)
b = int(((y * 32)/255) * brightness + zero)
r = abs(g - b)
sense.clear((r,g,b))
#print(r,g,b)
def draw_bug(event):
global state
if event.action == 'released':
# Ignore releases
return
elif event.direction == 'up':
state["bug_x"] = state["bug_x"]
state["bug_y"] = 7 if state["bug_y"] == 0 else state["bug_y"] - 1
setscreen()
sense.set_pixel(state["bug_x"], state["bug_y"], state["bug_rgb"])
elif event.direction == 'down':
state["bug_x"] = state["bug_x"]
state["bug_y"] = 0 if state["bug_y"] == 7 else state["bug_y"] + 1
setscreen()
sense.set_pixel(state["bug_x"], state["bug_y"], state["bug_rgb"])
elif event.direction == 'right':
state["bug_x"] = 0 if state["bug_x"] == 7 else state["bug_x"] + 1
state["bug_y"] = state["bug_y"]
setscreen()
sense.set_pixel(state["bug_x"], state["bug_y"], state["bug_rgb"])
elif event.direction == 'left':
state["bug_x"] = 7 if state["bug_x"] == 0 else state["bug_x"] - 1
state["bug_y"] = state["bug_y"]
setscreen()
sense.set_pixel(state["bug_x"], state["bug_y"], state["bug_rgb"])
# Initial state
setscreen()
sense.set_pixel(state["bug_x"], state["bug_y"], state["bug_rgb"])
try:
while True:
for event in sense.stick.get_events():
draw_bug(event)
except KeyboardInterrupt:
sys.exit()
An updated flappy_click.py
:
import sense_hat
from time import sleep, time
from random import randint
sense = sense_hat.SenseHat()
sense.clear()
##Globals
game_over = False
RED = (255,0,0)
BLACK = (0,0,0)
BLUE = (0,0,255)
y = 4
speed = 0
# column index, gap row start, gap size
columns = [ (7, 3, 3)]
def move_columns():
global columns
columns = [(c[0] -1, c[1], c[2]) for c in columns]
columns = [c for c in columns if c[0] >= 0]
if max([c[0] for c in columns]) == 4:
gap_size = randint(2,4)
row_start = randint(1 + gap_size, 6)
columns.append((7,row_start,gap_size))
def draw_column(col):
x, gap_start, gap_size = col
c = [RED] * 8
# print(col, x, gap_start, gap_size, type(gap_start + gap_size),c)
c[gap_start - gap_size: gap_start] = [BLACK] * gap_size
for y, color in enumerate(c):
#print(x,y,color, gap_start, gap_size)
sense.set_pixel(x,y,color)
def draw_screen():
global columns, y, speed
sense.clear()
for c in columns:
draw_column(c)
def draw_bird():
global y
# Draw bird. Negative speed = up
sense.set_pixel(3,y,BLACK)
y += speed
# Stay onscreen
if y > 7:
y = 7
if y < 0:
y = 0
sense.set_pixel(3,y,BLUE)
#print(y)
last_tick = round(time(), 1) * 20
draw_screen()
draw_bird()
redraw_screen = False
while not game_over:
tick = round(time(), 1) * 20
if (tick % 20 == 0) and (tick > last_tick):
move_columns()
draw_screen()
last_tick = tick
draw_bird()
events = sense.stick.get_events()
if events:
for e in events:
if e.direction == sense_hat.DIRECTION_UP and e.action == sense_hat.ACTION_PRESSED:
move_columns()
draw_screen()
speed = -1
draw_bird()
else:
speed = +1
redraw_screen = False
sense.show_message("You Lose", text_colour=(255,0,0))
Updated joystick_test.py
:
import sense_emu as sense_hat
import time
"""
Simple utility to test SenseHat joystick and LEDs are working.
Uses sense_hat.SenseStick for input
"""
screen = sense_hat.SenseHat()
def react(event):
n = {
'up': 133,
'left': 155,
'right': 166,
'down': 188,
}[event.direction]
color = [(n,n,n)]*64
screen.set_pixels(color)
print(event.direction)
print("Test joystick directions. Click joystick to exit")
while True:
for event in screen.stick.get_events():
if event.direction == 'middle':
break
react(event)
time.sleep(.001)
Hey Dave, yeah they're planning to update the Sense Stick API soon. But you've saved them a job by updating these examples. Many thanks!
@waveform80 thanks a ton for the updates! We'll get them pushed once the new API is implemented in JS
Just FYI - I'm not sure if this is a bug or not: the characters.py
script uses some library I'm not familiar with for loading pixels.gif (it's not installed by default on Raspbian, and doesn't appear to be a sense HAT dependency). I have a feeling it might be a really old version of PIL (I vaguely recall "import image" from way back, but my memory my be fooling me).
Either way, I get the impression it's a deliberate variation as the original script (linked to at the bottom of the trinket version) imports PIL and uses the usual Image.open()
instead of image()
, size
instead of getWidth()
, etc. so I'm guessing it's something to do with the set of libraries accessible via trinket?
You're exactly right that it's not a Python module. It's a Skulpt module for handling images that's vaguely inspired by some real Python stuff. I used it as a proof of concept for how to deal with image files, but it's probably not a good example to preserve on the demo since it' won't be backwards compatible
Changed the title to reflect the overarching issue. We'll deploy the API updates and updated example programs all at once later this week and I'll comment here.
This is implemented! Check out the updated joystick examples on the demos page, including an much improved flappy_hat.py (now with lives and scoring!) and a visual rock paper scissors game
@waveform80 testing on the new API much appreciated since you're the authority. We're working on an implementation for signal.pause
in skulpt but in the meantime you'll need another way to keep the rpogram from terminating. Perhaps in a future version of the library a sense.stick.listen()
method that wrapped pause() or etc would be nice to have.
Also, check out the new sensors.py - it uses the stick API to integrate all three sensor displays into one program.
The
bug_game.py
demo uses methods from SenseStick that were removed (or made non-public) in the eventual version of SenseStick that got merged for release:wait
andread
methods are now internal only; you probably want to useget_events
in the main loop insteadSTATE_*
attributes are nowACTION_*
, andKEY_*
are nowDIRECTION_*
; the attributes are also strings to make for easier debugging and more obvious comparisons and are now part of the sense_hat module itself rather than class attributes (again, easier for beginners)hat.stick.wait_for_event
Sorry! I'm just going through all the demos on the actual hat with the merged code to see if anything else needs tweaking. In the meantime, I think
bug_game.py
probably wants to read like this instead: