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