#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)
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:
Puis après avoir cliqué une fois dans l'image:
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
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 ?
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 !
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)
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