#!/usr/bin/env python # -*- coding: utf8 -*- #*********************************************************************** # pysycache : a tool for learn to use the mouse # Copyright (C) 2005-2006 Vincent DEROO (vincent.pysycache@free.fr) # # This tool is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #*********************************************************************** #******************************************************************************* # Importation des modules #******************************************************************************* import sys import getopt, string import random import time import random, os import pygame from pygame.locals import * import datas from datasclass import BtnMenu import const import glob DUREETRANSITION = 3 #******************************************************************************* # # # # # Classe # # # # # #******************************************************************************* class Balloon(pygame.sprite.Sprite): """This class is for the elements that move""" def __init__(self, left, top, filename, id, categ): pygame.sprite.Sprite.__init__(self) #call Sprite intializer dirname = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/themes-buttons', GLstThemesButtons[const.GIdxThemes]) self.image, self.rect = datas.load_png(dirname, filename) self.id = id self.largeur = 96 self.hauteur = 96 self.cptspeed = 0 self.visible = 1 #l'image est visible self.speed = const.GSpeed self.sens = 1 # 1 : descendre # 0 : arret # #-1 : monter self.rect.left = left self.rect.top = top self.categ = categ #1 : gauche #2 : droite def move(self): #deplacement de l'element if self.visible == 1: self.cptspeed = self.cptspeed + 1 if self.cptspeed == self.speed: #on se deplace de 1 pixel self.rect.top = self.rect.top + 1 * self.sens self.cptspeed = 0 #--------------------- verification des limites -------------------- if self.rect.left < GLimGauche : #zone a gauche liminf = GLimBasG limsup = GLimHautG elif self.rect.left + self.largeur > GLimDroite: #zone a droite liminf = GLimBasD limsup = GLimHautD else: #zone centrale liminf = GLimBas limsup = GLimHaut if self.rect.top < limsup: self.rect.top = limsup self.sens = -1 * self.sens if self.rect.top + self.hauteur > liminf: self.rect.top = liminf - self.hauteur self.sens = -1 * self.sens #******************************************************************************* # # # # # Fonctions # # # # # #******************************************************************************* #******************************************************************************* # le contenu de ce fichier dfg est # # fond01.bmp image de fond # 200-20 coin ht gauche # 500-505 coin bas droite # 180-150-180-300 # 500-365-500-515 # 01.png-4 img de gauche - nbre # 02.png-2 img de droite - nbre #******************************************************************************* def LoadBackgroundOfConfig(themename): """ Charge le fond a partir d'un fichier de configuration contenus dans le repertoire""" # # il faut ajouter les marges const.MARGELEFT et const.MARGETOP # #GLimHaut --------------------- # | | # | | # | | #GLimHautG---- | # | #GLimBasG----- | # | | # | | # | ---------GLimHautD # | # | ---------GLimBasD # | | # | | #GLimBas |--------------------| # GLimGauche GLimDroite global GLimGauche global GLimDroite global GLimHaut global GLimBas global GLimHautD global GLimHautG global GLimBasD global GLimBasG global GLstBallons #liste des images des elements mobiles global GLimFinG global GLimFinD GLstBallons = pygame.sprite.RenderClear() screen = pygame.display.get_surface() #effacer l'existant const.GTabButtons[:] = [] LstFound = [] #------------------ on va lire le fichier de configuration ----------------- configname = GLstFicConfig[const.GIdxImage] cpt = 0 f = open(configname,'rb') lignes = f.readlines() for lig in lignes: lig = lig.strip() if len(lig) == 0: continue if cpt == 0: #fond de l'image #chargement du dessin servant de cache filename = os.path.join(themename, lig) imgfilename = lig ImgFond, background_rect = datas.load_image('/usr/X11R6/share/pysycache/themes-buttons', filename ) #on copie ce cache sur l'image de fond screen = pygame.display.get_surface() Gbackground_image.blit(ImgFond, (0 + const.MARGELEFT, 0 + const.MARGETOP)) #on copie cette image sur l'ecran screen.blit(Gbackground_image, (0, 0)) if cpt == 1: #la limite superieure gauche lig = lig.split('-') GLimGauche = int(lig[0]) + const.MARGELEFT GLimHaut = int(lig[1]) + const.MARGETOP if cpt == 2: #la limite inferieure droite lig = lig.split('-') GLimDroite = int(lig[0]) + const.MARGELEFT GLimBas = int(lig[1]) + const.MARGETOP if cpt == 3 : #le tunnel de gauche lig = lig.split('-') GLimHautG = int(lig[1]) + const.MARGETOP GLimBasG = int(lig[3]) + const.MARGETOP if cpt == 4 : #le tunnel de droite lig = lig.split('-') GLimHautD = int(lig[1]) + const.MARGETOP GLimBasD = int(lig[3]) + const.MARGETOP if cpt == 5: #l'element de gauche et le nombre maxi possible lig = lig.split('-') nb1 = random.randint(1, int(lig[1]) ) for i in range (nb1) : x = random.randint(GLimGauche + 1, GLimDroite - 1 - 96) + const.MARGELEFT y = random.randint(GLimHaut, GLimBas - 96) + const.MARGETOP btn = Balloon(x, y, lig[0], i, 1) btn.id = i GLstBallons.add(btn) if cpt == 6: #l'element de droite et le nombre maxi possible lig = lig.split('-') nb2 = random.randint(1, int(lig[1]) ) for i in range (nb2) : x = random.randint(GLimGauche + 1, GLimDroite - 1 - 96) + const.MARGELEFT y = random.randint(GLimHaut, GLimBas - 96) + const.MARGETOP btn = Balloon(x, y, lig[0], i, 2) btn.id = nb1 + i GLstBallons.add(btn) if cpt == 7: #la limite a gauche pour cacher l'element lig = lig.split('-') GLimFinG = int(lig[0]) + const.MARGELEFT if cpt == 8: #la limite a gauche pour cacher l'element lig = lig.split('-') GLimFinD = int(lig[0]) + const.MARGELEFT cpt = cpt + 1 f.close() #MAJ du nombre de buttons a voir const.GNbButtons = nb1 + nb2 #******************************************************************************* # Recherche les fichiers de configuration pour un repertoire # on recherche tous les fichiers de definition (*.dfg) #******************************************************************************* def LoadListConfigFile(themename): """ Find all available pictures of a theme directory """ filtre = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/themes-buttons', themename, '*.dfg') #vider # GLstImage[:] = [] GLstFicConfig[:] = [] #remplir for nom in glob.glob(filtre): if os.path.isfile(nom): #--- recuperation du nom (hors chemin) du fichier de definition ---- GLstFicConfig.append(nom) #choisir un fichier au hasard if len(GLstFicConfig) == 1: const.GIdxImage = 0 else : const.GIdxImage = random.randint(0, len(GLstFicConfig) - 1) #******************************************************************************* # change le logo du theme # (a partir des repertoires) #******************************************************************************* def ChangeLogoButtons(): """ Change logo of a theme """ if const.GIdxThemes == 999999: #tous les themes filename = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/images', 'logo.png') else: #un theme particulier filename = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/themes-buttons', GLstThemesButtons[const.GIdxThemes], 'logo.png') if os.path.isfile(filename) == True: imgtmp = pygame.image.load(filename) else: filename = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/images', 'logo.png') imgtmp = pygame.image.load(filename) #mise a jour de l'image du theme for btn in LstBtn.sprites(): if btn.id == 5: #the id of the logo button screen = pygame.display.get_surface() screen.blit(Gbackground_image, (btn.rect.left, btn.rect.top), (0, 0, btn.largeur, btn.hauteur)) btn.image.blit(imgtmp, (btn.rect.left, btn.rect.top), (0, 0, btn.largeur, btn.hauteur)) btn.image = imgtmp #******************************************************************************* # Detection des evenements # # # self.listenKeys = { K_UP: self.MoveUp, # K_DOWN: self.MoveDown, # K_LEFT: self.SetVelocityLeft, # K_RIGHT: self.SetVelocityRight, # K_SPACE: self.MoveUp # } # # #******************************************************************************* def DetectEvent(): """ Traitement des evenements """ for event in pygame.event.get(): if event.type == QUIT: return 0 elif event.type == KEYUP: if event.key == K_ESCAPE: return 0 elif event.type == pygame.MOUSEMOTION: #*************** evenement deplacement de la souris *************** event0 = event.pos[0] event1 = event.pos[1] screen = pygame.display.get_surface() screen.blit(Gbackground_image, (0,0)) #redessin de la souris a sa position actuelle screen.blit(GMaSouris, GMaSouris_position) GMaSouris_position.left = event0 GMaSouris_position.top = event1 return 1 elif event.type == MOUSEBUTTONDOWN: #*************************** evenement clic ************************* str = pygame.mouse.get_pressed() ok = 0 #----------------- recherche si un objet a deplacer ---------------- #on ne fait pas deplacer si en dehors de la zone for obj in GLstBallons.sprites(): if obj.visible == 0: continue if ( event.pos[0] >= obj.rect.left ) & ( event.pos[0] <= obj.rect.left + obj.largeur ) & ( event.pos[1] >= obj.rect.top ) & ( event.pos[1] <= obj.rect.top + obj.hauteur ) : objtrouve = obj ok = 1 if ok == 1: ok = 0 if str[0] == 1: #------------------ a gauche ------------------------------- datas.load_sound('sounds', 'left.ogg') ok = 1 #ne pas aller dans la zone interdite... if GLimGauche >= objtrouve.rect.left - 50: if objtrouve.categ == 1: #l'element peut aller a gauche... mais #est-il dans la zone pour aller se ranger ? if (objtrouve.rect.top > GLimHautG) & (objtrouve.rect.top + objtrouve.hauteur < GLimBasG) : objtrouve.rect.left = objtrouve.rect.left - 50 #verification que l'element a atteint sa limite if objtrouve.rect.left <= GLimFinG: objtrouve.visible = 0 filename = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/images', 'button-vide.png') imgtmp = pygame.image.load(filename) screen = pygame.display.get_surface() objtrouve.image.blit(imgtmp, (0, 0), (0, 0, objtrouve.largeur, objtrouve.hauteur)) objtrouve.image = imgtmp const.GNbButtons = const.GNbButtons - 1 else: objtrouve.rect.left = GLimGauche else: objtrouve.rect.left = GLimGauche else: #pas de pb de limites objtrouve.rect.left = objtrouve.rect.left - 50 elif str[1] == 1: #-------- on change le mvt : haut <--> bas ----------------- datas.load_sound('/usr/X11R6/share/pysycache/sounds', 'center.ogg') objtrouve.sens = -1 * objtrouve.sens elif str[2] == 1: #-------------------- a droite ----------------------------- datas.load_sound('/usr/X11R6/share/pysycache/sounds', 'right.wav') ok = 1 if GLimDroite <= objtrouve.rect.left + 50 + objtrouve.largeur : if objtrouve.categ == 2: #l'element peut aller a droite... mais #est-il dans la zone pour aller se ranger ? if (objtrouve.rect.top > GLimHautD) & (objtrouve.rect.top + objtrouve.hauteur < GLimBasD) : objtrouve.rect.left = objtrouve.rect.left + 50 #verification que l'element a atteint sa limite if objtrouve.rect.left + objtrouve.largeur >= GLimFinD: objtrouve.visible = 0 filename = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/images', 'button-vide.png') imgtmp = pygame.image.load(filename) screen = pygame.display.get_surface() objtrouve.image.blit(imgtmp, (0, 0), (0, 0, objtrouve.largeur, objtrouve.hauteur)) objtrouve.image = imgtmp const.GNbButtons = const.GNbButtons - 1 else: objtrouve.rect.left = GLimDroite - objtrouve.largeur else: objtrouve.rect.left = GLimDroite - objtrouve.largeur else: #pas de pb de limites objtrouve.rect.left = objtrouve.rect.left + 50 if ok == 1: screen = pygame.display.get_surface() # LstBtn.draw(screen) GLstBallons.draw(screen) #redessin de la souris a sa position actuelle # screen.blit(GMaSouris, GMaSouris_position) pygame.display.flip() return 1 #------------------ recherche si un bouton de menu ----------------- for obj in LstBtn.sprites() : screen = pygame.display.get_surface() if ( event.pos[0] >= obj.rect.left ) & ( event.pos[0] <= obj.rect.left + obj.largeur ) & ( event.pos[1] >= obj.rect.top ) & ( event.pos[1] <= obj.rect.top + obj.hauteur ) : #----------- show the correct window ----------------- if ( obj.id == 1 ) : #change la vitesse du jeu (normal/moyenne/rapide) if const.GSpeed == 3: const.GSpeed = 2 filename = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/images', 'btn-vitesse2.png') elif const.GSpeed == 2: const.GSpeed = 1 filename = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/images', 'btn-vitesse1.png') elif const.GSpeed == 1: const.GSpeed = 3 filename = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/images', 'btn-vitesse3.png') imgtmp = pygame.image.load(filename) #mise a jour image screen.blit(Gbackground_image, (obj.rect.left, obj.rect.top), (0, 0, obj.largeur, obj.hauteur)) obj.image.blit(imgtmp, (obj.rect.left, obj.rect.top), (0, 0, obj.largeur, obj.hauteur)) obj.image = imgtmp #rechargement du jeu LoadListConfigFile(GLstThemesButtons[const.GIdxThemes]) LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes]) ChangeLogoButtons() ok = 1 if ( obj.id == 2) : #Quitter return 0 if ( obj.id == 3) : #image avant (dans le theme) if const.GIdxImage > 0: const.GIdxImage = const.GIdxImage - 1 else: const.GIdxImage = len(GLstFicConfig) - 1 #transition datas.ShowTransitionOfTheme(DUREETRANSITION, 'fond-buttons.bmp') LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes]) ChangeLogoButtons() ok = 0 if ( obj.id == 4) : #image apres (dans le theme) if const.GIdxImage < len(GLstFicConfig) - 1: const.GIdxImage = const.GIdxImage + 1 else: const.GIdxImage = 0 #transition datas.ShowTransitionOfTheme(DUREETRANSITION, 'fond-buttons.bmp') LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes]) ChangeLogoButtons() ok = 0 if ( obj.id == 5) : #autre theme const.GIdxThemes = const.GIdxThemes + 1 if const.GIdxThemes == len(GLstThemesButtons): const.GIdxThemes = 0 LoadListConfigFile(GLstThemesButtons[const.GIdxThemes]) LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes]) ChangeLogoButtons() ok = 1 break if ok == 1: LstBtn.draw(screen) GLstBallons.draw(screen) #redessin de la souris a sa position actuelle screen.blit(GMaSouris, GMaSouris_position) pygame.display.flip() # return 1 return 1 #******************************************************************************* # boucle principale # si typfull = 0 : mode fenetre # = 1 : mode plein ecran #******************************************************************************* def ShowWindow(typfull): global GMaSouris global Gbackground_image #image de fond global GMaSouris_position global GLstThemesButtons #themes des images #est obtenue a partir du repertoire datas global GLstFicConfig #liste des fichiers de config dans le theme screen = pygame.display.get_surface() const.GIdxThemes = 0 const.GIdxImage = 0 const.GSpeed = 2 #------------------- changer la souris en main ------------------- # filename = os.path.join('images', 'souris.xbm') # maskname = os.path.join('images', 'souris-mask.xbm') # cursor = pygame.cursors.load_xbm(filename, maskname) # cursor = cursor[0], (cursor[0][0] / 2, cursor[0][1] / 2), cursor[2], cursor[3] # pygame.mouse.set_cursor(cursor[0], (0, 0), cursor[2], cursor[3]) filename = dirname = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/images', 'souris.png') GMaSouris = pygame.image.load(filename) GMaSouris_position = GMaSouris.get_rect() GMaSouris_position.left = const.GPosDepX GMaSouris_position.top = const.GPosDepY pygame.mouse.set_pos((GMaSouris_position.left, GMaSouris_position.top)) #------------------ transition vers le jeu ------------------------ Gbackground_image, background_rect = datas.load_image('/usr/X11R6/share/pysycache/images', 'fond-buttons.bmp') for i in range(300): screen.blit(Gbackground_image, (0, i), (0, i, 800, 1)) screen.blit(Gbackground_image, (0, 600 - i), (0, 600 - i, 800, 1)) pygame.display.flip() pygame.time.wait(8) screen.blit(Gbackground_image, (0,0)) pygame.display.flip() #-------------------- liste des boutons ---------------------- global LstBtn LstBtn = pygame.sprite.RenderClear() #vitesse du jeu - 0/1/2 LstBtn.add(BtnMenu(712, 10, 'btn-vitesse2.png', 1, 85, 85)) #image du theme LstBtn.add(BtnMenu(711, 504, 'logo.png', 5, 85, 85)) #avant et apres LstBtn.add(BtnMenu(489, 537, 'btn-avant.png', 3, 60, 60)) LstBtn.add(BtnMenu(603, 537, 'btn-apres.png', 4, 60, 60)) #quitter LstBtn.add(BtnMenu(25, 535, 'btn-quitter.png', 2, 186, 60)) GLstFicConfig = [] #----------------- rechercher les themes disponibles ----------------------- repertoire = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/themes-buttons') GLstThemesButtons = [] for nom in os.listdir(repertoire): #ne prendre que les repertoires isrep = os.path.join(const.GRepPysycache, '/usr/X11R6/share/pysycache/themes-buttons', nom) if os.path.isdir(isrep): GLstThemesButtons.append(nom) if len(GLstThemesButtons) == 1: const.GIdxThemes = 0 else: const.GIdxThemes = random.randint(0, len(GLstThemesButtons) - 1) #---------- rechercher les fichiers de config d'un theme ------------------- LoadListConfigFile(GLstThemesButtons[const.GIdxThemes]) #lire ce fichier de configuration LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes]) ChangeLogoButtons() GLstBallons.draw(screen) #-------------- entree dans la boucle principale -------------- clock = pygame.time.Clock () running = 1 while running: clock.tick ( 60 ) #max 60 fps / sec #recherche des evt running = DetectEvent() screen.blit(Gbackground_image, (0,0)) for o in GLstBallons.sprites(): o.move() LstBtn.draw(screen) #verification si on a tout decouvert if const.GNbButtons == 0: tpsfin = pygame.time.get_ticks() pygame.mouse.set_pos((const.GPosDepX, const.GPosDepY)) const.GTypeSouris = 1 #on passe en mode gagne GMaSouris_position.left = const.GPosDepX GMaSouris_position.top = const.GPosDepY GLstBallons.draw(screen) pygame.display.flip() #on joue la musique de gagne datas.PlayWinnerSound() #on affiche l'image de gagne imggagne, imgfin_rect = datas.load_png('/usr/X11R6/share/pysycache/images', 'gagne.png') screen.blit(imggagne, (100, 40)) pygame.display.flip() #attende de 3 secondes pygame.time.wait(3000) #transition datas.ShowTransitionOfTheme(DUREETRANSITION, 'fond-buttons.bmp') #on recharge une nouvelle image if len(GLstFicConfig) > 1: nvidx = random.randint(0, len(GLstFicConfig) - 1) if nvidx == const.GIdxImage: #si la meme image qu'actuellement, on fait un second essai nvidx = random.randint(0, len(GLstFicConfig) - 1) const.GIdxImage = nvidx pygame.mouse.set_pos((const.GPosDepX, const.GPosDepY)) LoadBackgroundOfConfig(GLstThemesButtons[const.GIdxThemes]) const.tpsdebut = pygame.time.get_ticks() GLstBallons.draw(screen) screen.blit(GMaSouris, GMaSouris_position) pygame.display.flip()