Source code for gamecontroller

# -*- coding: utf-8 -*-
import math
import pygame, cv2
from pygame.locals import *
import notes, camera, circle
import util, virtualkeyboard
import rtopencv

[docs]class GameController: """ Controls the Piano App (Game) status/behaviour """ instance = None def __init__(self): self.running = True self.calibrating = False self.playing = False self.keyboard = None self.verbose=False self.play_status = { key:False for key in util.scale} self.picam=camera.Camera(util.config["camera_size"]) # Window initialization FULLSCREEN self.screen=pygame.display.set_mode((1024,768))#,pygame.FULLSCREEN) # Load sound objects that will be used for key press self.sound = notes.Notes() self.background = self._draw_background() self._init_calibrating() self.fgmask = None self.last_frame = None self.last_fgmask = None GameController.instance = self @staticmethod
[docs] def get_instance(): return GameController.instance
[docs] def _init_calibrating(self): self.calibrating_rect = pygame.sprite.Group() self.circles = {} self.circles["lefttop"] = circle.Circle(self.picam.pygame_position.left,self.picam.pygame_position.top,"lefttop") self.circles["righttop"] = circle.Circle(self.picam.pygame_position.right,self.picam.pygame_position.top,"righttop") self.circles["leftbottom"] = circle.Circle(self.picam.pygame_position.left,self.picam.pygame_position.bottom,"leftbottom") self.circles["rightbottom"] = circle.Circle(self.picam.pygame_position.right,self.picam.pygame_position.bottom,"rightbottom") self.calibrating_rect.add(self.circles.itervalues())
[docs] def _draw_background(self): # Add background image pianoimage = pygame.image.load(util.get_app_path() + "/res/piano.jpg") image_width = 1024.0 image_height = pianoimage.get_height()*(image_width/pianoimage.get_width()) image_width = int(image_width) image_height = int(math.floor(image_height)) pianoimage = pygame.transform.scale(pianoimage,(image_width,image_height)) background = pygame.Surface(self.screen.get_size()) background = background.convert() background.blit(pianoimage, (0,0)) # Text information to go to background if pygame.font: self.font = pygame.font.Font(None, 36) self.bigfont = pygame.font.Font(None, 64) self.smallfont = pygame.font.Font(None, 18) title = self.bigfont.render("Air Piano", 1, (0xCA,0xFF,0x70)) by = self.smallfont.render("By: ChopSueyTeam", 1, (0xCA,0xFF,0x70)) background.blit(title, title.get_rect(top=20, left=512-title.get_width()/2)) background.blit(by, by.get_rect(top=700, left=1004-by.get_width())) return background
[docs] def redraw(self): self.screen.blit(self.background, (0,0)) if self.calibrating: util.pygame_camera_draw(self.picam) self.calibrating_rect.draw(self.screen) pygame.draw.line(self.screen,util.WHITE, self.circles["lefttop"].rect.center, self.circles["righttop"].rect.center) pygame.draw.line(self.screen,util.WHITE, self.circles["lefttop"].rect.center, self.circles["leftbottom"].rect.center) pygame.draw.line(self.screen,util.WHITE, self.circles["righttop"].rect.center, self.circles["rightbottom"].rect.center) pygame.draw.line(self.screen,util.WHITE, self.circles["leftbottom"].rect.center, self.circles["rightbottom"].rect.center) hint = self.font.render("Click on the circles and adjust to the piano keyboard zone", 1,(0xCA,0xFF,0x70)) self.screen.blit(hint, hint.get_rect(top=600, left=20)) if self.verbose and self.playing: if self.last_frame != None: self.screen.blit(self.last_frame,(0,0)) if self.last_fgmask != None: mask_bgr = cv2.cvtColor(self.last_fgmask,cv2.COLOR_GRAY2BGR) mask = self.picam._to_pygame(mask_bgr) self.screen.blit(mask,(self.picam.width+5,0)) for key, value in self.keyboard.keys.iteritems(): for pixel in value['control_points']: if mask.get_at(pixel) == (255,255,255,255): pygame.draw.circle(mask, (255,100,30), pixel, 2, 0) else: pygame.draw.circle(mask, (0,150,255), pixel, 2, 0) #pygame.draw.line(mask,util.GREEN, # circles["leftbottom"].rect.center-picam.pygame_position, # circles["rightbottom"].rect.center-picam.pygame_position) self.screen.blit(mask,(self.picam.width*2+10,0)) hint = self.font.render("Verbose mode ON ({:.1f}fps average)".format(self.opencv.get_fps()), 1,(0xCA,0xFF,0x70)) self.screen.blit(hint, hint.get_rect(top=650, left=10)) if self.playing: hint = self.font.render("Touch the sketch and play the piano", 1,(0xCA,0xFF,0x70)) self.screen.blit(hint, hint.get_rect(top=600, left=10))
[docs] def process_key(self, key): key = chr(key) if key == 'c': self.calibrating=not(self.calibrating) if self.calibrating: # refres screen every 50ms pygame.time.set_timer(USEREVENT+1, 50) else: pygame.time.set_timer(USEREVENT+1, 0) elif key == 'p': self.playing=not(self.playing) if self.playing: self.keyboard=virtualkeyboard.VirtualKeyboard( [[s.rect.center[0]-self.picam.pygame_position.left,s.rect.center[1]-self.picam.pygame_position.top] for s in [self.circles["lefttop"],self.circles["righttop"],self.circles["leftbottom"],self.circles["rightbottom"]]]) self.start_fgsegmentation(self) # refres screen every 500ms pygame.time.set_timer(USEREVENT+2, 500) else: pygame.time.set_timer(USEREVENT+2, 0) self.stop_fgsegmentation() elif key == 'v': self.verbose = not self.verbose elif key == 'a': self.sound.play('low_c') elif key == 'w': self.sound.play('c_sharp') elif key == 's': self.sound.play('d') elif key == 'e': self.sound.play('d_sharp') elif key == 'd': self.sound.play('e') elif key == 'f': self.sound.play('f') elif key == 'r': self.sound.play('f_sharp') elif key == 'h': self.sound.play('g') elif key == 'y': self.sound.play('g_sharp') elif key == 'j': self.sound.play('a') elif key == 'u': self.sound.play('a_sharp') elif key == 'k': self.sound.play('b') elif key == 'l': self.sound.play('high_c') elif key == 'q' or ord(key) == K_ESCAPE: self.running = False
[docs] def test_frame(self): self.keyboard.test(self.fgmask) for k,v in self.keyboard.keys.iteritems(): if v['pressed']: if self.play_status[k] == False: self.sound.play(k) self.play_status[k] = True else: self.play_status[k] = False
[docs] def start_fgsegmentation(self, status): self.bgs_mog = cv2.BackgroundSubtractorMOG( util.config["bgs_mog_params"][0], util.config["bgs_mog_params"][1], util.config["bgs_mog_params"][2], util.config["bgs_mog_params"][3])#5, 3, 0.4, . self.opencv = rtopencv.RTOpenCV(self.picam.camera, GameController.process_image)
# process de frame , rtopencv and frame are passed as parameters @staticmethod
[docs] def process_image(rtopencv_class, frame): controller = GameController.get_instance() controller.fgmask = controller.bgs_mog.apply(frame,controller.fgmask, learningRate=util.config["bgs_mog_params"][3]) controller.test_frame() if controller.verbose: controller.last_frame = controller.picam._to_pygame(frame) controller.last_fgmask = controller.fgmask
[docs] def stop_fgsegmentation(self): self.opencv.close() self.bgs_mod = None