[PYTHON] Jeu de fractionnement de ballons avec pygame

introduction

Dans Dernier message, j'ai créé une liste à trois yeux au tour par tour en utilisant tkinter, donc cette fois j'ai utilisé pygame pour constamment mettre à jour l'écran. J'ai essayé de faire. Je l'ai écrit comme un jeu de fractionnement de ballons dans le titre, mais ce n'est pas si semblable à un jeu. Lol Cependant, peut-il être utilisé lors de la création de jeux à l'avenir? Je me demande si je pourrais apprendre le traitement. .. .. Je pense. Comme d'habitude, c'est un code chimérique qui possède toutes les fonctionnalités que vous souhaitez, la lisibilité est donc un problème pour l'avenir.

Ce produit fini
balloon_game.gif

À la toute fin, l'image complète de ce code est affichée.

Création d'écran d'affichage

Tout d'abord, c'est la création de l'écran de base.

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Game")

Importez quand même pygame. Initialisez le module pygame avec pygame.init (). Lors de l'écriture à l'ouverture, il peut être bon de reconnaître le niveau de sort habituel. Si vous utilisez un grand nombre de modules, vous devez initialiser les modules inutilisés. Peut-être que le jour viendra au milieu du processus?

pygame.display.set_mode est la taille, la largeur et la hauteur de l'écran. set_caption est le nom qui apparaîtra dans la barre de titre.

Processus de mise à jour de l'écran

import time

FPSCLOCK = pygame.time.Clock()
FPS = 15

class CanonGame():
    def __init__(self):

        while True:
            pygame.display.update()
            FPSCLOCK.tick(FPS)

def main():
    CanonGame()

if __name__ == '__main__':
    main()

Le rôle principal. Après avoir reflété le dessin d'écran avec pygame.display.update (), le traitement est exécuté à une vitesse qui ne dépasse pas (images) par seconde avec pygame.time.Clock.tick (images). Si vous augmentez le nombre d'images, vous pouvez mettre en œuvre un mouvement fluide, mais le traitement devient lourd. En outre, mettez essentiellement les éléments qui se mettent à jour dans la plage de while True:.

Obtenez l'événement clé

from pygame.locals import *

pygame.key.set_repeat(5, 5)

class CanonGame():
        while True:
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == KEYDOWN:
                    if event.key == K_SPACE:
                        self.bullet_shot = True
                    elif event.key == K_UP and self.cannon_radian < 89:
                        self.cannon_radian += 1
                    elif event.key == K_DOWN and self.cannon_radian > 0:
                        self.cannon_radian -= 1

En ce qui concerne les jeux, vous souhaitez toujours l'utiliser, non? Obtient le type d'opération effectuée par event.get (). Si event.type vaut QUIT (bouton x en haut à droite de l'écran), terminez tout. S'il s'agit de KEYDOWN (appui sur le clavier), alors event.key est acquis et le traitement est attribué à chaque touche enfoncée. Cette fois, tirez la balle avec la touche espace. J'ai ajusté l'orientation avec les touches haut et bas. En définissant key.set_repeat, il répondra même si vous maintenez la touche enfoncée.

Affichage de l'image, rotation


class CanonGame():
    def __init__(self):
        bullet_image = pygame.image.load("bullet.png ")
        self.cannon_image = pygame.image.load("cannon.png ")

            screen.fill((255, 255, 255))
            screen.blit(bullet_image, (self.bullet_x, self.bullet_y))

            rotate_cannon = pygame.transform.rotate(self.cannon_image, self.cannon_radian - 45)
            cannon_rect = rotate_cannon.get_rect()
            cannon_rect.center = (84, 536)
            screen.blit(rotate_cannon, cannon_rect)

Chargez l'image avec pygame.image.load («nom de l'image»). L'image est enregistrée au même emplacement où le fichier exécutable est enregistré. screen.fill (Rouge, Vert, Bleu) est la couleur d'arrière-plan. Je n'ai pas préparé d'image d'arrière-plan cette fois, donc je repeins l'arrière-plan à chaque fois et efface les images précédentes. Sans cela, les processus précédents resteront tels quels. screen.blit (image, (x, y)): Lors de l'organisation des images, vous devez faire attention à ce que le coin supérieur gauche de l'écran d'affichage soit x: 0, y: 0. Les valeurs x et y augmentent vers le bas à droite de l'écran.

Divers comportements

Concernant le comportement dans le jeu, je vais en reprendre quelques-uns et l'expliquer.

from random import randint

self.balloon_x = randint(500, 700)

randint (minimum, maximum). Cela rend la coordonnée x où le ballon apparaît aléatoire. Puisqu'il est entier, il est sélectionné au hasard parmi les entiers de la valeur définie.

import sys

sysfont = pygame.font.SysFont(None, 36)

        while True:
            score_image = sysfont.render("score : {}".format(self.score), True, (0, 0, 255))
            screen.blit(score_image, (10, 20))

Sortie de caractères. Vous pouvez modifier pygame.font.Sysfont (nom, taille, gras, italique) et 4 paramètres. format () est inclus dans {} de sysfont.render.

    def set_balloon(self):
        now_time = time.time()
        if self.is_collision:
            if now_time - self.balloon_break > 1:
                self.is_collision = False
        if self.is_collision is False:
            if self.is_balloon:
                self.balloon_y = self.balloon_y - 12
                self.balloon_alive = time.time()
                if self.balloon_alive - self.balloon_create > 4:
                    self.is_balloon = False
                else:
                    self.collision_check()
            else:
                self.balloon_image = pygame.image.load("balloon-red.png ")
                self.balloon_x = randint(500, 700)
                self.balloon_y = 600
                self.is_balloon = True
                self.balloon_create = time.time()

De plus, la fonction set_balloon que j'écris utilise ici le module time. Lorsqu'une bulle apparaît, l'heure actuelle est acquise sous forme de balloon_create, et après cela, l'heure appelée balloon_alive est acquise en continu, et lorsque la différence devient 4 secondes ou plus, la bulle réapparaît. Au fait, je mesure également now_time pour que si le ballon se brise, il apparaisse une seconde plus tard.

Si vous cochez le processus après n secondes, le mode veille apparaîtra, mais veuillez noter que l'utilisation de cette option arrêtera l'ensemble du processus.

import math

    def bullet(self):
        gravity = 9.8
        if self.bullet_shot:
            bullet_speed_x = self.bullet_speed * math.cos(math.radians(self.cannon_radian))
            bullet_speed_y = (self.bullet_speed * math.sin(math.radians(self.cannon_radian)))
            self.bullet_x = self.bullet_x + bullet_speed_x
            self.bullet_y = self.bullet_y - bullet_speed_y + gravity * self.time
            self.time += 0.2

            if self.bullet_x > 800 or self.bullet_y > 600:
                self.bullet_shot = False
                self.set_bullet()

Le comportement de la balle tirée doit être sinus cosinus à l'angle de lancement. Je me demandais s'il fallait utiliser une formule physique appropriée, mais c'est devenu un mouvement comme ça, alors Yoshi!

La balle suivante ne sera pas tirée tant que la balle ne sortira pas de l'écran.

    def collision_check(self):
        distance_y = ((self.balloon_y + 15) - (self.bullet_y + 16))**2
        distance_x = ((self.balloon_x + 20) - (self.bullet_x + 16))**2
        distance = (distance_x + distance_y)**(1/2)
        if distance < 31:
            self.pang_image = pygame.image.load("pang.png ")
            self.pang_rect = self.pang_image.get_rect()
            self.pang_rect.center = (self.balloon_x + 20, self.balloon_y + 15)
            self.is_collision = True
            self.is_balloon = False
            self.total_score(100)
            self.balloon_break = time.time()

Jugement de collision. Cette fois, la valeur absolue du centre approximatif de la sphère et du ballon est calculée. Cela fait longtemps et j'ai cherché sur Google le théorème des trois carrés. C'est facile si la hit box est un cercle! (Dans le cas d'un carré, calculez la valeur absolue de la différence entre l'axe des x et l'axe des y, et utilisez et.) Si vous entrez en collision, vous obtiendrez 100 points.

À la fin

La meilleure façon d'apprendre divers comportements est de les toucher. Si vous combinez les éléments de cette époque, j'ai l'impression que vous pouvez presque faire un jeu simple. Aussi, je veux pouvoir dessiner des illustrations ...

Le code entier

import math
import sys
import pygame
from pygame.locals import *
from random import randint
import time

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Game")
sysfont = pygame.font.SysFont(None, 36)
pygame.key.set_repeat(5, 5)
FPSCLOCK = pygame.time.Clock()
FPS = 15


class CanonGame():
    def __init__(self):
        bullet_image = pygame.image.load("bullet.png ")
        self.set_cannon()
        self.set_bullet()
        self.bullet_shot = False
        self.is_balloon = False
        self.is_collision = False
        self.score = 0

        while True:
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == KEYDOWN:
                    if event.key == K_SPACE:
                        self.bullet_shot = True
                    elif event.key == K_UP and self.cannon_radian < 89:
                        self.cannon_radian += 1
                    elif event.key == K_DOWN and self.cannon_radian > 0:
                        self.cannon_radian -= 1

            self.set_balloon()
            self.bullet()

            screen.fill((255, 255, 255))
            screen.blit(bullet_image, (self.bullet_x, self.bullet_y))
            if not self.is_collision:
                screen.blit(self.balloon_image, (self.balloon_x, self.balloon_y))
            elif self.is_collision:
                screen.blit(self.pang_image, self.pang_rect)
            rotate_cannon = pygame.transform.rotate(self.cannon_image, self.cannon_radian - 45)
            cannon_rect = rotate_cannon.get_rect()
            cannon_rect.center = (84, 536)
            screen.blit(rotate_cannon, cannon_rect)
            score_image = sysfont.render("score : {}".format(self.score), True, (0, 0, 255))
            screen.blit(score_image, (10, 20))

            pygame.display.update()
            FPSCLOCK.tick(FPS)

    def set_bullet(self):
        self.bullet_x = 68
        self.bullet_y = 520
        self.bullet_speed = 50
        self.time = 0

    def set_cannon(self):
        self.cannon_image = pygame.image.load("cannon.png ")
        self.cannon_radian = 45

    def set_balloon(self):
        now_time = time.time()
        if self.is_collision:
            if now_time - self.balloon_break > 1:
                self.is_collision = False
        if self.is_collision is False:
            if self.is_balloon:
                self.balloon_y = self.balloon_y - 12
                self.balloon_alive = time.time()
                if self.balloon_alive - self.balloon_create > 4:
                    self.is_balloon = False
                else:
                    self.collision_check()
            else:
                self.balloon_image = pygame.image.load("balloon-red.png ")
                self.balloon_x = randint(500, 700)
                self.balloon_y = 600
                self.is_balloon = True
                self.balloon_create = time.time()

    def bullet(self):
        gravity = 9.8
        if self.bullet_shot:
            bullet_speed_x = self.bullet_speed * math.cos(math.radians(self.cannon_radian))
            bullet_speed_y = (self.bullet_speed * math.sin(math.radians(self.cannon_radian)))
            self.bullet_x = self.bullet_x + bullet_speed_x
            self.bullet_y = self.bullet_y - bullet_speed_y + gravity * self.time
            self.time += 0.2

            if self.bullet_x > 800 or self.bullet_y > 600:
                self.bullet_shot = False
                self.set_bullet()

    def collision_check(self):
        distance_y = ((self.balloon_y + 15) - (self.bullet_y + 16))**2
        distance_x = ((self.balloon_x + 20) - (self.bullet_x + 16))**2
        distance = (distance_x + distance_y)**(1/2)
        if distance < 31:
            self.pang_image = pygame.image.load("pang.png ")
            self.pang_rect = self.pang_image.get_rect()
            self.pang_rect.center = (self.balloon_x + 20, self.balloon_y + 15)
            self.is_collision = True
            self.is_balloon = False
            self.total_score(100)
            self.balloon_break = time.time()

    def total_score(self, score):
        self.score = self.score + score


def main():
    CanonGame()


if __name__ == '__main__':
    main()

Recommended Posts

Jeu de fractionnement de ballons avec pygame
Créez une interface utilisateur de jeu à partir de zéro avec pygame2!
Jeu éducatif de programmation avec SenseHAT
Jeu de frappe simple avec DragonRuby
Développement de jeux Othello avec Python
Jeu de vie avec Python! (Le jeu de la vie de Conway)
Résolution de la théorie des jeux avec l'optimisation des combinaisons
Jeu Sugoroku et jeu d'addition avec Python