Dans ce tutoriel, nous allons apprendre comment utiliser la souris et le clavier en Pymunk pour interagir avec les formes et les corps. Vous pouvez créer des objets, les déplacer, les supprimer, et même tirer des balles avec la souris.
Dans ce tutoriel, nous allons apprendre comment utiliser la souris et le clavier en Pymunk pour interagir avec les formes et les corps. Vous pouvez créer des objets, les déplacer, les supprimer, et même tirer des balles avec la souris.
Avant d’attaquer l’utilisation de la souris et du clavier, notre point de départ sera :
Nous créons donc un fichier python, nommez-le comme vous le souhaitez, par exemple, "souri_clavier.py". Il contient les classes suivantes :
Exemple : Copier le code
import pymunk from pymunk.pygame_util import * from pymunk.vec2d import Vec2d import pygame from pygame.locals import * import random space = pymunk.Space() b0 = space.static_body size = w, h = 700, 300 GRAY = (220, 220, 220) RED = (255, 0, 0) class Box: def __init__(self, p0=(0, 0), p1=(w, h), d=4): x0, y0 = p0 x1, y1 = p1 ps = [(x0, y0), (x1, y0), (x1, y1), (x0, y1)] for i in range(4): segment = pymunk.Segment(b0, ps[i], ps[(i+1) % 4], d) segment.elasticity = 1 segment.friction = 1 space.add(segment)
Le programme répondra aux touches :
Exemple : Copier le code
class App: def __init__(self): pygame.init() self.screen = pygame.display.set_mode(size) self.draw_options = DrawOptions(self.screen) self.running = True def run(self): while self.running: for event in pygame.event.get(): self.do_event(event) self.draw() space.step(0.01) pygame.quit() def do_event(self, event): if event.type == QUIT: self.running = False elif event.type == KEYDOWN: if event.key in (K_q, K_ESCAPE): self.running = False if event.key == K_p: pygame.image.save(self.screen, 'souri.png') def draw(self): self.screen.fill(GRAY) space.debug_draw(self.draw_options) pygame.display.update()
On aura le code complet de notre fichier comme suit :
Exemple : Copier le code
import pymunk from pymunk.pygame_util import * from pymunk.vec2d import Vec2d import pygame from pygame.locals import * import random space = pymunk.Space() b0 = space.static_body size = w, h = 700, 300 GRAY = (220, 220, 220) RED = (255, 0, 0) class Box: def __init__(self, p0=(0, 0), p1=(w, h), d=4): x0, y0 = p0 x1, y1 = p1 ps = [(x0, y0), (x1, y0), (x1, y1), (x0, y1)] for i in range(4): segment = pymunk.Segment(b0, ps[i], ps[(i+1) % 4], d) segment.elasticity = 1 segment.friction = 1 space.add(segment) class App: def __init__(self): pygame.init() self.screen = pygame.display.set_mode(size) self.draw_options = DrawOptions(self.screen) self.running = True def run(self): while self.running: for event in pygame.event.get(): self.do_event(event) self.draw() space.step(0.01) pygame.quit() def do_event(self, event): if event.type == QUIT: self.running = False elif event.type == KEYDOWN: if event.key in (K_q, K_ESCAPE): self.running = False if event.key == K_p: pygame.image.save(self.screen, 'souri.png') def draw(self): self.screen.fill(GRAY) space.debug_draw(self.draw_options) pygame.display.update() if __name__ == '__main__': Box() App().run()
La méthode run() de votre code est la boucle principale de l'application. Elle est responsable de gérer les événements, mettre à jour la simulation et dessiner la simulation à l'écran.
Voici une analyse plus détaillée de la méthode run() :
La méthode run() de votre code est la boucle principale de l'application. Elle est responsable de gérer les événements, mettre à jour la simulation et dessiner la simulation à l'écran.
Voici une analyse plus détaillée de la méthode run() :
La méthode run() est appelée lorsque l'objet App est créé. Cela permet de démarrer la boucle principale de l'application immédiatement.
La méthode draw() de votre code est responsable du dessin de la simulation à l'écran.
Voici une analyse plus détaillée de la méthode draw() :
Voici quelques exemples d'options de dessin qui peuvent être utilisées avec la méthode debug_draw():
Vous pouvez combiner ces options pour dessiner la simulation de la manière qui vous convient le mieux.
Le code Python if __name__ == '__main__': Box() App().run() exécute les étapes suivantes :
Ce code est généralement utilisé pour créer un programme Python autonome. La classe Box pourrait être utilisée pour représenter la fenêtre principale du programme, et la classe App() pourrait être utilisée pour gérer la boucle principale du programme.
Ce qui affiche :
Maintenant que notre boîte est prête, nous pouvons y ajouter ce que l'on veut pour créer notre simulation.
Pour pouvoir créer des cercles, nous définissons la classe Circle que nous ajoutons dans le fichier "souri_clavier.py". La classe Circle est une classe simple qui définit un cercle comme un objet Pymunk.
Code Python :
Exemple : Copier le code
class Circle: def __init__(self, pos, radius=20): self.body = pymunk.Body() self.body.position = pos shape = pymunk.Circle(self.body, radius) shape.density = 0.01 shape.friction = 0.9 shape.elasticity = 1 space.add(self.body, shape)
Voici une analyse plus détaillée de la classe Circle :
Ensuite, nous ajoutons 8 balles à des endroits aléatoires.
Code Python :
Exemple : Copier le code
if __name__ == '__main__': Box() r = 20 for i in range(8): x = random.randint(r, w-r) y = random.randint(r, h-r) Circle((x, y), r) App().run()
La ligne "if __name__ == '__main__':" vérifie si le fichier est exécuté directement. Si c'est le cas, alors le code à l'intérieur de l'instruction "if" est exécuté.
La ligne "Box()" crée un nouvel objet Box. Cet objet représente la boîte dans laquelle la simulation va se dérouler.
La boucle "for" crée huit objets Circle de rayons 20 à des positions (x, y) aléatoires. Chaque objet Circle est créé à une position aléatoire dans la simulation.
La ligne "App().run()" démarre la boucle principale de l'application. La boucle principale est responsable de gérer les événements, mettre à jour la simulation et dessiner la simulation à l'écran.
Lorsque vous exécuterez ce code, vous verrez une fenêtre avec une boîte et huit cercles aléatoires.
Vous pouvez modifier le code pour ajouter plus de cercles à la simulation, ou pour modifier le comportement des cercles.
Voici quelques exemples de modifications que vous pouvez apporter au code :
Vous pouvez également utiliser les événements de Pygame pour contrôler la simulation. Par exemple, vous pouvez utiliser l'événement "KEYDOWN" pour arrêter la simulation lorsque l'utilisateur appuie sur une touche spécifique.
Utilisons maintenant un événement "MOUSEBUTTONDOWN" pour sélectionner une forme active par un clic de souris. Les deux fonctions "from_pygame" et "to_pygame" nous permettent de passer d'une coordonnée pygame à une autre.
Donc, nous allons modifier le code de la classe "App()" pour gérer l'événement de clic de souris comme suit :
Code Python :
Exemple : Copier le code
class App: def __init__(self): pygame.init() self.screen = pygame.display.set_mode(size) self.draw_options = DrawOptions(self.screen) self.active_shape = None self.selected_shapes = [] self.running = True def run(self): while self.running: for event in pygame.event.get(): self.do_event(event) self.draw() space.step(0.01) pygame.quit() def do_event(self, event): if event.type == QUIT: self.running = False elif event.type == KEYDOWN: if event.key in (K_q, K_ESCAPE): self.running = False if event.key == K_p: pygame.image.save(self.screen, 'boite_et_cercle.png') elif event.type == MOUSEBUTTONDOWN: p = from_pygame(event.pos, self.screen) self.active_shape = None for s in space.shapes: dist = s.point_query(p) if dist.distance < 0: self active_shape = s
Voici une analyse du code modifié :
On doit aussi modifier le code de la fonction "draw()" qui dessine la simulation Pymunk sur l'écran et met en évidence la forme active actuelle comme suit :
Code Python :
Exemple : Copier le code
def draw(self): self.screen.fill(GRAY) space.debug_draw(self.draw_options) if self.active_shape != None: s = self.active_shape r = int(s.radius) p = to_pygame(s.body.position, self.screen) pygame.draw.circle(self.screen, RED, p, r, 3) pygame.display.update()
Voici une analyse de la fonction :
La fonction "to_pygame()" convertit les coordonnées Pymunk en coordonnées Pygame. Cela est nécessaire car Pymunk utilise un système de coordonnées différent de Pygame.
Maintenant qu’une balle est sélectionnée. Nous allons utiliser les touches fléchées du clavier pour la déplacer. Pour cela, nous définissons un dictionnaire dans lequel nous associons les 4 vecteurs unitaires de direction aux 4 touches fléchées. Si la touche pressée est une touche fléchée, nous déplaçons la forme active de 30 pixels dans cette direction :
Voici le code à ajouter après :
Code Python :
Exemple : Copier le code
elif event.key == K_p: pygame.image.save(self screen, 'mouse.png') et avant : elif event.type == MOUSEBUTTONDOWN:
Code Python :
Exemple : Copier le code
keys = {K_LEFT: (-1, 0), K_RIGHT: (1, 0), K_UP: (0, 1), K_DOWN: (0, -1)} if event.key in keys: v = Vec2d(keys[event.key][0] * 30, keys[event.key][1] * 30) if self.active_shape != None: self.active_shape.body.position += v
Nous allons ajouter un code qui lorsque l’on clique sur une balle et on déplace la souris tout en gardant le bouton de la souris enfoncé, ce qui trace une ligne rouge entre la position de la souris et la position de la balle. En relâchant le bouton de la souris, nous relevons la position de la souris et appliquons à la balle une impulsion proportionnelle à la ligne rouge tracée avec la souris, p0 étant la position de l'objet et p1 la position de la souris :
Voici le code Python pour gérer cet événement (MOUSEBUTTONUP) et ajouter MOUSEMOTION :
Code Python :
Exemple : Copier le code
elif event.type == MOUSEMOTION: self.p = event.pos elif event.type == MOUSEBUTTONUP: if self.pulling: self.pulling = False b = self.active_shape.body p0 = Vec2d(b.position.x, b.position.y) p1 = from_pygame(event.pos, self.screen) impulse = 100 * Vec2d(p0[0] - p1[0], p0[1] - p1[1]).rotated(-b.angle) b.apply_impulse_at_local_point(impulse)
et le code pour dessiner la ligne rouge :
Code Python :
Exemple : Copier le code
def draw(self): self.screen.fill(GRAY) space.debug_draw(self.draw_options) if self.active_shape != None: s = self.active_shape r = int(s.radius) p = to_pygame(s.body.position, self screen) pygame.draw.circle(self screen, RED, p, r, 3) if self.pulling: pygame.draw.line(self screen, RED, p, self.p, 3) pygame.draw.circle(self screen, RED, self.p, r, 3)
Modifier aussi le code MOUSEBUTTONDOWN comme suit :
Code Python :
Exemple : Copier le code
elif event.type == MOUSEBUTTONDOWN: p = from_pygame(event.pos, self screen) self.active_shape = None for s in space.shapes: query_info = s.point_query(p) shape = query_info.shape dist = query_info.distance if dist < 0: self.active_shape = s self.pulling = True
Ce qui donne le résultat suivant :
Nous proposons d’utiliser les touches du clavier pour ajouter un nouveau objet (balle) à la position de la souris ou supprimer un objet existant.
Pour ajouter un objet en utilisant la touche « n », Dans la section "do_event()", nous ajoutons le code suivant, dans la section "do_event()":
Code Python :
Exemple : Copier le code
elif event.key == K_n: p = from_pygame(pygame.mouse.get_pos(), self.screen) Circle(p, radius=20)
Placer la souris là où vous voulez ajouter une nouvelle balle et taper "n".
Pour supprimer un objet (balle) sélectionner l’objet en question et taper la touche "backspace".
Voici le code de la suppression à ajouter dans la section "do_event()":
Code Python :
Exemple : Copier le code
elif event.key == K_BACKSPACE: s = self.active_shape if s != None: space.remove(s, s.body) self.active_shape = None
Voilà, maintenant avec ce tutoriel, vous pouvez utiliser la souris et les touches du clavier pour créer des applications fascinantes.
Télécharger ici le code complet de l’exempleLivre numérique court pour comprendre la méthode secrète permettant d'obtenir des likes sans fin sur Facebook.
GAGNER DE L'ARGENT