Ccmmutty logo
Commutty IT
9 min read

懐かしのゲーム

https://cdn.magicode.io/media/notebox/a5d1028f-3cb2-4860-ab9e-5e407c8e140e.jpeg
pip install pygame
import sys
import random
import pygame

class Snake(): #スネークのクラス
    def __init__(self): #ゲームを初期状態にする関数・機能
        self.length = 1 #スネークの長さを1(先頭のみ)に設定する
        self.positions = [((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2))] #スネークの位置を画面の真ん中にする
        self.direction = random.choice([up, down, left, right]) #スネークの進行方向をランダムに設定する
        self.color = (17, 24, 47) #スネークの色を設定する
        self.score = 0 #スコアを0にする

    def get_head_position(self): #スネークの現在の先頭マスを呼んだコードに教える関数・機能
        return self.positions[0] 

    def turn(self, point): #スネークの進行方向を変更する関数
        if self.length > 1 and (point[0] * -1, point[1] * -1) == self.direction: #self.length > 1 ...スネークの長さ(length)が1より大きい and...かつ 
                                                                                 #(point[0] * -1, point[1] * -1) == self.direction...進行方向が前後であれば、前後ろキーは無効、左右も同様に左右のキーが無効になる
            return #何もしないで呼んだコードに戻る
        else: #上の条件に満たしていない場合に以下のコードが使用される
            self.direction = point

    def move(self): #スネークを1マス進める関数・機能
        cur = self.get_head_position() #現在のスネークの先頭マスを関数に聞く
        x, y = self.direction #現在のスネークの進行方向を取得する
        new = (((cur[0] + (x * GRIDSIZE)) % SCREEN_WIDTH), (cur[1] + (y * GRIDSIZE)) % SCREEN_HEIGHT) #次に移動するマスを計算する
        if len(self.positions) > 2 and new in self.positions[2:]: #スネークの先頭とスネーク自身の体が重なった場合
            self.reset() #スネークのマスや長さ、スコアをリセットする
        elif cur[0] <= 0 or cur[0] >= SCREEN_HEIGHT - GRIDSIZE or cur[1] <= 0 or cur[1] >= SCREEN_WIDTH - GRIDSIZE: #スネークの先頭が壁にぶつかった場合
            self.reset() #スネークのマスや長さ、スコアをリセットする
        else: #↑2つの条件を満たさないとき
            self.positions.insert(0, new) #マスの位置を新しく計算したマスを先頭のマスに設定する
            if len(self.positions) > self.length: #現在のスネークの長さとポジションの数を比較して、スネークの長さが小さい場合 ※ポジションの数は、スネークの長さ+次に移動するマス
                self.positions.pop() #一番後ろの体を消滅させる

    def reset(self): #スネークの長さ、マス、進行方向、スコアを最初からにする関数・機能
        self.length = 1 #スネークの長さを1マス(先頭だけ)にする
        self.positions = [((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2))] #スネークのマスを真ん中のマスに設定する
        self.direction = random.choice([up, down, left, right]) #スネークの進行方向をランダムに設定する
        self.score = 0 #スコアを0に設定する

    def draw(self, surface): #画面にスネークを表示させる関数・機能
        for p in self.positions: #スネークの長さ分繰り返す
            r = pygame.Rect((p[0], p[1]), (GRIDSIZE, GRIDSIZE)) #スネークを表示させるマスを設定する
            pygame.draw.rect(surface, self.color, r) #画面にスネークを表示させる
            pygame.draw.rect(surface, (93, 216, 218), r, 1) #画面のスネークに隙間を表示させる


    def handle_keys(self): #押されているキーを見て、キーによって使用するコードを変える関数・機能
        for event in pygame.event.get(): #何が起きているか(イベント)見る
            if event.type == pygame.QUIT: #画面が閉じられている場合
                pygame.quit() #ゲームを終了する
                sys.exit() #プログラムを終了する
            elif event.type == pygame.KEYDOWN: #キーボードのキーが押された場合
                if event.key == pygame.K_UP: #↑キーが押された場合
                    self.turn(up) #進行方向を↑に設定する
                elif event.key == pygame.K_DOWN: #↓キーが押された場合
                    self.turn(down) #進行方向を↓に設定する
                elif event.key == pygame.K_LEFT: #←キーが押された場合
                    self.turn(left) #進行方向を←に設定する
                elif event.key == pygame.K_RIGHT: #→キーが押された場合
                    self.turn(right) #進行方向を→に設定する

class Food(): #食べ物のクラス
    def __init__(self): #ゲームを初期状態にする関数・機能
        self.position = (0, 0) #食べ物を配置するマスを左上に設定する変数
        self.color = (223, 163, 49) #食べ物の色を設定する変数
        self.randomize_position() #食べ物をランダムなマスに配置する関数を呼ぶ

    def randomize_position(self): #食べ物をランダムなマスに配置する関数・機能
        X = random.randint(1, GRID_WIDTH - 2) * GRIDSIZE
        Y = random.randint(1, GRID_HEIGHT - 2) * GRIDSIZE
        self.position = (X,Y) #↑で計算したマスを食べ物を配置するマスとして設定する

    def draw(self, surface): #画面に食べ物を表示させる関数・機能
        r = pygame.Rect(self.position, (GRIDSIZE, GRIDSIZE)) #食べ物を表示させるマスを設定する
        pygame.draw.rect(surface, self.color, r) #食べ物を表示させる
        pygame.draw.rect(surface, (93, 216, 228), r, 1) #食べ物の周りに隙間を表示させる


def drawGrid(surface): #画面の背景を表示させる関数・機能
    for y in range(0, int(GRID_HEIGHT)): #画面の縦幅分繰り返す
        for x in range(0, int(GRID_WIDTH)): #画面の横幅分繰り返す
            if (x + y) % 2 == 0: #縦の位置+横位置から2で割った際に、割り切れるマスの場合
                r = pygame.Rect((x * GRIDSIZE, y * GRIDSIZE), (GRIDSIZE, GRIDSIZE)) #マスの場所を設定
                pygame.draw.rect(surface, (93, 216, 228), r) #マスを表示させる
            else:  #縦の位置+横位置から2で割った際に、割り切れないマスの場合
                rr = pygame.Rect((x * GRIDSIZE, y * GRIDSIZE), (GRIDSIZE, GRIDSIZE)) #マスの場所を設定
                pygame.draw.rect(surface, (84, 194, 205), rr) #マスを表示させる


SCREEN_WIDTH = 480 #画面の横幅
SCREEN_HEIGHT = 480 #画面の縦幅

GRIDSIZE = 20 #1マスのサイズ
GRID_WIDTH = SCREEN_HEIGHT / GRIDSIZE #1画面に存在する横のマスの数
GRID_HEIGHT = SCREEN_WIDTH / GRIDSIZE #1画面に存在する縦のマスの数

up = (0, -1)    #上マスに移動するための数字      0 ...右に0マス移動 -1...下に-1マス移動(つまり上方向に移動)
down = (0, 1)   #下マスに移動するための数字      0 ...右に0マス移動 1 ...下に1マス移動
left = (-1, 0)  #左マスに移動するための数字     -1 ...右に-1マス移動(左方向に移動)0...下に0マス移動
right = (1, 0)  #下マスに移動するための数字      1 ...右に1マス移動 0 ...下に0マス移動


def main():
    try:
        #ゲームを使用できるようにする(初期化)
        pygame.init() #ゲームを初期状態にする
        clock = pygame.time.Clock() #ゲームで使うタイマーの間隔
        screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32) #画面のサイズを決めたうえで画面を作成する

        #表示するための画面を作る
        surface = pygame.Surface(screen.get_size()) #まっさらな画面の作成 ※screen と surfaceは別の画面であることに注意
        surface = surface.convert() #↑で作成した画面のコピーを取る
        drawGrid(surface) #作成したまっさらな画面にゲームの背景部分を表示する

        #スネークと食べ物を使用できるようにする
        snake = Snake() #スネークの機能を使えるようにする(スネークの初期化)
        food = Food() #食べ物の機能を使えるようにする(食べ物の初期化)

        #文字の表示について設定する
        myfont = pygame.font.SysFont("monospace", 16) #スコアの表示を設定する

        while (True):
            clock.tick(10) #1秒に10回実行(移動)する
            snake.handle_keys() #キーボードでどのキーが押されているかチェックして、上下左右のキーが押されていたら方向を変える
            drawGrid(surface) #画面にゲームの背景部分を表示する
            snake.move() #現在の進行方向に1マス進め、その後、ゲームオーバーの条件を満たしているかチェックする。満たしている場合はゲームをリセットする
            if snake.get_head_position() == food.position: #スネークの先頭(頭の部分)のマスと食べ物があるマスを比較して、場所が同じ場合に以下3行のコードを使用する
                snake.length += 1 #スネークの長さを1マス増やす
                snake.score += 1 #スコアをプラス1する
                food.randomize_position() #食べ物の場所をランダムに設定する
            snake.draw(surface) #画面にスネークを表示する
            food.draw(surface)#画面に食べ物を表示する
            screen.blit(surface, (0, 0)) #screenの画面の左上(0,0)にsurface(スネークと食べ物)の画面を描く
            text = myfont.render("Score {0}".format(snake.score), 1, (0, 0, 0)) #スコアの絵を作る
            screen.blit(text, (5, 10)) #screenの画面の左上(5,10)にtext(スコア)の絵を描く
            pygame.display.update() #画面を更新する
    except Exception as err:
        raise Exception("Error") from err

main() #プログラムを開始する関数を呼ぶ

Discussion

コメントにはログインが必要です。