#!/usr/bin/env python # -*- coding: utf8 -*- #*********************************************************************** # pysycache : a program for learn to use the mouse # Copyright (C) 2005-2007 Vincent DEROO (vincent.pysycache@free.fr) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc. : # 51 Franklin Street, Fifth Floor, Boston, MA02110-1301, 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 pysyclasses import * import const PIECEPOSED = 1 PIECENOTPOSED = 0 NODRAG = 0 DRAGSTARTED = 1 PIECELOIN = 20 PIECEPRES = 21 #******************************************************************************* # Classe # #******************************************************************************* class MovedPiece(pygame.sprite.Sprite): """This class is for the pieces during the drag and drop """ def __init__(self, filename, mouseleft, mousetop, targetleft, targettop, id): pygame.sprite.Sprite.__init__(self) #call Sprite intializer dirname = os.path.join("", filename, "1") self.image, self.rect = datas.Load_image(dirname, filename) (self.width, self.height) = self.image.get_size() self.rect.left = mouseleft - int(self.width / 2) self.rect.top = mousetop - int(self.height / 2) self.targetleft = targetleft self.targettop = targettop self.id = id self.left = self.rect.left self.top = self.rect.top screen = pygame.display.get_surface() screen.blit(self.image, (self.left, self.top)) def move(self, mouseleft, mousetop, background, ecart): #deplacement de l'element #on va effacer le dessous screen = pygame.display.get_surface() tr2 = pygame.Rect([self.left, self.top, self.width, self.height]) screen.blit(background, (self.left, self.top), tr2) self.rect.left = mouseleft - int(self.width / 2) self.rect.top = mousetop - int(self.height / 2) ok = 0 if const.GModeJeu == const.MODEFANTOM : if const.GIdPieceToDrop == self.id: ok = 1 else: ok = 1 if ok == 1: #on doit verifier la proximite if ( self.rect.left + ecart > self.targetleft) & ( self.rect.top + ecart > self.targettop) & (self.rect.left + self.width - ecart < self.targetleft + self.width ) & ( self.rect.top + self.height - ecart < self.targettop + self.height) : #on est proche de la cible... on met la souris en rose que si on #etait loin avant if const.GTypeSouris == PIECELOIN : for o in const.GLstSouris.sprites(): o.changepicture('souris-puzzlepink.png') const.GTypeSouris = PIECEPRES else: #on est loin de la cible... si avant on etait pres... on passe #la souris en normal if const.GTypeSouris == PIECEPRES : const.GTypeSouris = PIECELOIN for o in const.GLstSouris.sprites(): o.changepicture('souris-puzzle.png') self.left = self.rect.left self.top = self.rect.top class Piece: """A piece of the jigsaw """ targetleft = 0 #position sur le modele targettop = 0 boxleft = 0 #position dans la boite boxtop = 0 boxlargeur = 0 boxhauteur = 0 filename = '' backgrd = '' #image de fond pour le mode fantome id = 0 visible = PIECENOTPOSED #0 : la piece n'a pas ete posee #1 : a ete posee #******************************************************************************* # #******************************************************************************* class ApplicationPuzzle(ApplicationPysy): def __init__(self): ApplicationPysy.__init__(self) self.ImgBackground = "" self.ImgModele = "" self.EcartPiece = 40 #ecart pour le placement des pieces self.GIdxPremPieceCoffre = 0 #indice de la premiere piece visible du coffre self.PieceMoved = pygame.sprite.RenderClear() def InitializeApp(self, DirThemes, ActName): ApplicationPysy.InitializeApp(self, DirThemes, ActName) self.BackgroundBox, rectmp = datas.Load_image("images", 'fond-' + self.ActivityName + '.png') if const.GWithSound == 1: if const.GSoundError == 0: self.Channel0 = pygame.mixer.Channel(0) music = os.path.join(const.GRepPysycache, 'sounds', 'slide.wav').encode(const.GConsoleLocale) self.Sound0 = pygame.mixer.Sound(music) self.PuzzleWidth = 0 self.PuzzleHeight = 0 self.WaitForClick = True #*************************************************************************** # Retour 0 : on a pas gagne # 1 : on a gagne #*************************************************************************** def OnAGagne(self, gagne): if (const.GNbPieces == 0): gagne = 1 else: gagne = 0 return gagne #*************************************************************************** # #*************************************************************************** def DoPlayerGagne(self): screen = pygame.display.get_surface() Imggagne, rectgagne = datas.Load_image("", self.ImgBackground, None, True) self.Background.blit(Imggagne, (0 + const.MARGELEFT + 27, 0 + const.MARGETOP)) screen.blit(Imggagne, (0 + const.MARGELEFT + 27, 0 + const.MARGETOP)) pygame.display.update() pygame.time.wait(2000) #*************************************************************************** # #*************************************************************************** def GetPieceToDrop(self): if const.GModeJeu == const.MODEFANTOM : #on va designer la piece a installer if const.GNbPieces > 0: x = random.randint(0, const.GNbPieces - 1) cpt = 0 for pzl in const.GTabPuzzles: if pzl.visible == PIECEPOSED: #piece deja posee pass else: if cpt == x: #c'est cette piece qu'il faut poser screen = pygame.display.get_surface() ImgATrouv, recttmp = datas.Load_image("", pzl.backgrd , None, True) w, h = ImgATrouv.get_size() w2 = int(w * self.PuzzleWidth / 640) h2 = int(h * self.PuzzleHeight / 480) ImgATrouv = pygame.transform.scale(ImgATrouv, (w2, h2) ) self.Background.blit(ImgATrouv, (pzl.targetleft, pzl.targettop)) const.GIdPieceToDrop = pzl.id break cpt += 1 else: const.GIdPieceToDrop = 999 #*************************************************************************** # #*************************************************************************** def InitActivity(self, WithHasard): ApplicationPysy.InitActivity(self, WithHasard) const.StateOfDrag = NODRAG const.GTypeSouris = PIECELOIN const.GIdxMovedPiece = 0 self.ImgFond, background_rect = datas.Load_image("", self.ImgModele, None, True) screen = pygame.display.get_surface() #on copie ce cache sur l'image de fond screen = pygame.display.get_surface() self.Background.blit(self.ImgFond, (0 + const.MARGELEFT + 27, 0 + const.MARGETOP)) self.GetPieceToDrop() #afficher les pieces du puzzle dans le coffre self.GIdxPremPieceCoffre = 0 self.ShowPiecesOfPuzzle() #*************************************************************************** # #*************************************************************************** def MotionAfterMouse(self, event0, event1, str): ApplicationPysy.MotionAfterMouse(self, event0, event1, str) if (str[0] == 0) & (str[1] == 0) & (str[2] == 0): #on bouge sans avoir enfonce de bouton... #l'etat de la souris est a 0 0 0 if (const.GStateOfDrag == DRAGSTARTED) : #... mais on est en statut drag 'n drop ... #ce n'est pas normal screen = pygame.display.get_surface() screen.blit(self.Background, (0, 0)) const.GStateOfDrag = NODRAG for o in const.GLstSouris.sprites(): o.changepicture('souris-puzzle.png') #la souris n'est rose qu'en mode drag if (const.GStateOfDrag == DRAGSTARTED) : #on deplace la piece en meme temps que la souris for pce in self.PieceMoved.sprites() : pce.move(event0, event1, self.Background, self.EcartPiece) screen = pygame.display.get_surface() self.PieceMoved.draw(screen) #*************************************************************************** # #*************************************************************************** def DoOnMouseDown(self, event0, event1, str): ApplicationPysy.DoOnMouseDown(self, event0, event1, str) #recherche si n'est pas un des deux boutons avant/apres if ( event0 + const.DEMISOURIS >= 0 ) & ( event0 + const.DEMISOURIS <= 64) & ( event1 + const.DEMISOURIS >= 487 ) & ( event1 + const.DEMISOURIS <= 551 ) : #pieces avant self.GIdxPremPieceCoffre = self.GIdxPremPieceCoffre - 1 if self.GIdxPremPieceCoffre < 0: self.GIdxPremPieceCoffre = 0 self.ShowPiecesOfPuzzle() #et recopier la derniere piece (car chevauchement) self.ShowBtnMenus() if ( event0 + const.DEMISOURIS >= 648 ) & ( event0 + const.DEMISOURIS <= 712) & ( event1 + const.DEMISOURIS >= 487 ) & ( event1 + const.DEMISOURIS <= 551 ) : #pieces apres self.GIdxPremPieceCoffre += 1 if self.GIdxPremPieceCoffre > len( const.GTabPuzzles) - 1: self.GIdxPremPieceCoffre = len( const.GTabPuzzles) -1 self.ShowPiecesOfPuzzle() #et recopier la derniere piece (car chevauchement) self.ShowBtnMenus() i = 0 screen = pygame.display.get_surface() #----------------- recherche si est une piece a deplacer ------------ #on ne fait pas deplacer si en dehors de la zone if const.GChrono == 1: y = int(60 - float(pygame.time.get_ticks() - const.GTpsDebut)/1000) if y == 5: imgchrono, rectchrono = datas.Load_image("images", "chrono4.png") self.Background.blit(imgchrono, (736, 10)) screen.blit(imgchrono, (736, 10)) elif y == 15: imgchrono, rectchrono = datas.Load_image("images", "chrono3.png") self.Background.blit(imgchrono, (736, 10)) screen.blit(imgchrono, (736, 10)) elif y == 30: imgchrono, rectchrono = datas.Load_image("images", "chrono2.png") self.Background.blit(imgchrono, (736, 10)) screen.blit(imgchrono, (736, 10)) elif y >= 58: imgchrono, rectchrono = datas.Load_image("images", "chrono1.png") self.Background.blit(imgchrono, (736, 10)) screen.blit(imgchrono, (736, 10)) for obj in const.GTabPuzzles: if ( event0 + const.DEMISOURIS >= obj.boxleft ) & ( event0 + const.DEMISOURIS <= obj.boxleft + obj.boxlargeur ) & ( event1 + const.DEMISOURIS >= obj.boxtop ) & ( event1 + const.DEMISOURIS <= obj.boxtop + obj.boxhauteur ) : #on va commencer a faire glisser la piece const.GStateOfDrag = DRAGSTARTED const.GTypeSouris = PIECELOIN #on recupere la piece qu'il faut deplacer const.GIdxMovedPiece = obj.id self.PieceMoved.empty() self.PieceMoved.add(MovedPiece(obj.filename, event0, event1, obj.targetleft, obj.targettop, obj.id)) self.PieceMoved.draw(screen) # pygame.display.update() break i += 1 const.GLstSouris.draw(screen) pygame.display.update() #*************************************************************************** # #*************************************************************************** def DoOnMouseUpAfterButtons(self, event0, event1): ApplicationPysy.DoOnMouseUpAfterButtons(self, event0, event1) ok = 0 if (const.GStateOfDrag == DRAGSTARTED) : #on est a la fin du deplacement screen = pygame.display.get_surface() if (const.GTypeSouris == PIECEPRES) : cpt = 0 for pzl in const.GTabPuzzles: if (pzl.id == const.GIdxMovedPiece) : #on recherche la piece concernee if const.GModeJeu == const.MODEFANTOM : if const.GIdPieceToDrop == pzl.id: ok = 1 else: ok = 1 if ok == 1: #on informe que la piece est posee pzl.visible = PIECEPOSED self.PieceMoved.empty() datas.DebugMessage( "I put the piece id " + str(pzl.id) + " with the visibility " + str(pzl.visible)) #on colle la piece a sa position filename = os.path.join(self.LstThemesOfActivity[const.GIdxThemes], "1", pzl.filename) imgtmp, background_rect = datas.Load_image("", pzl.filename, None, True) self.Background.blit(imgtmp, (pzl.targetleft, pzl.targettop)) ok = 1 #on joue la musique if const.GWithSound == 1: if const.GSoundError == 0: self.Channel0.play(self.Sound0) #on diminue le nombre de pieces restants const.GNbPieces = const.GNbPieces - 1 datas.DebugMessage("") datas.DebugMessage("Number of leaving pieces " + str(const.GNbPieces)) del const.GTabPuzzles[cpt] #On redessine la souris en blanc for o in const.GLstSouris.sprites(): o.changepicture('souris-puzzle.png') #on recharge les pieces du puzzle self.GetPieceToDrop() if const.GModeJeu == const.MODEFANTOM : #effacer la zone de l'ecran concernant la boite a piece screen = pygame.display.get_surface() self.Background.blit(self.BackgroundBox, (67, 487), (67, 487, 640, 110)) self.ShowPiecesOfPuzzle() screen.blit(self.Background, (0, 0)) #et recopier la derniere piece (car chevauchement) self.ShowBtnMenus() break cpt += 1 else: datas.DebugMessage("trop loin") for o in const.GLstSouris.sprites(): o.changepicture('souris-puzzle.png') screen.blit(self.Background, (0, 0)) #redessin de la souris a sa position const.GLstSouris.draw(screen) pygame.display.update() const.GStateOfDrag = NODRAG #*************************************************************************** # #*************************************************************************** def DoInitLevel(self): """ """ ApplicationPysy.DoInitLevel(self) self.EcartPiece = 60 if const.GLevel == 0: self.EcartPiece = 60 elif const.GLevel == 1 : self.EcartPiece = 40 else: self.EcartPiece = 20 #*************************************************************************** # #*************************************************************************** def GetLevelForDfgFile(self, levelname): return str(const.GLevel) #*************************************************************************** # #*************************************************************************** def ReadDfgFile(self): """ Charge le fond a partir d'un fichier de configuration contenus dans le repertoire""" ApplicationPysy.ReadDfgFile(self) #effacer l'existant const.GTabPuzzles[:] = [] #------------------ on va lire le fichier de configuration ----------------- configname = self.LstFicConfig[self.IdxFileDfg] datas.DebugMessage("") datas.DebugMessage("dfg file (number : " + str(self.IdxFileDfg) + ") named " + configname) (dirpath, dirname) = os.path.split(configname) cpt = 0 i = 0 nb1 = 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 fond (f1, f2) = os.path.split(dirpath) lig = lig.split('|') if len(lig) == 3: self.PuzzleWidth = int(lig[1]) self.PuzzleHeight = int(lig[2]) self.ImgBackground = os.path.join(f1, lig[0]) else: self.PuzzleWidth = 640 self.PuzzleHeight = 480 self.ImgBackground = os.path.join(f1, lig[0]) if cpt == 1: #le modele du puzzle self.ImgModele = os.path.join(dirpath, lig) if cpt >= 2: #les morceaux du puzzle pce = Piece() lig = lig.split('|') pce.targetleft = int(lig[1]) + const.MARGELEFT + 27 pce.targettop = int(lig[2]) + const.MARGETOP pce.filename = os.path.join(dirpath, lig[0]) pce.backgrd = os.path.join(dirpath, lig[3]) pce.id = i const.GTabPuzzles.append(pce) i += 1 cpt += 1 f.close() #MAJ du nombre de piece a voir const.GNbPieces = i #*************************************************************************** # Affiche les pieces du puzzle dans le coffre #*************************************************************************** def ShowPiecesOfPuzzle(self): NbPieceCoffre = 5 #effacer la zone de l'ecran concernant la boite a piece screen = pygame.display.get_surface() self.Background.blit(self.BackgroundBox, (67, 487), (67, 487, 640, 110)) screen.blit(self.BackgroundBox, (67, 487), (67, 487, 640, 110)) #afficher les pieces i = 0 cptvisible = 0 for pzl in const.GTabPuzzles: datas.DebugMessage ("i=" + str(i) + " visible = " + str(pzl.visible)) if cptvisible >= NbPieceCoffre : pzl.boxleft = -1 pzl.boxtop = -1 else: if i >= self.GIdxPremPieceCoffre: if pzl.visible == PIECENOTPOSED : #la piece n'est pas posee : on peut donc l'afficher imgtmp, self.rect = datas.Load_image("", pzl.filename, None, True) width = 0 height = 0 (pzl.largeur, pzl.hauteur) = imgtmp.get_size() coefwidth = float(pzl.largeur) / 116 #largeur admissible pour les pieces posees coefheight = float(pzl.hauteur) / 107 #hauteur admissible pour les pieces posees if coefwidth > coefheight : coefimg = coefwidth else : coefimg = coefheight pzl.coef = coefimg pzl.boxlargeur = int(pzl.largeur / coefimg) pzl.boxhauteur = int(pzl.hauteur / coefimg) imgtmp = pygame.transform.scale(imgtmp, (pzl.boxlargeur, pzl.boxhauteur )) pzl.boxleft = 69 + 116 * cptvisible pzl.boxtop = 489 self.Background.blit(imgtmp, (pzl.boxleft, pzl.boxtop)) screen.blit(imgtmp, (pzl.boxleft, pzl.boxtop)) cptvisible += 1 else: pzl.boxleft = -1 pzl.boxtop = -1 else: pzl.boxleft = -1 pzl.boxtop = -1 i += 1 if cptvisible == 0: # i = 0 # for pzl in const.GTabPuzzles: # if i <= self.GIdxPremPieceCoffre : # if pzl.visible == PIECENOTPOSED : # cptvisible += 1 # else: # break # # i += 1 self.GIdxPremPieceCoffre = self.GIdxPremPieceCoffre - 1 if self.GIdxPremPieceCoffre >= 0: self.ShowPiecesOfPuzzle()