Table des matières
Vue d'ensemble
Détection de collision
Conclusion
Maison développement back-end Tutoriel Python Créer des jeux interactifs avec Python 3 et Pygame : Partie 4

Créer des jeux interactifs avec Python 3 et Pygame : Partie 4

Aug 27, 2023 pm 03:01 PM

使用 Python 3 和 Pygame 创建互动游戏:第 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'
Copier après la connexion

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])
Copier après la connexion

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()
Copier après la connexion

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])
Copier après la connexion

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])
Copier après la connexion

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)
Copier après la connexion

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'
Copier après la connexion

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]
Copier après la connexion

Créer un menu

create_menu() 函数创建一个带有两个按钮的菜单,其中包含文本“PLAY”和“QUIT”。它有两个嵌套函数,名为 on_play()on_quit() ,它提供给相应的按钮。每个按钮都添加到 objects 列表(待绘制)以及 menu_buttonschamps.

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)
Copier après la connexion

Lorsque vous cliquez sur le bouton PLAY, on_play() est appelé, qui est défini de objects 列表中删除按钮,这样就不再绘制它们了。此外,触发游戏开始的布尔字段 is_game_runningstart_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
Copier après la connexion
Afficher et masquer le menu du jeu

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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

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

Comment résoudre le problème des autorisations rencontré lors de la visualisation de la version Python dans le terminal Linux? Comment résoudre le problème des autorisations rencontré lors de la visualisation de la version Python dans le terminal Linux? Apr 01, 2025 pm 05:09 PM

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 ...

Comment copier efficacement la colonne entière d'une dataframe dans une autre dataframe avec différentes structures dans Python? Comment copier efficacement la colonne entière d'une dataframe dans une autre dataframe avec différentes structures dans Python? Apr 01, 2025 pm 11:15 PM

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 ...

Quelles sont les bibliothèques Python populaires et leurs utilisations? Quelles sont les bibliothèques Python populaires et leurs utilisations? Mar 21, 2025 pm 06:46 PM

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 sans servir_forever ()? Comment Uvicorn écoute-t-il en permanence les demandes HTTP sans servir_forever ()? Apr 01, 2025 pm 10:51 PM

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 ...

Comment créer dynamiquement un objet via une chaîne et appeler ses méthodes dans Python? Comment créer dynamiquement un objet via une chaîne et appeler ses méthodes dans Python? Apr 01, 2025 pm 11:18 PM

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 ...

Que sont les expressions régulières? Que sont les expressions régulières? Mar 20, 2025 pm 06:25 PM

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 le projet et les méthodes axées sur les problèmes dans les 10 heures? Comment enseigner les bases de la programmation novice en informatique dans le projet et les méthodes axées sur les problèmes dans les 10 heures? Apr 02, 2025 am 07:18 AM

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 ...

See all articles