Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 08/07/2011, à 17:04

xanmoo

[résolu] Bouger un sprite (Drag and drop:pygame)

Bonjour,
Je débute avec pygame, et je rencontre quelques difficultés avec le module sprite. Le but est de spécifier la position d'un sprite à la souris:

Je voudrais:

  • Afficher des sprites (un seul pour commencer)

Image pour construire le sprite

  • Cliquer dessus (avec un effet graphique pour vérifier l'action)

  • Cliquer ailleurs dans l'image pour pour spécifier la nouvelle position ce qui entraine la disparition du sprite de sa position initiale et son apparition à sa position finale.

Je me suis inspiré du script Birds:

# -*- coding: utf-8 -*-
"""
Created on Thu Jul  7 14:27:47 2011

@author: Jean-Patrick Pommier
"""

import scipy
import os
import sys
import pygame

pygame.init()
screen=pygame.display.set_mode((800,600))


class Chrom(pygame.sprite.Sprite):
    image=[]  # list of all images
    # not necessary:
#    chromosomes = {} # a dictionary of all chromosomes, each chromosome has its own number
    number = 0  
    def __init__(self, image, startpos=(50,50), area=screen.get_rect()):
        pygame.sprite.Sprite.__init__(self, self.groups)
        self.pos = [0.0,0.0]
        self.pos[0] = startpos[0]*1.0 # float
        self.pos[1] = startpos[1]*1.0 # float
        self.image = Chrom.image
        self.rect = self.image.get_rect()
        self.area = area # where the sprite is allowed to move
        self.selected = False ## caught
        self.timeClicked=0
        
    def update(self):
        mpos=pygame.mouse.get_pos()#mouseposition
        buttons=pygame.mouse.get_pressed#usefull?
        self.selected=pygame.Rect.collidepoint(mpos)
        #test if the mouse click on the sprite for the first time
        if self.selected==True:
            self.timeClicked=self.timeClicked+1
            if self.timeClicked==2:
                #unselect the sprite                
                self.image.set_alpha(255)
                self.timeClicked=0     
            elif self.timeClicked==1:
                #select the sprite, show a visual effect
                self.image.set_alpha(50)
        #The sprite was clicked once        
        #A click outside the sprite gives the new position
        if (self.timeClicked==1 and buttons==pygame.MOUSEBUTTONDOWN):
            #new position
            self.pos=pygame.mouse.get_pos()
            self.image.set_alpha(255)
            
#===============================================================================
# 
#===============================================================================
def main():
   pygame.display.set_caption('Testing')
   running = True
   chr1=Chrom(karyoIm[2],(0,0))
   while running:
      for event in pygame.event.get():
         if event.type == pygame.QUIT:
            running = False
         if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
         if event.type ==pygame.MOUSEBUTTONDOWN:
             chr1.update()
             print pygame.mouse.get_pos()
   pygame.display.quit()

#===============================================================================
# 
#===============================================================================
user=os.path.expanduser("~")
workdir=os.path.join(user,"Applications","ImagesTest","jp","Jpp48","13","DAPI","particules")
#print os.path.isfile(workdir+"/part0.png")
#list all the images called partXX.png with XX=00 to 35
n=0
karyoIm=[]
chrIm=os.path.join(workdir,"part"+str(n)+".png")
print chrIm
while os.path.isfile(chrIm):
    im=pygame.image.load(chrIm).convert()
    im.set_colorkey((0,0,0))
    karyoIm.append(im.copy())
    n=n+1
    chrIm=os.path.join(workdir,"part"+str(n)+".png")
print len(karyoIm)

if __name__ == '__main__':
    
    main()

Bon, ça plante:

/home/claire/Applications/ImagesTest/jp/Jpp48/13/DAPI/particules/part0.png
36
Traceback (most recent call last):
  File "/home/claire/Applications/ProjetPython/projet particule et objet/SpritesKaryo_mouse.py", line 110, in <module>
    main()
  File "/home/claire/Applications/ProjetPython/projet particule et objet/SpritesKaryo_mouse.py", line 77, in main
    chr1=Chrom(karyoIm[2],(0,0))
  File "/home/claire/Applications/ProjetPython/projet particule et objet/SpritesKaryo_mouse.py", line 40, in __init__
    pygame.sprite.Sprite.__init__(self, self.groups)
  File "/usr/lib/python2.6/dist-packages/pygame/sprite.py", line 114, in __init__
    if groups: self.add(groups)
  File "/usr/lib/python2.6/dist-packages/pygame/sprite.py", line 129, in add
    else: self.add(*group)
  File "/usr/lib/python2.6/dist-packages/pygame/sprite.py", line 129, in add
    else: self.add(*group)
TypeError: add() argument after * must be a sequence, not instancemethod

Cela doit venir du constructeur.
Merci pour vos conseil.

Dernière modification par xanmoo (Le 12/09/2011, à 15:54)


Portable IBM Thinkpad R50e 2 Go | 40 Go: MX Linux 19.4
Portable IBM Thinkpad T430 8 Go | 240 Go: endeavour OS
Dell Precision T5500, Xeon x5570, 24Go, GTX 960- 4Go,  SSD 120Go, Ubuntu 22.04
http://dip4fish.blogspot.com/

Hors ligne

#2 Le 13/07/2011, à 15:42

haku_arsene

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

Salut,
en effet il y a un problème dans le constructeur, self.groups n'est pas défini au moment de l'appel de pygame.sprite.Sprite.__init__.
J'ai supposé que ta liste de toutes les images est en fait le groupe, ce qui donne :

class Chrom(pygame.sprite.Sprite):
    images=[]  # list of all images
    # not necessary:
#    chromosomes = {} # a dictionary of all chromosomes, each chromosome has its own number
    number = 0  
    def __init__(self, image, startpos=(50,50), area=screen.get_rect()):
        pygame.sprite.Sprite.__init__(self, Chrom.images)
        self.pos = [0.0,0.0]
        self.pos[0] = startpos[0]*1.0 # float
        self.pos[1] = startpos[1]*1.0 # float
        self.image = image
        self.rect = self.image.get_rect()
        self.area = area # where the sprite is allowed to move
        self.selected = False ## caught
        self.timeClicked=0

Au passage je l'ai renommé en images pour ne pas confondre avec self.image.

Ça a l'air de marcher...

Ensuite il y a un petit problème dans update. Il faut remplacer

self.selected=pygame.Rect.collidepoint(mpos)

par

self.selected=self.rect.collidepoint(mpos)

Ensuite pour afficher, j'ai ajouté deux lignes dans la boucle principale.

def main():
   pygame.display.set_caption('Testing')
   running = True
   chr1=Chrom(karyoIm[2],(0,0))
   while running:
      for event in pygame.event.get():
         if event.type == pygame.QUIT:
            running = False
         if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
         if event.type ==pygame.MOUSEBUTTONDOWN:
             chr1.update()
             print pygame.mouse.get_pos()
      pygame.display.get_surface().blit(chr1.image,chr1.pos)
      pygame.display.flip()
   pygame.display.quit()

Reste à gérer les clics.
Je ne sais pas si cet exemple est le plus simple pour comprendre...

Hors ligne

#3 Le 15/07/2011, à 11:05

xanmoo

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

merci,
Je vais essayer tout ça.


Portable IBM Thinkpad R50e 2 Go | 40 Go: MX Linux 19.4
Portable IBM Thinkpad T430 8 Go | 240 Go: endeavour OS
Dell Precision T5500, Xeon x5570, 24Go, GTX 960- 4Go,  SSD 120Go, Ubuntu 22.04
http://dip4fish.blogspot.com/

Hors ligne

#4 Le 18/07/2011, à 12:12

xanmoo

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

Bonjour,
J'ai modifier le script comme indiqué. Le sprite s'affiche, mais je ne parviens pas à le déplacer.
Pour voir un comment faire évoluer le script, j'ai introduit un deuxième sprite et ça se gâte:

# -*- coding: utf-8 -*-
"""
Created on Sat Jul 16 17:09:16 2011

@author: claire
"""

import scipy
import os
import sys
import pygame

pygame.init()
screen=pygame.display.set_mode((800,600))


class Chrom(pygame.sprite.Sprite):
    images=[]  # list of all images
    # not necessary:
#    chromosomes = {} # a dictionary of all chromosomes, each chromosome has its own number  
    def __init__(self, image,number, startpos=(50,50), area=screen.get_rect()):
        pygame.sprite.Sprite.__init__(self, Chrom.images)
        self.pos = [0.0,0.0]
        self.pos[0] = startpos[0]*1.0 # float
        self.pos[1] = startpos[1]*1.0 # float
        self.image = image
        self.rect = self.image.get_rect()
        self.area = area # where the sprite is allowed to move
        self.selected = False ## caught
        self.timeClicked=0
        self.number = 0
    def update(self):
        mpos=pygame.mouse.get_pos()#mouseposition
        buttons=pygame.mouse.get_pressed#usefull?
        self.selected=self.rect.collidepoint(mpos)
        #test if the mouse click on the sprite for the first time
        if self.selected==True:
            print "sprite",self.number," clicked:",self.timeClicked
            self.timeClicked=self.timeClicked+1
            if self.timeClicked==2:
                #unselect the sprite                
                self.image.set_alpha(255)
                self.timeClicked=0     
            if self.timeClicked==1:
                #select the sprite, show a visual effect
                self.image.set_alpha(50)
        #The sprite was clicked once        
        #A click outside the sprite gives the new position
        if (self.timeClicked==1 and buttons==pygame.MOUSEBUTTONDOWN):
            #new position
            self.pos=pygame.mouse.get_pos()
            self.image.set_alpha(255)
#===============================================================================
# 
#===============================================================================
def main():
   pygame.display.set_caption('Testing')
   running = True
   chr1=Chrom(karyoIm[5],1,(100,200))
   chr2=Chrom(karyoIm[30],2,(50,100))
   kar=pygame.sprite.RenderUpdates(chr1)
   kar=pygame.sprite.RenderUpdates(chr2)
   while running:
      for event in pygame.event.get():
         if event.type == pygame.QUIT:
            running = False
         if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
         if event.type ==pygame.MOUSEBUTTONDOWN:
             chr1.update()
             chr2.update()
             kar.update()
             kar.draw(screen)
             pygame.display.flip()
             print pygame.mouse.get_pos()
      pygame.display.get_surface().blit(chr1.image,chr1.pos)
      pygame.display.get_surface().blit(chr2.image,chr2.pos)
      pygame.display.flip()
   pygame.display.quit()

#===============================================================================
# 
#===============================================================================
user=os.path.expanduser("~")
workdir=os.path.join(user,"Applications","ImagesTest","jp","Jpp48","13","DAPI","particules")
#print os.path.isfile(workdir+"/part0.png")
#list all the images called partXX.png with XX=00 to 35
n=0
karyoIm=[]
chrIm=os.path.join(workdir,"part"+str(n)+".png")
print chrIm
while os.path.isfile(chrIm):
    im=pygame.image.load(chrIm).convert()
    im.set_colorkey((0,0,0))
    karyoIm.append(im.copy())
    n=n+1
    chrIm=os.path.join(workdir,"part"+str(n)+".png")
print len(karyoIm)

if __name__ == '__main__':
    main()

Potentiellement, on doit manipuler ici 36 chromosomes.
Au lancement, on a:
démarrage du script

Puis après avoir cliqué une fois dans l'image:
duplication
un des sprite est dupliqué et n'est pas afficher au bon endroit.

De plus quand on clique sur les sprites, un seul semble détecter l'événement "être cliqué (avoir le focus)":

/particules/part0.png
36
(90, 121)
(132, 230)
(92, 121)
sprite 0  clicked: 0
sprite 0  clicked: 0
sprite 0  clicked: 1
(44, 14)

La classe est à revoir, ainsi que la boucle d'événement.

Faut-il mettre le code pour gérer l'interaction (avoir le focus,...) avec la souris dans la classe Chrom?
Je cherche un exemple de code avec plusieurs sprites différents avec une boucle type:

  • un sprite selectionné à la souris

  • réaction du sprite

  • clic de souris  pour fixer la destination du sprite selectionné

  • déplacement du sprite

merci

Dernière modification par xanmoo (Le 18/07/2011, à 12:14)


Portable IBM Thinkpad R50e 2 Go | 40 Go: MX Linux 19.4
Portable IBM Thinkpad T430 8 Go | 240 Go: endeavour OS
Dell Precision T5500, Xeon x5570, 24Go, GTX 960- 4Go,  SSD 120Go, Ubuntu 22.04
http://dip4fish.blogspot.com/

Hors ligne

#5 Le 28/07/2011, à 17:15

doudoulolita

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

Je m'entraine sur Pygame ( voir Faire une animation... ) pour réaliser des programmes pour enfants. Je suis encore débutante en programmation mais j'ai déjà réussi à créer un petit jeu assez simple nommé Miks_game.

Je vais suivre votre discussion sur le module Sprite, que je n'ai pas encore testé.

miks_static1.png   miks_walk2.png   Miks
Pour moi, l'intérêt pour un prochain jeu sera de déplacer avec les touches du pavé numérique des personnages qui marchent (avec 2 frames pour commencer). Plus tard, peut-être faire attraper des objets par le personnage, en suivant un ordre précis (ou les faire s'assoir sur des chaises numérotées)
Et les chromosomes, ils se tortilleront dans ce jeu ? wink

Plus sérieusement, je compte aussi proposer mon jeu aux institutrices de maternelles qui amènent leurs élèves dans l'Espace Public Numérique où je travaille, lorsqu'il sera plus au point sur un plan pédagogique. Je m'intéresse aussi en ce moment aux "jeux sérieux" (serious games) et notre association a été créée par des scientifiques, donc les chromosomes, c'est cool ! cool

Pour les déplacements, utilises-tu une classe Vecteur ?  Voir le blog de Will McGugan et http://www.willmcgugan.com/gameobjects/docs/index.html.
Un des exemples de son bouquin Beginning Game Development with Python and Pygame se fait sur des fourmis, ça ressemble pas mal à tes chromosomes.

Dernière modification par doudoulolita (Le 28/07/2011, à 17:41)

Hors ligne

#6 Le 08/09/2011, à 21:37

xanmoo

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

Bonjour,
@doudoulolita:euh désolé de répondre aussi tard: je n'utilise pas gameobject (pas de tuto, exemple, juste la doc automatique)
@haku_arsene:merci pour

self.selected=self.rect.collidepoint(mpos)

je continue ma quête, le but étant de choisir un sprite (on clic dessus, on drag et on lache) et de le déplacer, mon code ressemble à cela:
          *créer des sprites (deux)
          *Dans la classe dérivée de sprite, il faut:
                  *détecter le survol de la souris
                  *détecter le clic de souris
                  *gérer le déplacement du sprite
         *boucle d'événement et rafraichissement
ce qui donne:

# -*- coding: utf-8 -*-
"""
Created on Mon Sep  5 15:44:42 2011

@author: jean-pat
"""

#!/usr/bin/env python
#modified from
#http://www.siteduzero.com/forum-83-274873-p1-pygame-chimp-modifie.html
#
import os, pygame
from pygame.locals import*

def load_image(name, colorkey=None):
    fullname=os.path.join("data", name)
    try:
        image=pygame.image.load(fullname)
    except pygame.error, message:
        print "Impossible de charger l'image:",name
        raise SystemExit, message
    image = image.convert()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = image.get_at((0, 0))
        image.set_colorkey(colorkey, RLEACCEL)
    return image, image.get_rect()

class Ichrom(pygame.sprite.Sprite):
    def __init__(self,image,initpos):
        pygame.sprite.Sprite.__init__(self)
        self.pos = initpos
        self.image, self.rect=image
        self.button=(0,0,0)#mouse buttons not pressed
        self.selected = 0
        print "init chrom at ",self.pos
    def update(self):
        self.button=pygame.mouse.get_pressed()
        mpos=pygame.mouse.get_pos()#mouseposition
        self.selected=self.rect.collidepoint(mpos)
        print "chr",self,"selected",self.selected
        if (self.selected==1):
            print "mouse pos:",mpos
            if self.button==(1,0,0):     # )  
                pos = pygame.mouse.get_pos()
                self.rect.midtop = pos

def main():
    pygame.init()
    screen = pygame.display.set_mode((400,300))
    pygame.display.set_caption("Karyotyper")
    pygame.mouse.set_visible(True)
    
    background = pygame.Surface(screen.get_size())
    background = background.convert()
    background.fill((0, 0, 0))

    screen.blit(background,(0, 0))
    pygame.display.flip()
    
    i1=load_image("/home/claire/Applications/ImagesTest/jp/Jpp48/13/DAPI/particules/part15.png", -1)
    i2=load_image("/home/claire/Applications/ImagesTest/jp/Jpp48/13/DAPI/particules/part9.png", -1)
    chr1 = Ichrom(i1,(0,0))
    chr2=Ichrom(i2,(30,30))
    allsprites = pygame.sprite.RenderPlain((chr1,chr2))
    clock = pygame.time.Clock()

    while 1:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == QUIT:
                return
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                return
    
        allsprites.update()
        
        screen.blit(background,(0,0))
        allsprites.draw(screen)
        pygame.display.flip()
    
if __name__ == '__main__': main()

cela ne fonctionne pas, je ne peux que déplacer les sprites que un peu vers la droite et en bas, ensuite impossible de les remonter. Quend on clic sur un il "saute vers le bas.

Si je vire le test de collision entre la souris et un sprite, tous les sprites sont "drag and dropés":
Ici le résultat avec un seul sprite.

class Ichrom(pygame.sprite.Sprite):
    def __init__(self,image,initpos):
        pygame.sprite.Sprite.__init__(self)
        self.pos = initpos
        self.image, self.rect=image
        self.button=(0,0,0)#mouse buttons not pressed
        self.selected = 0
        print "init chrom at ",self.pos
    def update(self):
        self.button=pygame.mouse.get_pressed()
        mpos=pygame.mouse.get_pos()#mouseposition
        self.selected=self.rect.collidepoint(mpos)
        print "chr",self,"selected",self.selected
        #if (self.selected==1):
        print "mouse pos:",mpos
        if self.button==(1,0,0):     # )  
            pos = pygame.mouse.get_pos()
            self.rect.midtop = pos

Dernière modification par xanmoo (Le 08/09/2011, à 21:53)


Portable IBM Thinkpad R50e 2 Go | 40 Go: MX Linux 19.4
Portable IBM Thinkpad T430 8 Go | 240 Go: endeavour OS
Dell Precision T5500, Xeon x5570, 24Go, GTX 960- 4Go,  SSD 120Go, Ubuntu 22.04
http://dip4fish.blogspot.com/

Hors ligne

#7 Le 08/09/2011, à 21:51

xanmoo

Re : [résolu] Bouger un sprite (Drag and drop:pygame)


Portable IBM Thinkpad R50e 2 Go | 40 Go: MX Linux 19.4
Portable IBM Thinkpad T430 8 Go | 240 Go: endeavour OS
Dell Precision T5500, Xeon x5570, 24Go, GTX 960- 4Go,  SSD 120Go, Ubuntu 22.04
http://dip4fish.blogspot.com/

Hors ligne

#8 Le 12/09/2011, à 15:07

xanmoo

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

je progresse petit à petit. Je relisant ce code, j'ai trouvé une réponse partielle
Reste à gérer une liste de sprites et la collision avec d'autres sprites.

Dernière modification par xanmoo (Le 27/09/2011, à 09:13)


Portable IBM Thinkpad R50e 2 Go | 40 Go: MX Linux 19.4
Portable IBM Thinkpad T430 8 Go | 240 Go: endeavour OS
Dell Precision T5500, Xeon x5570, 24Go, GTX 960- 4Go,  SSD 120Go, Ubuntu 22.04
http://dip4fish.blogspot.com/

Hors ligne

#9 Le 23/09/2011, à 13:54

doudoulolita

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

xanmoo a écrit :

je progresse petit à petit. Je relisant ce code, j'ai trouvé une réponse partielle
Reste à gérer une liste de sprites et la collision avec d'autres sprites.

Lien incorrect vers le code, ce n'est pas plutôt ça : http://thepythongamebook.com/en:part2:pygame:step014

Hors ligne

#10 Le 27/09/2011, à 09:19

xanmoo

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

merci, c'est corrigé.
Depuis, j'ai introduit la rotation des chromosomes.
En ce moment, j'essaie de définir une classe pour lire les images en utilisant un fichier de configuration de manière à ne pas modifier le script quand on change d'image.


Portable IBM Thinkpad R50e 2 Go | 40 Go: MX Linux 19.4
Portable IBM Thinkpad T430 8 Go | 240 Go: endeavour OS
Dell Precision T5500, Xeon x5570, 24Go, GTX 960- 4Go,  SSD 120Go, Ubuntu 22.04
http://dip4fish.blogspot.com/

Hors ligne

#11 Le 27/09/2011, à 13:40

doudoulolita

Re : [résolu] Bouger un sprite (Drag and drop:pygame)

Moi, je me suis inspirée de ça pour le module Sprite : piman's writing.
J'ai encore quelques erreurs dans mon code pour animer mon Sprite mais ça avance grâce au forum.

Hors ligne