@ryuyamazoe

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

pygameで作るインベーダーゲーム ポーズ画面作成の仕方

初めまして、Python初心者です。
今回、pythonのpygameライブラリを用いて、インベーダーゲームを作成しています。
ネットに落ちていたコードを元にある程度のところまでは作れたのですが、ポーズ画面がうまく動作しません。

画面は全部で4画面あります。
1:タイトル
2:プレイ
3:ポーズ
4:ゲームオーバー

2のプレイ画面起動中に、キーボード”P”を押すとポーズ画面が起動されるようにしているのですが、ポーズ画面終了後に敵の動きだけ止まりませんでした。
その他の、球などは止まっています。

そこでコードを読んだところ、
敵クラスを最初に呼び出した時間と現在時刻の差の分だけ敵が動くように記載されていました。
なので、対策としてポーズ画面起動中は、その差が変わらないよう
敵クラスを最初に呼び出した時間にポーズ中の時間も足されるようにコーディングした所敵の動きも止まるようになりました。

しかし、ポーズ画面を解除し、プレイ画面に戻っても敵の動きが動かなくなりました。
その間も敵の弾は動いています。
不規則な時間経過後また動き出すのですが、このラグを無くしたいです。どのようにすればよろしいでしょうか?

稚拙な質問内容、質問の仕方で恐縮なのですが、ご有識者の方よろしくお願いします。

出ているエラーメッセージを入力
エラーメッセージ自体は出ていません。

スクリーンショット 2024-01-06 11.39.17.png

スクリーンショット 2024-01-06 11.40.43.png

該当するソースコード
Python pygame
ソースコードを入力
【敵のグループクラス】
class EnemiesGroup(sprite.Group):
def init(self, columns, rows):
super().init()
sprite.Group.init(self)
self.enemies = [[None] * columns for _ in range(rows)]
self.columns = columns
self.rows = rows
self.leftAddMove = 0
self.rightAddMove = 0
self.moveTime = 600
self.direction = 1
self.rightMoves = 30
self.leftMoves = 30
self.moveNumber = 0
self.timer = time.get_ticks()
self.bottom = game.enemyPosition + ((rows - 1) * 45) + 35
self._aliveColumns = list(range(columns))
self._leftAliveColumn = 0
self._rightAliveColumn = columns - 1

def update(self, current_time , paused):
    if not paused:
        # saved_timer = self.timer
        if current_time - self.timer > self.moveTime:
            if self.direction == 1:
                max_move = self.rightMoves + self.rightAddMove
            else:
                max_move = self.leftMoves + self.leftAddMove

            if self.moveNumber >= max_move:
                self.leftMoves = 30 + self.rightAddMove
                self.rightMoves = 30 + self.leftAddMove
                self.direction *= -1
                self.moveNumber = 0
                self.bottom = 0
                for enemy in self:
                    enemy.rect.y += ENEMY_MOVE_DOWN
                    enemy.toggle_image()
                    if self.bottom < enemy.rect.y + 35:
                        self.bottom = enemy.rect.y + 35
            else:
                velocity = 10 if self.direction == 1 else -10
                for enemy in self:
                    enemy.rect.x += velocity
                    enemy.toggle_image()
                self.moveNumber += 1

            self.timer += self.moveTime
    else:
        self.timer = self.timer + current_time

【メインクラス内に記載の関数】
def check_input(self):
self.keys = key.get_pressed()
for e in event.get():
if self.should_exit(e):
sys.exit()
if e.type == KEYDOWN:
if e.key == K_SPACE:
if len(self.bullets) == 0 and self.shipAlive:
if self.score < 1000:
bullet = Bullet(self.player.rect.x + 23,
self.player.rect.y + 5, -1,
15, 'laser', 'center')
self.bullets.add(bullet)
self.allSprites.add(self.bullets)
self.sounds['shoot'].play()
else:
leftbullet = Bullet(self.player.rect.x + 8,
self.player.rect.y + 5, -1,
15, 'laser', 'left')
rightbullet = Bullet(self.player.rect.x + 38,
self.player.rect.y + 5, -1,
15, 'laser', 'right')
self.bullets.add(leftbullet)
self.bullets.add(rightbullet)
self.allSprites.add(self.bullets)
self.sounds['shoot2'].play()
elif e.key == K_p:
self.paused = not self.paused
self.startGame = not self.startGame

def draw_pause_screen(self):
    # self.screen.fill((0, 0, 0)) 
    # self.screen.blit(self.background, (0, 0))

    pause_text = Text(FONT, 50, 'Paused', WHITE, 300, 250)
    resume_text = Text(FONT, 30, 'Press R to Resume', WHITE, 290, 320)
    quit_text = Text(FONT, 30, 'Press Q to Quit', WHITE, 310, 370)

    pause_text.draw(self.screen)
    resume_text.draw(self.screen)
    quit_text.draw(self.screen)

    self.keys = key.get_pressed()                               # 現在のキーボードの状態を取得
    for e in event.get():                                       # イベントを処理
        if self.should_exit(e):                                 # ウィンドウを閉じるイベントがあればプログラムを終了
            sys.exit()
        if e.type == KEYDOWN:                                   # キーの押下によるイベント処理
            if e.key == K_p:                                    # Pキーが押された場合
                self.paused = not self.paused
                self.startGame = not self.startGame

【メインクラス内のメインループないコード】
def main(self):
while True:
if self.mainScreen:
self.screen.blit(self.background, (0, 0))
self.titleText.draw(self.screen)
self.titleText2.draw(self.screen)
self.enemy1Text.draw(self.screen)
self.enemy2Text.draw(self.screen)
self.enemy3Text.draw(self.screen)
self.enemy4Text.draw(self.screen)
self.create_main_menu()
for e in event.get():
if self.should_exit(e):
sys.exit()
if e.type == KEYUP:
# Only create blockers on a new game, not a new round
self.allBlockers = sprite.Group(self.make_blockers(0),
self.make_blockers(1),
self.make_blockers(2),
self.make_blockers(3))
self.livesGroup.add(self.life1, self.life2, self.life3)
self.reset(0)
self.startGame = True
self.mainScreen = False

        elif self.startGame:
            if self.paused:
                self.draw_pause_screen()
            else:
                if not self.enemies and not self.explosionsGroup:
                    currentTime = time.get_ticks()
                    if currentTime - self.gameTimer < 3000:
                        self.screen.blit(self.background, (0, 0))
                        self.scoreText2 = Text(FONT, 20, str(self.score),
                                            GREEN, 85, 5)
                        self.scoreText.draw(self.screen)
                        self.scoreText2.draw(self.screen)
                        self.nextRoundText.draw(self.screen)
                        self.livesText.draw(self.screen)
                        self.livesGroup.update()
                        self.check_input()
                    if currentTime - self.gameTimer > 3000:
                        # Move enemies closer to bottom
                        self.enemyPosition += ENEMY_MOVE_DOWN
                        self.reset(self.score)
                        self.gameTimer += 3000
                else:
                    currentTime = time.get_ticks()
                    self.play_main_music(currentTime)
                    self.screen.blit(self.background, (0, 0))
                    self.allBlockers.update(self.screen)
                    self.scoreText2 = Text(FONT, 20, str(self.score), GREEN,
                                        85, 5)
                    self.scoreText.draw(self.screen)
                    self.scoreText2.draw(self.screen)
                    self.livesText.draw(self.screen)
                    self.check_input()
                    # self.check_input2()
                    self.enemies.update(currentTime , self.paused)
                    self.allSprites.update(self.keys, currentTime)
                    self.explosionsGroup.update(currentTime)
                    self.check_collisions()
                    self.create_new_ship(self.makeNewShip, currentTime)
                    self.make_enemies_shoot()
            
        elif self.gameOver:
            currentTime = time.get_ticks()
            # Reset enemy starting position
            self.enemyPosition = ENEMY_DEFAULT_POSITION
            self.create_game_over(currentTime)

        else:
            self.draw_pause_screen()
0 likes

1Answer

すみません。コードを読まずに回答しますが、

ポーズ中を示すグローバル変数を持っておいて、各イベント処理では、ポーズ中ならば何もせずにすぐにリーターンするような処理にしてはどうでしょうか。
(自分ならこう書くと思います)

この説明がよく分からないということであれば、
下記のコードブロックの書き方を理解して、最初の質問のソースコードを正しくコードブロックに入れるように修正してください。
そうしてもらえたら、コードを読んでお答えします。

コードの挿入 - Code blocks - コードブロック

0Like

Comments

  1. オリジナルのコードに少しだけ手を加えました。

    #!/usr/bin/env python
    
    # Space Invaders
    # Created by Lee Robinson
    
    from pygame import *
    import sys
    from os.path import abspath, dirname
    from random import choice
    
    BASE_PATH = abspath(dirname(__file__))
    FONT_PATH = BASE_PATH + '/fonts/'
    IMAGE_PATH = BASE_PATH + '/images/'
    SOUND_PATH = BASE_PATH + '/sounds/'
    
    # Colors (R, G, B)
    WHITE = (255, 255, 255)
    GREEN = (78, 255, 87)
    YELLOW = (241, 255, 0)
    BLUE = (80, 255, 239)
    PURPLE = (203, 0, 255)
    RED = (237, 28, 36)
    
    SCREEN = display.set_mode((800, 600))
    FONT = FONT_PATH + 'space_invaders.ttf'
    IMG_NAMES = ['ship', 'mystery',
                 'enemy1_1', 'enemy1_2',
                 'enemy2_1', 'enemy2_2',
                 'enemy3_1', 'enemy3_2',
                 'explosionblue', 'explosiongreen', 'explosionpurple',
                 'laser', 'enemylaser']
    IMAGES = {name: image.load(IMAGE_PATH + '{}.png'.format(name)).convert_alpha()
              for name in IMG_NAMES}
    
    BLOCKERS_POSITION = 450
    ENEMY_DEFAULT_POSITION = 65  # Initial value for a new game
    ENEMY_MOVE_DOWN = 35
    
    
    class Ship(sprite.Sprite):
        def __init__(self):
            sprite.Sprite.__init__(self)
            self.image = IMAGES['ship']
            self.rect = self.image.get_rect(topleft=(375, 540))
            self.speed = 5
    
        def update(self, keys, *args):
            if keys[K_LEFT] and self.rect.x > 10:
                self.rect.x -= self.speed
            if keys[K_RIGHT] and self.rect.x < 740:
                self.rect.x += self.speed
            game.screen.blit(self.image, self.rect)
    
    
    class Bullet(sprite.Sprite):
        def __init__(self, xpos, ypos, direction, speed, filename, side):
            sprite.Sprite.__init__(self)
            self.image = IMAGES[filename]
            self.rect = self.image.get_rect(topleft=(xpos, ypos))
            self.speed = speed
            self.direction = direction
            self.side = side
            self.filename = filename
    
        def update(self, keys, *args):
            game.screen.blit(self.image, self.rect)
            self.rect.y += self.speed * self.direction
            if self.rect.y < 15 or self.rect.y > 600:
                self.kill()
    
    
    class Enemy(sprite.Sprite):
        def __init__(self, row, column):
            sprite.Sprite.__init__(self)
            self.row = row
            self.column = column
            self.images = []
            self.load_images()
            self.index = 0
            self.image = self.images[self.index]
            self.rect = self.image.get_rect()
    
        def toggle_image(self):
            self.index += 1
            if self.index >= len(self.images):
                self.index = 0
            self.image = self.images[self.index]
    
        def update(self, *args):
            game.screen.blit(self.image, self.rect)
    
        def load_images(self):
            images = {0: ['1_2', '1_1'],
                      1: ['2_2', '2_1'],
                      2: ['2_2', '2_1'],
                      3: ['3_1', '3_2'],
                      4: ['3_1', '3_2'],
                      }
            img1, img2 = (IMAGES['enemy{}'.format(img_num)] for img_num in images[self.row])
            self.images.append(transform.scale(img1, (40, 35)))
            self.images.append(transform.scale(img2, (40, 35)))
    
    
    class EnemiesGroup(sprite.Group):
        def __init__(self, columns, rows):
            sprite.Group.__init__(self)
            self.enemies = [[None] * columns for _ in range(rows)]
            self.columns = columns
            self.rows = rows
            self.leftAddMove = 0
            self.rightAddMove = 0
            self.moveTime = 600
            self.direction = 1
            self.rightMoves = 30
            self.leftMoves = 30
            self.moveNumber = 15
            self.timer = time.get_ticks()
            self.bottom = game.enemyPosition + ((rows - 1) * 45) + 35
            self._aliveColumns = list(range(columns))
            self._leftAliveColumn = 0
            self._rightAliveColumn = columns - 1
    
        def update(self, current_time):
            if current_time - self.timer > self.moveTime:
                if self.direction == 1:
                    max_move = self.rightMoves + self.rightAddMove
                else:
                    max_move = self.leftMoves + self.leftAddMove
    
                if self.moveNumber >= max_move:
                    self.leftMoves = 30 + self.rightAddMove
                    self.rightMoves = 30 + self.leftAddMove
                    self.direction *= -1
                    self.moveNumber = 0
                    self.bottom = 0
                    for enemy in self:
                        enemy.rect.y += ENEMY_MOVE_DOWN
                        enemy.toggle_image()
                        if self.bottom < enemy.rect.y + 35:
                            self.bottom = enemy.rect.y + 35
                else:
                    velocity = 10 if self.direction == 1 else -10
                    for enemy in self:
                        enemy.rect.x += velocity
                        enemy.toggle_image()
                    self.moveNumber += 1
    
                self.timer += self.moveTime
    
        def add_internal(self, *sprites):
            super(EnemiesGroup, self).add_internal(*sprites)
            for s in sprites:
                self.enemies[s.row][s.column] = s
    
        def remove_internal(self, *sprites):
            super(EnemiesGroup, self).remove_internal(*sprites)
            for s in sprites:
                self.kill(s)
            self.update_speed()
    
        def is_column_dead(self, column):
            return not any(self.enemies[row][column]
                           for row in range(self.rows))
    
        def random_bottom(self):
            col = choice(self._aliveColumns)
            col_enemies = (self.enemies[row - 1][col]
                           for row in range(self.rows, 0, -1))
            return next((en for en in col_enemies if en is not None), None)
    
        def update_speed(self):
            if len(self) == 1:
                self.moveTime = 200
            elif len(self) <= 10:
                self.moveTime = 400
    
        def kill(self, enemy):
            self.enemies[enemy.row][enemy.column] = None
            is_column_dead = self.is_column_dead(enemy.column)
            if is_column_dead:
                self._aliveColumns.remove(enemy.column)
    
            if enemy.column == self._rightAliveColumn:
                while self._rightAliveColumn > 0 and is_column_dead:
                    self._rightAliveColumn -= 1
                    self.rightAddMove += 5
                    is_column_dead = self.is_column_dead(self._rightAliveColumn)
    
            elif enemy.column == self._leftAliveColumn:
                while self._leftAliveColumn < self.columns and is_column_dead:
                    self._leftAliveColumn += 1
                    self.leftAddMove += 5
                    is_column_dead = self.is_column_dead(self._leftAliveColumn)
    
    
    class Blocker(sprite.Sprite):
        def __init__(self, size, color, row, column):
            sprite.Sprite.__init__(self)
            self.height = size
            self.width = size
            self.color = color
            self.image = Surface((self.width, self.height))
            self.image.fill(self.color)
            self.rect = self.image.get_rect()
            self.row = row
            self.column = column
    
        def update(self, keys, *args):
            game.screen.blit(self.image, self.rect)
    
    
    class Mystery(sprite.Sprite):
        def __init__(self):
            sprite.Sprite.__init__(self)
            self.image = IMAGES['mystery']
            self.image = transform.scale(self.image, (75, 35))
            self.rect = self.image.get_rect(topleft=(-80, 45))
            self.row = 5
            self.moveTime = 25000
            self.direction = 1
            self.timer = time.get_ticks()
            self.mysteryEntered = mixer.Sound(SOUND_PATH + 'mysteryentered.wav')
            self.mysteryEntered.set_volume(0.3)
            self.playSound = True
    
        def update(self, keys, currentTime, *args):
            resetTimer = False
            passed = currentTime - self.timer
            if passed > self.moveTime:
                if (self.rect.x < 0 or self.rect.x > 800) and self.playSound:
                    self.mysteryEntered.play()
                    self.playSound = False
                if self.rect.x < 840 and self.direction == 1:
                    self.mysteryEntered.fadeout(4000)
                    self.rect.x += 2
                    game.screen.blit(self.image, self.rect)
                if self.rect.x > -100 and self.direction == -1:
                    self.mysteryEntered.fadeout(4000)
                    self.rect.x -= 2
                    game.screen.blit(self.image, self.rect)
    
            if self.rect.x > 830:
                self.playSound = True
                self.direction = -1
                resetTimer = True
            if self.rect.x < -90:
                self.playSound = True
                self.direction = 1
                resetTimer = True
            if passed > self.moveTime and resetTimer:
                self.timer = currentTime
    
    
    class EnemyExplosion(sprite.Sprite):
        def __init__(self, enemy, *groups):
            super(EnemyExplosion, self).__init__(*groups)
            self.image = transform.scale(self.get_image(enemy.row), (40, 35))
            self.image2 = transform.scale(self.get_image(enemy.row), (50, 45))
            self.rect = self.image.get_rect(topleft=(enemy.rect.x, enemy.rect.y))
            self.timer = time.get_ticks()
    
        @staticmethod
        def get_image(row):
            img_colors = ['purple', 'blue', 'blue', 'green', 'green']
            return IMAGES['explosion{}'.format(img_colors[row])]
    
        def update(self, current_time, *args):
            passed = current_time - self.timer
            if passed <= 100:
                game.screen.blit(self.image, self.rect)
            elif passed <= 200:
                game.screen.blit(self.image2, (self.rect.x - 6, self.rect.y - 6))
            elif 400 < passed:
                self.kill()
    
    
    class MysteryExplosion(sprite.Sprite):
        def __init__(self, mystery, score, *groups):
            super(MysteryExplosion, self).__init__(*groups)
            self.text = Text(FONT, 20, str(score), WHITE, mystery.rect.x + 20, mystery.rect.y + 6)
            self.timer = time.get_ticks()
    
        def update(self, current_time, *args):
            passed = current_time - self.timer
            if passed <= 200 or 400 < passed <= 600:
                self.text.draw(game.screen)
            elif 600 < passed:
                self.kill()
    
    
    class ShipExplosion(sprite.Sprite):
        def __init__(self, ship, *groups):
            super(ShipExplosion, self).__init__(*groups)
            self.image = IMAGES['ship']
            self.rect = self.image.get_rect(topleft=(ship.rect.x, ship.rect.y))
            self.timer = time.get_ticks()
    
        def update(self, current_time, *args):
            passed = current_time - self.timer
            if 300 < passed <= 600:
                game.screen.blit(self.image, self.rect)
            elif 900 < passed:
                self.kill()
    
    
    class Life(sprite.Sprite):
        def __init__(self, xpos, ypos):
            sprite.Sprite.__init__(self)
            self.image = IMAGES['ship']
            self.image = transform.scale(self.image, (23, 23))
            self.rect = self.image.get_rect(topleft=(xpos, ypos))
    
        def update(self, *args):
            game.screen.blit(self.image, self.rect)
    
    
    class Text(object):
        def __init__(self, textFont, size, message, color, xpos, ypos):
            self.font = font.Font(textFont, size)
            self.surface = self.font.render(message, True, color)
            self.rect = self.surface.get_rect(topleft=(xpos, ypos))
    
        def draw(self, surface):
            surface.blit(self.surface, self.rect)
    
    
    class SpaceInvaders(object):
        def __init__(self):
            # It seems, in Linux buffersize=512 is not enough, use 4096 to prevent:
            #   ALSA lib pcm.c:7963:(snd_pcm_recover) underrun occurred
            mixer.pre_init(44100, -16, 1, 4096)
            init()
            self.clock = time.Clock()
            self.caption = display.set_caption('Space Invaders')
            self.screen = SCREEN
            self.background = image.load(IMAGE_PATH + 'background.jpg').convert()
            self.startGame = False
            self.mainScreen = True
            self.gameOver = False
            # Counter for enemy starting position (increased each new round)
            self.enemyPosition = ENEMY_DEFAULT_POSITION
            self.titleText = Text(FONT, 50, 'Space Invaders', WHITE, 164, 155)
            self.titleText2 = Text(FONT, 25, 'Press any key to continue', WHITE, 201, 225)
            self.gameOverText = Text(FONT, 50, 'Game Over', WHITE, 250, 270)
            self.nextRoundText = Text(FONT, 50, 'Next Round', WHITE, 240, 270)
            self.enemy1Text = Text(FONT, 25, '   =   10 pts', GREEN, 368, 270)
            self.enemy2Text = Text(FONT, 25, '   =  20 pts', BLUE, 368, 320)
            self.enemy3Text = Text(FONT, 25, '   =  30 pts', PURPLE, 368, 370)
            self.enemy4Text = Text(FONT, 25, '   =  ?????', RED, 368, 420)
            self.scoreText = Text(FONT, 20, 'Score', WHITE, 5, 5)
            self.livesText = Text(FONT, 20, 'Lives ', WHITE, 640, 5)
    
            self.life1 = Life(715, 3)
            self.life2 = Life(742, 3)
            self.life3 = Life(769, 3)
            self.livesGroup = sprite.Group(self.life1, self.life2, self.life3)
    
    +       self.paused = False
    
    
        def reset(self, score):
            self.player = Ship()
            self.playerGroup = sprite.Group(self.player)
            self.explosionsGroup = sprite.Group()
            self.bullets = sprite.Group()
            self.mysteryShip = Mystery()
            self.mysteryGroup = sprite.Group(self.mysteryShip)
            self.enemyBullets = sprite.Group()
            self.make_enemies()
            self.allSprites = sprite.Group(self.player, self.enemies, self.livesGroup, self.mysteryShip)
            self.keys = key.get_pressed()
    
            self.timer = time.get_ticks()
            self.noteTimer = time.get_ticks()
            self.shipTimer = time.get_ticks()
            self.score = score
            self.create_audio()
            self.makeNewShip = False
            self.shipAlive = True
    
        def make_blockers(self, number):
            blockerGroup = sprite.Group()
            for row in range(4):
                for column in range(9):
                    blocker = Blocker(10, GREEN, row, column)
                    blocker.rect.x = 50 + (200 * number) + (column * blocker.width)
                    blocker.rect.y = BLOCKERS_POSITION + (row * blocker.height)
                    blockerGroup.add(blocker)
            return blockerGroup
    
        def create_audio(self):
            self.sounds = {}
            for sound_name in ['shoot', 'shoot2', 'invaderkilled', 'mysterykilled', 'shipexplosion']:
                self.sounds[sound_name] = mixer.Sound(
                    SOUND_PATH + '{}.wav'.format(sound_name))
                self.sounds[sound_name].set_volume(0.2)
    
            self.musicNotes = [mixer.Sound(SOUND_PATH + '{}.wav'.format(i)) for i in range(4)]
            for sound in self.musicNotes:
                sound.set_volume(0.5)
    
            self.noteIndex = 0
    
        def play_main_music(self, currentTime):
            if currentTime - self.noteTimer > self.enemies.moveTime:
                self.note = self.musicNotes[self.noteIndex]
                if self.noteIndex < 3:
                    self.noteIndex += 1
                else:
                    self.noteIndex = 0
    
                self.note.play()
                self.noteTimer += self.enemies.moveTime
    
        @staticmethod
        def should_exit(evt):
            # type: (pygame.event.EventType) -> bool
            return evt.type == QUIT or (evt.type == KEYUP and evt.key == K_ESCAPE)
    
        def check_input(self):
            self.keys = key.get_pressed()
            for e in event.get():
                if self.should_exit(e):
                    sys.exit()
                if e.type == KEYDOWN:
                    if e.key == K_SPACE:
                        if len(self.bullets) == 0 and self.shipAlive:
                            if self.score < 1000:
                                bullet = Bullet(self.player.rect.x + 23,
                                                self.player.rect.y + 5, -1,
                                                15, 'laser', 'center')
                                self.bullets.add(bullet)
                                self.allSprites.add(self.bullets)
                                self.sounds['shoot'].play()
                            else:
                                leftbullet = Bullet(self.player.rect.x + 8,
                                                    self.player.rect.y + 5, -1,
                                                    15, 'laser', 'left')
                                rightbullet = Bullet(self.player.rect.x + 38,
                                                     self.player.rect.y + 5, -1,
                                                     15, 'laser', 'right')
                                self.bullets.add(leftbullet)
                                self.bullets.add(rightbullet)
                                self.allSprites.add(self.bullets)
                                self.sounds['shoot2'].play()
    +               elif e.key == K_p:
    +                   self.paused = not self.paused
    
    +   def draw_pause_screen(self):
    +       # self.screen.fill((0, 0, 0))
    +       # self.screen.blit(self.background, (0, 0))
    +
    +       pause_text = Text(FONT, 50, 'Paused', WHITE, 286, 250)
    +       resume_text = Text(FONT, 30, 'Press P to Resume', WHITE, 227, 320)
    +       quit_text = Text(FONT, 30, 'Press Q to Quit', WHITE, 254, 370)
    +
    +       pause_text.draw(self.screen)
    +       resume_text.draw(self.screen)
    +       quit_text.draw(self.screen)
    +
    +       self.keys = key.get_pressed()                               # 現在のキーボードの状態を取得
    +       for e in event.get():                                       # イベントを処理
    +           if self.should_exit(e):                                 # ウィンドウを閉じるイベントがあればプログラムを終了
    +               sys.exit()
    +           if e.type == KEYDOWN:                                   # キーの押下によるイベント処理
    +               if e.key == K_p:                                    # Pキーが押された場合
    +                   self.paused = not self.paused
    +                   self.enemies.timer = time.get_ticks()
    +               elif e.key == K_q:                                  # Qキーが押された場合
    +                   sys.exit()
    
        def make_enemies(self):
            enemies = EnemiesGroup(10, 5)
            for row in range(5):
                for column in range(10):
                    enemy = Enemy(row, column)
                    enemy.rect.x = 157 + (column * 50)
                    enemy.rect.y = self.enemyPosition + (row * 45)
                    enemies.add(enemy)
    
            self.enemies = enemies
    
        def make_enemies_shoot(self):
            if (time.get_ticks() - self.timer) > 700 and self.enemies:
                enemy = self.enemies.random_bottom()
                self.enemyBullets.add(
                    Bullet(enemy.rect.x + 14, enemy.rect.y + 20, 1, 5, 'enemylaser', 'center'))
                self.allSprites.add(self.enemyBullets)
                self.timer = time.get_ticks()
    
        def calculate_score(self, row):
            scores = {0: 30,
                      1: 20,
                      2: 20,
                      3: 10,
                      4: 10,
                      5: choice([50, 100, 150, 300])
                      }
    
            score = scores[row]
            self.score += score
            return score
    
        def create_main_menu(self):
            self.enemy1 = IMAGES['enemy3_1']
            self.enemy1 = transform.scale(self.enemy1, (40, 40))
            self.enemy2 = IMAGES['enemy2_2']
            self.enemy2 = transform.scale(self.enemy2, (40, 40))
            self.enemy3 = IMAGES['enemy1_2']
            self.enemy3 = transform.scale(self.enemy3, (40, 40))
            self.enemy4 = IMAGES['mystery']
            self.enemy4 = transform.scale(self.enemy4, (80, 40))
            self.screen.blit(self.enemy1, (318, 270))
            self.screen.blit(self.enemy2, (318, 320))
            self.screen.blit(self.enemy3, (318, 370))
            self.screen.blit(self.enemy4, (299, 420))
    
        def check_collisions(self):
            sprite.groupcollide(self.bullets, self.enemyBullets, True, True)
    
            for enemy in sprite.groupcollide(self.enemies, self.bullets, True, True).keys():
                self.sounds['invaderkilled'].play()
                self.calculate_score(enemy.row)
                EnemyExplosion(enemy, self.explosionsGroup)
                self.gameTimer = time.get_ticks()
    
            for mystery in sprite.groupcollide(self.mysteryGroup, self.bullets, True, True).keys():
                mystery.mysteryEntered.stop()
                self.sounds['mysterykilled'].play()
                score = self.calculate_score(mystery.row)
                MysteryExplosion(mystery, score, self.explosionsGroup)
                newShip = Mystery()
                self.allSprites.add(newShip)
                self.mysteryGroup.add(newShip)
    
            for player in sprite.groupcollide(self.playerGroup, self.enemyBullets, True, True).keys():
                if self.life3.alive():
                    self.life3.kill()
                elif self.life2.alive():
                    self.life2.kill()
                elif self.life1.alive():
                    self.life1.kill()
                else:
                    self.gameOver = True
                    self.startGame = False
                self.sounds['shipexplosion'].play()
                ShipExplosion(player, self.explosionsGroup)
                self.makeNewShip = True
                self.shipTimer = time.get_ticks()
                self.shipAlive = False
    
            if self.enemies.bottom >= 540:
                sprite.groupcollide(self.enemies, self.playerGroup, True, True)
                if not self.player.alive() or self.enemies.bottom >= 600:
                    self.gameOver = True
                    self.startGame = False
    
            sprite.groupcollide(self.bullets, self.allBlockers, True, True)
            sprite.groupcollide(self.enemyBullets, self.allBlockers, True, True)
            if self.enemies.bottom >= BLOCKERS_POSITION:
                sprite.groupcollide(self.enemies, self.allBlockers, False, True)
    
        def create_new_ship(self, createShip, currentTime):
            if createShip and (currentTime - self.shipTimer > 900):
                self.player = Ship()
                self.allSprites.add(self.player)
                self.playerGroup.add(self.player)
                self.makeNewShip = False
                self.shipAlive = True
    
        def create_game_over(self, currentTime):
            self.screen.blit(self.background, (0, 0))
            passed = currentTime - self.timer
            if passed < 750:
                self.gameOverText.draw(self.screen)
            elif 750 < passed < 1500:
                self.screen.blit(self.background, (0, 0))
            elif 1500 < passed < 2250:
                self.gameOverText.draw(self.screen)
            elif 2250 < passed < 2750:
                self.screen.blit(self.background, (0, 0))
            elif passed > 3000:
                self.mainScreen = True
    
            for e in event.get():
                if self.should_exit(e):
                    sys.exit()
    
        def main(self):
            while True:
                if self.mainScreen:
                    self.screen.blit(self.background, (0, 0))
                    self.titleText.draw(self.screen)
                    self.titleText2.draw(self.screen)
                    self.enemy1Text.draw(self.screen)
                    self.enemy2Text.draw(self.screen)
                    self.enemy3Text.draw(self.screen)
                    self.enemy4Text.draw(self.screen)
                    self.create_main_menu()
                    for e in event.get():
                        if self.should_exit(e):
                            sys.exit()
                        if e.type == KEYUP:
                            # Only create blockers on a new game, not a new round
                            self.allBlockers = sprite.Group(self.make_blockers(0),
                                                            self.make_blockers(1),
                                                            self.make_blockers(2),
                                                            self.make_blockers(3))
                            self.livesGroup.add(self.life1, self.life2, self.life3)
                            self.reset(0)
                            self.startGame = True
                            self.mainScreen = False
    
    +           elif self.paused:
    +               self.draw_pause_screen()
    +
                elif self.startGame:
                    if not self.enemies and not self.explosionsGroup:
                        currentTime = time.get_ticks()
                        if currentTime - self.gameTimer < 3000:
                            self.screen.blit(self.background, (0, 0))
                            self.scoreText2 = Text(FONT, 20, str(self.score), GREEN, 85, 5)
                            self.scoreText.draw(self.screen)
                            self.scoreText2.draw(self.screen)
                            self.nextRoundText.draw(self.screen)
                            self.livesText.draw(self.screen)
                            self.livesGroup.update()
                            self.check_input()
                        if currentTime - self.gameTimer > 3000:
                            # Move enemies closer to bottom
                            self.enemyPosition += ENEMY_MOVE_DOWN
                            self.reset(self.score)
                            self.gameTimer += 3000
                    else:
                        currentTime = time.get_ticks()
                        self.play_main_music(currentTime)
                        self.screen.blit(self.background, (0, 0))
                        self.allBlockers.update(self.screen)
                        self.scoreText2 = Text(FONT, 20, str(self.score), GREEN, 85, 5)
                        self.scoreText.draw(self.screen)
                        self.scoreText2.draw(self.screen)
                        self.livesText.draw(self.screen)
                        self.check_input()
                        self.enemies.update(currentTime)
                        self.allSprites.update(self.keys, currentTime)
                        self.explosionsGroup.update(currentTime)
                        self.check_collisions()
                        self.create_new_ship(self.makeNewShip, currentTime)
                        self.make_enemies_shoot()
    
                elif self.gameOver:
                    currentTime = time.get_ticks()
                    # Reset enemy starting position
                    self.enemyPosition = ENEMY_DEFAULT_POSITION
                    self.create_game_over(currentTime)
    
                display.update()
                self.clock.tick(60)
    
    
    if __name__ == '__main__':
        game = SpaceInvaders()
        game.main()
    

Your answer might help someone💌