


Créer des jeux interactifs avec Python 3 et Pygame : Partie 4
Vue d'ensemble
Il s'agit du quatrième d'une série de didacticiels en cinq parties sur la création de jeux avec Python 3 et Pygame. Dans la troisième partie, nous avons plongé dans le cœur de Breakout, appris à gérer les événements, examiné les principales classes de Breakout et vu comment déplacer différents objets du jeu.
Dans cette partie, nous apprendrons comment détecter les collisions et ce qui se passe lorsque la balle touche divers objets tels que des raquettes, des briques, des murs, des plafonds et des sols. Enfin, nous passerons en revue des sujets importants concernant l'interface utilisateur du jeu, en particulier comment créer des menus avec nos propres boutons personnalisés.
Détection de collision
Dans le jeu, les choses entrent en collision. La percée ne fait pas exception. La plupart du temps, c'est la balle qui frappe quelque chose. handle_ball_collisions()
方法有一个嵌套函数,名为 intersect()
, utilisé pour tester si la balle touche un objet et où elle touche l'objet. Si la balle manque un objet, renvoie "Gauche", "Droite", "Haut", "Bas" ou "Aucun".
def handle_ball_collisions(self): def intersect(obj, ball): edges = dict( left=Rect(obj.left, obj.top, 1, obj.height), right=Rect(obj.right, obj.top, 1, obj.height), top=Rect(obj.left, obj.top, obj.width, 1), bottom=Rect(obj.left, obj.bottom, obj.width, 1)) collisions = set(edge for edge, rect in edges.items() if ball.bounds.colliderect(rect)) if not collisions: return None if len(collisions) == 1: return list(collisions)[0] if 'top' in collisions: if ball.centery >= obj.top: return 'top' if ball.centerx < obj.left: return 'left' else: return 'right' if 'bottom' in collisions: if ball.centery >= obj.bottom: return 'bottom' if ball.centerx < obj.left: return 'left' else: return 'right'
Frappez la balle avec la raquette
Lorsque la balle touche la raquette, elle rebondit. S'il touche le haut de la pagaie, il rebondira mais conservera la même composante de vitesse horizontale.
Cependant, si elle heurte un côté de la pagaie, elle rebondira de l'autre côté (gauche ou droite) et poursuivra son mouvement vers le bas jusqu'à ce qu'elle touche le sol. Ce code utilise la fonction d'intersection ().
# Hit paddle s = self.ball.speed edge = intersect(self.paddle, self.ball) if edge is not None: self.sound_effects['paddle_hit'].play() if edge == 'top': speed_x = s[0] speed_y = -s[1] if self.paddle.moving_left: speed_x -= 1 elif self.paddle.moving_left: speed_x += 1 self.ball.speed = speed_x, speed_y elif edge in ('left', 'right'): self.ball.speed = (-s[0], s[1])
Atterrissage
Lorsque la raquette manque la balle en descendant (ou que la balle touche le côté de la raquette), la balle continuera de tomber et finira par toucher le sol. À ce stade, le joueur perd une vie et la balle est recréée pour que le jeu puisse continuer. Le jeu se termine lorsque le joueur n'a plus de vie.
# Hit floor if self.ball.top > c.screen_height: self.lives -= 1 if self.lives == 0: self.game_over = True else: self.create_ball()
Cosses aux plafonds et aux murs
Lorsque la balle touche un mur ou un plafond, elle rebondit simplement.
# Hit ceiling if self.ball.top < 0: self.ball.speed = (s[0], -s[1]) # Hit wall if self.ball.left < 0 or self.ball.right > c.screen_width: self.ball.speed = (-s[0], s[1])
Brique Break
Quand la balle touche une brique, c'est un événement majeur dans Breakout - la brique disparaît, le joueur marque un point, la balle rebondit et quelques autres choses se produisent (effets sonores et éventuellement effets spéciaux), j'en discuterai ça plus tard.
Pour déterminer si une brique a été touchée, le code vérifie si des briques croisent la balle :
# Hit brick for brick in self.bricks: edge = intersect(brick, self.ball) if not edge: continue self.bricks.remove(brick) self.objects.remove(brick) self.score += self.points_per_brick if edge in ('top', 'bottom'): self.ball.speed = (s[0], -s[1]) else: self.ball.speed = (-s[0], s[1])
Programmer le menu du jeu
La plupart des jeux ont une sorte d'interface utilisateur. Breakout a un menu simple avec deux boutons, "PLAY" et "QUITTER". Ce menu apparaît au démarrage du jeu et disparaît lorsque le joueur clique sur "Démarrer". Voyons comment les boutons et les menus sont implémentés et comment ils s'intègrent au jeu.
Créer un bouton
Pygame n'a pas de bibliothèque d'interface utilisateur intégrée. Il existe des extensions tierces, mais j'ai décidé de créer mon propre bouton pour le menu. Les boutons sont des objets de jeu avec trois états : normal, survolé et enfoncé. L'état normal est lorsque la souris n'est pas sur le bouton, et l'état de survol est lorsque la souris est sur le bouton mais que le bouton gauche de la souris n'est pas enfoncé. L'état enfoncé est lorsque la souris est sur le bouton et que le joueur appuie sur le bouton gauche de la souris.
Le bouton est implémenté sous la forme d'un rectangle avec une couleur d'arrière-plan et du texte affiché dessus. Le bouton reçoit également une fonction on_click (par défaut une fonction noop lambda), qui est appelée lorsque l'on clique sur le bouton.
import pygame from game_object import GameObject from text_object import TextObject import config as c class Button(GameObject): def __init__(self, x, y, w, h, text, on_click=lambda x: None, padding=0): super().__init__(x, y, w, h) self.state = 'normal' self.on_click = on_click self.text = TextObject(x + padding, y + padding, lambda: text, c.button_text_color, c.font_name, c.font_size) def draw(self, surface): pygame.draw.rect(surface, self.back_color, self.bounds) self.text.draw(surface)
Les boutons gèrent leurs propres événements de souris et modifient leur état interne en fonction de ces événements. Lorsque le bouton est enfoncé, la fonction MOUSEBUTTONUP
事件,表示玩家点击了按钮,并调用 on_click()
est reçue.
def handle_mouse_event(self, type, pos): if type == pygame.MOUSEMOTION: self.handle_mouse_move(pos) elif type == pygame.MOUSEBUTTONDOWN: self.handle_mouse_down(pos) elif type == pygame.MOUSEBUTTONUP: self.handle_mouse_up(pos) def handle_mouse_move(self, pos): if self.bounds.collidepoint(pos): if self.state != 'pressed': self.state = 'hover' else: self.state = 'normal' def handle_mouse_down(self, pos): if self.bounds.collidepoint(pos): self.state = 'pressed' def handle_mouse_up(self, pos): if self.state == 'pressed': self.on_click(self) self.state = 'hover'
La propriété back_color
utilisée pour dessiner le rectangle d'arrière-plan renvoie toujours une couleur qui correspond à l'état actuel du bouton, afin que le joueur puisse clairement voir que le bouton est actif :
@property def back_color(self): return dict(normal=c.button_normal_back_color, hover=c.button_hover_back_color, pressed=c.button_pressed_back_color)[self.state]
Créer un menu
create_menu()
函数创建一个带有两个按钮的菜单,其中包含文本“PLAY”和“QUIT”。它有两个嵌套函数,名为 on_play()
和 on_quit()
,它提供给相应的按钮。每个按钮都添加到 objects
列表(待绘制)以及 menu_buttons
champs.
def create_menu(self): for i, (text, handler) in enumerate((('PLAY', on_play), ('QUIT', on_quit))): b = Button(c.menu_offset_x, c.menu_offset_y + (c.menu_button_h + 5) * i, c.menu_button_w, c.menu_button_h, text, handler, padding=5) self.objects.append(b) self.menu_buttons.append(b) self.mouse_handlers.append(b.handle_mouse_event)
Lorsque vous cliquez sur le bouton PLAY, on_play() est appelé, qui est défini de objects
列表中删除按钮,这样就不再绘制它们了。此外,触发游戏开始的布尔字段 is_game_running
和 start_level
à True.
Défini sur True lorsque vous cliquez sur le bouton de sortie, déclenchant la séquence de jeu finale. is_game_running
设置为 False
(有效暂停游戏)并且 game_over
def on_play(button): for b in self.menu_buttons: self.objects.remove(b) self.is_game_running = True self.start_level = True def on_quit(button): self.game_over = True self.is_game_running = False
Afficher et masquer les menus est implicite. Lorsque les boutons sont dans la liste
, le menu est visible ; lorsqu'ils sont supprimés, il est masqué. C'est aussi simple que cela. objects
Il est possible de créer un menu imbriqué avec sa propre surface qui restitue des sous-composants comme des boutons, puis d'ajouter/supprimer simplement ce composant de menu, mais ce menu simple n'en a pas besoin.
Conclusion
Dans cette section, nous abordons la détection de collision et ce qui se passe lorsque la balle touche divers objets tels que des raquettes, des briques, des murs, des plafonds et des sols. De plus, nous avons créé notre propre menu avec des boutons personnalisés qui se cachent et s'affichent en fonction des commandes.
Dans cette dernière partie de la série, nous examinerons le jeu final, en accordant une attention particulière aux scores et aux vies, aux effets sonores et à la musique.
Ensuite, nous développerons un système d'effets spéciaux complexe pour ajouter de l'intérêt au jeu. Enfin, nous discutons des orientations futures et des améliorations potentielles.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Solution aux problèmes d'autorisation Lors de la visualisation de la version Python dans Linux Terminal Lorsque vous essayez d'afficher la version Python dans Linux Terminal, entrez Python ...

Lorsque vous utilisez la bibliothèque Pandas de Python, comment copier des colonnes entières entre deux frames de données avec différentes structures est un problème courant. Supposons que nous ayons deux dats ...

L'article traite des bibliothèques Python populaires comme Numpy, Pandas, Matplotlib, Scikit-Learn, Tensorflow, Django, Flask et Demandes, détaillant leurs utilisations dans le calcul scientifique, l'analyse des données, la visualisation, l'apprentissage automatique, le développement Web et H et H

Comment Uvicorn écoute-t-il en permanence les demandes HTTP? Uvicorn est un serveur Web léger basé sur ASGI. L'une de ses fonctions principales est d'écouter les demandes HTTP et de procéder ...

Dans Python, comment créer dynamiquement un objet via une chaîne et appeler ses méthodes? Il s'agit d'une exigence de programmation courante, surtout si elle doit être configurée ou exécutée ...

Fastapi ...

Les expressions régulières sont des outils puissants pour la correspondance des motifs et la manipulation du texte dans la programmation, améliorant l'efficacité du traitement de texte sur diverses applications.

Comment enseigner les bases de la programmation novice en informatique dans les 10 heures? Si vous n'avez que 10 heures pour enseigner à l'informatique novice des connaissances en programmation, que choisissez-vous d'enseigner ...
