IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Programmation multimédia/Jeux Python Discussion :

[pygame] Manipulation d'un tank


Sujet :

Programmation multimédia/Jeux Python

  1. #1
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut [pygame] Manipulation d'un tank
    Bonjour à tous,

    Voilà, j'ai en tete un petit jeu tout bete pour le fun, et apprendre à manipuler pygame (surtout). L'idée doit pas etre mauvaise car j'apprend plein de choses, cependant, je but sur un probleme.

    J'ai un tank (mon perso). A terme, il sera constitué de 2 images superposées (1 pour la tourelle/canon; 1 pour le corps). Le but est de pouvoir dirigé le tank via les fleches, et orienté le canon via le curseur de la souris.

    A l'heure actuelle, je n'ai qu'une seule image représentant le tank en entier, pour simplifier mon dev/apprentissage.

    Mes constats sont les suivants:
    -Si je ne fait que déplacer le char avec les fleches, cela fonctionne.
    -Si je ne fait que tourner l'image (en bougeant simplement la souris), cela fonctionne.
    -Si j'enchaine ces deux actions, l'image bouge légèrement (les coordonnées bougent).
    -Si j'essaie de faire les deux actions en meme temps (canon + mouvement), tel que cela devra fonctionner à terme, ça part en vrille totale.

    Je ne comprend pas pourquoi en séparé cela fonctionne, mais pas en simultané. J'ai déjà fait pas mal de manip sans succès. Quelqu'un aurait une idée? Merci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    #!/usr/bin/env python
    # -*-coding:utf-8 -*
     
    import pygame
    import math
    from pygame.locals import *
     
    def rot_center(image, rect, angle):
    	"""rotate an image while keeping its center"""
    	rot_image = pygame.transform.rotate(image, angle)
    	w = math.sqrt(rect.width**2 + rect.height**2)
    	rot_rect = rot_image.get_rect(center=rect.center, size=(w,w))
    	return rot_image,rot_rect
     
     
    pygame.init()
    pygame.key.set_repeat(30, 50)
    #Ouverture de la fenêtre Pygame
    fenetre = pygame.display.set_mode((640, 480))
     
    #Chargement et collage du fond
    fond = pygame.image.load("/home/sg/Images/background.jpg").convert()
    fenetre.blit(fond, (0,0))
     
    #Chargement et collage du personnage
    perso = pygame.image.load("/home/sg/Images/tank2.png").convert_alpha()
    perso = pygame.transform.scale(perso, (50,80))
    position_perso = perso.get_rect()
    perso2 = perso
    position_perso2 = position_perso
     
    fenetre.blit(perso, position_perso)
     
    #Rafraîchissement de l'écran
    pygame.display.flip()
     
    #BOUCLE INFINIE
    continuer = 1
    x=0
    y = 0
    i = 0
    while continuer:
    	pygame.time.Clock().tick(10)
    	for event in pygame.event.get():    #Attente des événements
    		if event.type == QUIT:
    			continuer = 0
    		if event.type == KEYDOWN:
    			if event.key == K_DOWN: #Si "flèche bas"
    				#On descend le perso
    				if position_perso2.bottom + 10 <= 480:
    					position_perso2 = position_perso2.move(0,10)
    			if event.key == K_UP: #Si "flèche haut"
    				#On monte le perso
    				if position_perso2.top - 10 >= 0:
    					position_perso2 = position_perso2.move(0,-10)
    			if event.key == K_LEFT: #Si "flèche gauche"
    				#On gauche le perso
    				position_perso2 = position_perso2.move(-10,0)
    			if event.key == K_RIGHT: #Si "flèche droite"
    				#On droite le perso
    				position_perso2 = position_perso2.move(10,0)
     
    			position_perso[0] = position_perso2[0]
    			position_perso[1] = position_perso2[1]
    			print "p1=",position_perso2
     
     
    		if event.type == MOUSEBUTTONDOWN and event.button == 3:
    			position_perso2[0] = event.pos[0]
    			position_perso2[1] = event.pos[1]
    			position_perso[0] = event.pos[0]
    			position_perso[1] = event.pos[1]
    			print "p2=",position_perso2
     
     
    		#if event.type == MOUSEMOTION and event.buttons[0] == 1:
    		if event.type == MOUSEMOTION:
    			x = event.pos[0]
    			y = event.pos[1]
     
    			dx = x - position_perso2.center[0]
    			dy = y - position_perso2.center[1]
    			hyp = math.sqrt(dx**2 + dy**2)
     
    			rads = math.atan2(-dy,dx)
    			degs = math.degrees(rads) - 90 #decalage de 90° de l'image rapport au 0°
    			angle = degs
     
    			perso2, position_perso2 = rot_center(perso, position_perso, angle)
    			print "p3=",position_perso2
     
    			#perso2 = pygame.transform.scale(perso, (500,500))
     
    	#Re-collage
    	fenetre.blit(fond, (0,0))  
    	fenetre.blit(perso2, (position_perso2[0],position_perso2[1]))
    	#Rafraichissement
    	pygame.display.flip()
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    Que vient faire le module math dans l'histoire ?

  3. #3
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    le module math me sert pour calculer l'angle de rotation (L. 85 dans mon code), et pour limiter la taille du nouveau rectangle, lors de la rotation.
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    Ok, là j'ai pas le temps de tester le code avant 23h00.
    Il faudrait que tu mette les images.

  5. #5
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Apres quelque essais, si ça peut aider, le probleme semble venir de l'intreraction de la fonction rotation avec le reste du code). J'ai placé un print juste avant le return, pour comparer rect.center et rot_rect.center, qui normalement doivent être identique, et ils ne le sont jamais.

    EDIT: ci-joint les images. Merci beaucoup de ton aide
    Images attachées Images attachées   
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  6. #6
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Voici une version plus prche de mes attentes. Finalement j'ai réussit à faire fonctionné el tout (un conflit je pense, j'ai réécrit une partie du code simplement). Par contre, j'ai un probleme de superposition d'image (centres non superposés) lorsuqe l'on va à l'horizontal.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    #!/usr/bin/env python
    # -*-coding:utf-8 -*
     
    import pygame
    import math
    from pygame.locals import *
     
    def rot_center(image, rect, angle):
    	"""rotate an image while keeping its center"""
    	rot_image = pygame.transform.rotate(image, angle)
    	rot_rect = rot_image.get_rect(center=rect.center)
    	print "rect=",rect.center," rect2=", rot_rect.center
    	return rot_image,rot_rect
     
     
    def change_image(image, rect, cible, rect_cible):
    	rect.center = rect_cible.center
    	cible = image
    	rect_cible = rect_cible.fit(rect)
    	rect_cible.center = rect.center
    	return cible, rect_cible
     
     
    pygame.init()
    pygame.key.set_repeat(30, 50)
    #Ouverture de la fenêtre Pygame
    fenetre = pygame.display.set_mode((640, 480))
     
    #Chargement et collage du fond
    fond = pygame.image.load("/home/sg/Images/fond.png").convert()
    fond = pygame.transform.scale(fond, (640,480))
    fenetre.blit(fond, (0,0))
     
    #Chargement et collage du personnage
    base = pygame.image.load("/home/sg/Images/base.png").convert_alpha()
    base2 = pygame.image.load("/home/sg/Images/base2.png").convert_alpha()
    coord_base = base.get_rect()
    coord_base2 = base2.get_rect()
    print coord_base.center, "||", coord_base2.center
    coord_base2.center = coord_base.center
    print coord_base.center, "||", coord_base2.center
     
    tourelle = pygame.image.load("/home/sg/Images/tourelle.png").convert_alpha()
    coord_tourelle = tourelle.get_rect()
     
     
    base_scr = base
    tourelle_scr = tourelle
    coord_base_scr = base_scr.get_rect()
    coord_tourelle_scr = tourelle_scr.get_rect()
     
    coord_tourelle_scr.center = coord_base_scr.center
     
     
    fenetre.blit(base_scr, coord_base_scr)
    fenetre.blit(tourelle_scr, coord_tourelle_scr)
     
     
    #Rafraîchissement de l'écran
    pygame.display.flip()
     
    #BOUCLE INFINIE
    continuer = 1
    x=0
    y = 0
     
    while continuer:
    	pygame.time.Clock().tick(50)
    	for event in pygame.event.get():    #Attente des événements
    		if event.type == QUIT:
    			continuer = 0
    		if event.type == KEYDOWN:
    			keys = pygame.key.get_pressed()
    			if keys[K_LEFT]:
    				base_scr, coord_base_scr = change_image(base2,coord_base2,base_scr,coord_base_scr)
    				coord_tourelle_scr.center = coord_base_scr.center
    				coord_base_scr = coord_base_scr.move(-10,0)
    				coord_tourelle_scr = coord_tourelle_scr.move(-10,0)
     
    			if keys[K_RIGHT]:
    				base_scr, coord_base_scr = change_image(base2,coord_base2,base_scr,coord_base_scr)
    				coord_tourelle_scr.center = coord_base_scr.center
    				coord_base_scr = coord_base_scr.move(10,0)
    				coord_tourelle_scr = coord_tourelle_scr.move(10,0)
     
    			if keys[K_UP]:
    				base_scr, coord_base_scr = change_image(base,coord_base,base_scr,coord_base_scr)
    				coord_tourelle_scr.center = coord_base_scr.center
    				coord_base_scr = coord_base_scr.move(0,-10)
    				coord_tourelle_scr = coord_tourelle_scr.move(0,-10)
     
    			if keys[K_DOWN]:
    				base_scr, coord_base_scr = change_image(base,coord_base,base_scr,coord_base_scr)
    				coord_tourelle_scr.center = coord_base_scr.center
    				coord_base_scr = coord_base_scr.move(0,10)
    				coord_tourelle_scr = coord_tourelle_scr.move(0,10)
     
    			coord_base.center = coord_base_scr.center
    			coord_tourelle.center = coord_tourelle_scr.center
     
     
    	x, y = pygame.mouse.get_pos()
     
    	dx = x - coord_tourelle_scr.center[0]
    	dy = y - coord_tourelle_scr.center[1]
     
    	rads = math.atan2(-dy,dx)
    	degs = math.degrees(rads) - 90 #decalage de 90° de l'image rapport au 0°
    	angle = degs
     
    	tourelle_scr, coord_tourelle_scr = rot_center(tourelle, coord_tourelle, angle)
     
     
    	fenetre.blit(fond, (0,0))  
    	fenetre.blit(base_scr, coord_base_scr)
    	fenetre.blit(tourelle_scr, coord_tourelle_scr)
    	pygame.display.flip()
    Images attachées Images attachées     
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  7. #7
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Bon, finalement, après avoir une nuit de repos, j'ai tenté avec des images carrés, et plus aucuns soucis. Je part donc sur cette solution.

    Ce problème est donc résolu.

    Merci beaucoup
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  8. #8
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    me suis un peu amusé: http://joel-murielle.perso.sfr.fr/tank.zip
    se déplacer avec les flèches
    clic sur l'écran pour diriger le canon
    clic sur la zone du tank pour verrouiller le canon

  9. #9
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Pas mal du tout .

    J'avoue que mon tank ne casse pas trois pattes à un canard (merci à une certaine prof pour l'expression), mais le côté graphique n'était pas ma priorité.

    Par contre, coté code, c'est assez sympa. ton déplacement du corps du char est bien plus agréable que le mien. Je vais le regarder de plus prêt afin de le comprendre.

    Je reviens vers toi après. Merci beaucoup en tout cas.
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  10. #10
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Comme promis, de retour.

    J'ai appris 2/3 chose avec ton code et t'en remercie. Juste une dernière question à laquelle je ne trouve de reponse par moi meme:

    Dans mon code j'utilise "pygame.time.Clock().tick(30)", dans ton code, tu utilises "ev = event.poll()", puis" t += c.tick()". pourquoi? Quel en est l'intérêt, avantages/inconvénients? Et pourquoi t n'est pas réinitialisé à 0 à la fin des if?

    Merci beaucoup de ton retour
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  11. #11
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    salut,

    pygame.time.Clock().tick(30) est bloquant, utile pour temporiser la boucle principale.

    ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while 1:
        t += c.tick()
        if t >= 20:
            fait des trucs
            t -= 20
    n'est pas bloquant et exécute "fait des trucs" toutes les 20ms.
    pour le t -= 20, en effet tu peux mettre t = 0, ça ne fait une différence que si une autre partie du code utilise plus de cycles que prévue.

  12. #12
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Si je comprend bien du coup, c.tick() correspond au nombre de ms écoulées depuis la dernière lecture. Je comprend mieux l'utilité du -=20 rapport au =0.

    Merci beaucoup pour ces explications.
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Manipulation des handle contexte
    Par rockbiker dans le forum DirectX
    Réponses: 1
    Dernier message: 09/05/2003, 18h51
  2. Manipuler JAVA et SSL ?
    Par jah dans le forum Sécurité
    Réponses: 6
    Dernier message: 05/05/2003, 00h30
  3. [VB6]manipuler les semaines en VB ?
    Par kamadji dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 02/05/2003, 12h33
  4. Réponses: 2
    Dernier message: 18/01/2003, 17h06
  5. Fonctions de manipulation des chaines et des dates
    Par Fares BELHAOUAS dans le forum Débuter
    Réponses: 3
    Dernier message: 09/11/2002, 22h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo