Previous posts for this project here:
Got my kit, and assembled the Pi screen. I did a few things that will help with development and deployment. Follow the steps on this page:
http://opentechguides.com/how-to/article/raspberry-pi/5/raspberry-pi-auto-start.html
This will allow auto login, as well as automatic starting of the GUI on boot. This is better for a project that will use the GUI and wont have a keyboard and/or mouse attached.
Edit your /boot/boot.config file to have these lines. The lines probably already exist so just edit them.
framebuffer_width=800
framebuffer_height=480
I found this to be a perfect resolution for the Raspberry pi Screen as well as the command line interface.
I have been working on the code to animate the eyes. I have one eye working that blinks at random. I have it enlarged for development and here is a video demonstration:
The blinking is a simple algorithm that ensures it does not blink too fast or blink too slow. The actual blink animation is a fixed time, but the time between blinks is based on the interval between the last blink.
if(self.blinking == 0): #determine when to blink again
display.blit(self.leftEye,(0,0))
if (time.time() - self.lastBlink >= self.blinkDelay):
print("Blink!" + "(" + str(self.blinkDelay) + ")")
self.blinking = 1
self.blinkIndex = 0
self.blinkDirection = 1
lastBlinkSwap = time.time()
if(self.blinkDelay <= 2):
self.blinkMin = 4
else:
self.blinkMin = 1
if(self.blinkDelay >= 4):
self.blinkMax = 3
else:
self.blinkMax = 6
self.blinkDelay = random.randint(self.blinkMin,self.blinkMax)
self.lastBlink = time.time()
I have added a Eye subclass to the Face class. Each part of the face will be a class that encapsulates and draws its own images on the screen. The completed code thus far:
import os
import pygame,sys, time, random
from pygame.locals import *
#a generic function for loading a set of images from a given directory
def LoadImages(imagesPath):
imageList = list()
for dirname, dirnames, filenames in os.walk(imagesPath):
for filename in sorted(filenames):
try:
imageList.append( pygame.image.load(os.path.join(dirname, filename)))
except:
pass
return imageList
#a generic function for loading a set of sounds from a given directory
def LoadSounds(imagesPath):
soundList = list()
for dirname, dirnames, filenames in os.walk(imagesPath):
for filename in sorted(filenames):
try:
soundList.append( pygame.mixer.Sound(os.path.join(dirname, filename)))
except:
pass
return soundList
#define the face and sub classes, which is just used to keep all the images together that go together
class Eyes:
def __init__(self,path):
self.leftEyeSquint = LoadImages(os.path.join(path, 'eye/left/squint/'))
self.leftEye = pygame.image.load(os.path.join(path, 'eye/left/eye.png'))
self.leftEyeBlink = LoadImages(os.path.join(path , 'eye/left/blink/'))
self.rightEyeSquint = LoadImages(os.path.join(path , 'eye/right/squint/'))
self.rightEyeBlink = LoadImages(os.path.join(path , 'eye/right/blink/'))
self.leftEyeX = 20
self.leftEyeY = 20
self.leftEyeW = 20
self.leftEyeH = 20
self.rightEyeX = 70
self.rightEyeY = 70
self.rightEyeW = 20
self.rightEyeH = 20
self.lastBlink = time.time()
self.lastBlinkSwap = time.time()
self.blinkMin = 1
self.blinkMax = 6
self.blinkDelay = random.randint(self.blinkMin,self.blinkMax)
self.blinking = 0
self.blinkIndex = 0
self.blinkDirection = 1
def getBlink(self):
if(self.blinking == 0): #determine when to blink again
display.blit(self.leftEye,(0,0))
if (time.time() - self.lastBlink >= self.blinkDelay):
print("Blink!" + "(" + str(self.blinkDelay) + ")")
self.blinking = 1
self.blinkIndex = 0
self.blinkDirection = 1
lastBlinkSwap = time.time()
if(self.blinkDelay <= 2):
self.blinkMin = 4
else:
self.blinkMin = 1
if(self.blinkDelay >= 4):
self.blinkMax = 3
else:
self.blinkMax = 6
self.blinkDelay = random.randint(self.blinkMin,self.blinkMax)
self.lastBlink = time.time()
else: #animate blinking
if(time.time() - self.lastBlinkSwap >= .3):
self.blinkIndex = self.blinkIndex + self.blinkDirection
if(self.blinkIndex >= len(self.leftEyeBlink)):
self.blinkIndex = len(self.leftEyeBlink)-1
self.blinkDirection = -1
if(self.blinkIndex == 0 and self.blinkDirection == -1):
## print("reset")
self.blinking = 0
self.blinkDirection = 1
self.lastBlink = time.time()
## print("blink index:" + str(self.blinkIndex))
display.blit(self.leftEyeBlink[self.blinkIndex],(0,0))
class Face:
def __init__(self,path):
#load each component of the eyes using the generic image loading function
self.mouthTalk = LoadImages(os.path.join(path , 'mouth/talk/'))
self.talkSounds = LoadSounds(os.path.join(path , 'sounds/talk'))
self.singSounds = LoadSounds(os.path.join(path , 'sounds/sing'))
self.scareSounds = LoadSounds(os.path.join(path , 'sounds/scare'))
#create the eyes class
self.eyes = Eyes(path)
#define vars for face
#emperically determined coordinates
self.mouthX = 20
self.mouthY = 150
self.mouthW = 200
self.mouthH = 200
def PrintInfo(self):
print str(len(self.eyes.leftEyeSquint)) + ' left squint images loaded'
print str(len(self.eyes.leftEyeBlink )) + ' left blink images loaded'
print str(len(self.eyes.rightEyeSquint )) + ' right squint images loaded'
print str(len(self.eyes.rightEyeBlink )) + ' right blink images loaded'
print str(len(self.mouthTalk )) + ' talk images loaded'
print str(len(self.talkSounds )) + ' talk sounds loaded'
print str(len(self.singSounds )) + ' sing sounds loaded'
print str(len(self.scareSounds )) + ' scare sounds loaded'
#main code here
pygame.init()
display = pygame.display.set_mode((800, 320))
pygame.display.set_caption('Funny Pumpkin')
#Create a list of faces classes, this example only has 1 face, but multiple faces can be used
faces = list()
#load the default face
faces.append(Face('./faces/default/'))
#test the class
faces[0].PrintInfo()
#global vars
FPS = 30
#main game loop
i = 0
while(1):
faces[0].eyes.getBlink()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
Top Comments