スキップしてメイン コンテンツに移動

Python:お粗末でもゲームを作ってみる!【Pygame】

  今回はPythonのライブラリPygameを使ってゲームを作っていきたいと思います。 PygamePythonでゲームを作るライブラリの中で一般的ではありますが初心者の私からすると少し難しく感じました。 Python自体もそこまで自信がないので今回できたことを備忘録程度にまとめていきたいと思います。

前提条件

Pythonの開発環境が整っていること

ライブラリのインストール

まず初めにPygameライブラリが必要なのでインストールから始めます。
以下の説明は私がPython3を使っているのでpip3コマンドを使っていきますが環境のバージョンに合わせてpipコマンドを使ってください。

pip3 install pygame

でインストールできます。そして確認は

pip3 list

コマンドで自分がインストールしたライブラリの一覧が出てきます。 画像下部のようにpygameが存在すれば完了です。 

前準備

次に今回はお粗末なゲームを作るうえで見栄えとわかりやすいように画像を使用するので少し説明していきたいと思います。

  • 注意:ネットに落ちている画像を使う場合は著作権などに注意して使ってください。

今回使う画像はこちらからダウンロードさせていただきました。

opengameart.org

まずは画像の保存場所を決めましょう。
プログラムと画像を保存したいファイルを作ります。私はわかりやすくデスクトップにファイルを作り説明していきますが、それぞれの環境に合わせて決めてください。

\Users\UserName\Desktop\test

デスクトップにtestファイルを作りここにプログラムと画像や音のファイルを追加していきます。
Pygameで使える画像のフォーマットは下記のサイトを参考にさせて頂きました。shizenkarasuzon.hatenablog.com要約すると身近なJPG、PNGが対応しているとのことで、GIFは静止画のみが読み込まれるようです。なるべく前者の2つを使用するのがいいと思います。

プログラム

次にプログラムの説明をしていきたいと思います。自分もあまり理解できていない点があるので浅広な内容になってしまいますがご了承ください。
単純なモグラたたきに似て非なるものを作ってみました。

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

class MySprite(pygame.sprite.Sprite): #スプライトクラス
    def __init__(self, filename, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(filename).convert_alpha()
        width = self.image.get_width()
        height = self.image.get_height()
        self.rect = Rect(x, y, width, height)

    def update(self):
        self.kill()

def main():
    pygame.init()
    (w,h) = (800,600)   # 画面サイズ
    (x,y) = (200, 200)  # プレイヤー画像の初期配置座標
    pygame.init()       # pygame初期化
    font = pygame.font.Font(None, 40)                            #フォントの初期設定
    punch_count = 0
    count = 0
    screen = pygame.display.set_mode((w, h), 0, 0)              #画面設定
    screen = pygame.display.get_surface()
    pygame.display.set_caption("Test")                           #タイトルバーに表示する
    player = pygame.image.load("hogehoge.png").convert_alpha()      #プレイヤー画像の取得
    times_x = int(player.get_width() * 1.5)                      #画像の幅の1.5倍を取得
    times_y = int(player.get_height() * 1.5)                     #画像の高さの1.5倍を取得
    player = pygame.transform.scale(player, (times_x, times_y))  #1.5倍に拡大
    bg = pygame.image.load("hogehoge.png").convert_alpha()             #背景画像の取得
    rect_bg = bg.get_rect()
    pygame.mixer.init(frequency = 44100)                         #音用の初期設定
    group = pygame.sprite.RenderUpdates()                        #スプライトグループの作成
    clock = pygame.time.Clock()
    now_count = False

    start_time = time.time()
    while True:
        if  now_count == True:
            if (time.time() - count) >= del_sec:
                group.update()
                now_count = False
        else:
            del_sec = random.uniform(0.3,1.5) #出現と消滅頻度(乱数)
            count = time.time()
            #////敵の出現場所をランダムに選ぶ(乱数生成の範囲を変えることで出現場所を変えられる)
            enemy_x = random.randint(0,700)
            enemy_y = random.randint(200,500)
            enemy_x = random.randint(0,700)
            enemy_y = random.randint(200,500)
            enemy1 = MySprite("hogehoge.png", enemy_x, enemy_y)                #敵の画像を指定
            #////
            group.add(enemy1)
            now_count = True

        clock.tick(60)                                                       # 60fps
        screen.blit(bg, rect_bg)                                             #背景
        group.draw(screen)                                                   #グループの描画
        screen.blit(player, (x, y))                                          #プレイヤー画像の描画 0,0座標から幅44px高さ66pxだけ切り抜く
        text = font.render("COUNT:" + str(punch_count), True, (255,255,255)) #テキストの描画
        screen.blit(text, [0, 0])                                      #表示位置
        pygame.display.update()                                        #描画のアップデート

        for event in pygame.event.get():
            # マウスポインタで画像も移動
            if event.type == MOUSEMOTION:
                x, y = event.pos
                x -= int(player.get_width() / 2)
                y -= int(player.get_height() / 2)
            
            # 敵上でマウスがクリックされたか判定
            if (event.type == pygame.MOUSEBUTTONDOWN) and (event.button == 1) :
                #////クリックしたときの音
                # pygame.mixer.music.load("") #引数にwaveやmp3のファイル名を指定することによって音が出せる
                # pygame.mixer.music.play(1) #引数は1or-1で一回orループ
                #////
                if enemy1.rect.collidepoint(event.pos):
                    #////敵にカーソルを合わせてクリックしたときの音
                    # pygame.mixer.music.load("") #引数にwaveやmp3のファイル名を指定することによって音が出せる
                    # pygame.mixer.music.play(1) ##引数は1or-1で一回orループ
                    #////
                    group.update()
                    now_count = False
                    print("Hit!!")
                    punch_count += 1


            # 終了用のイベント処理
            if event.type == QUIT:          #×ボタンが押されたとき
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:       # キーを押したとき
                if event.key == K_ESCAPE:   # Escキーが押されたとき
                    pygame.quit()
                    sys.exit()
main()

動作確認もしたい方はこちらを画像が保存されているフォルダと同じ場所にプログラムを保存してください。そして以下の文を読んで書き換える作業を行ってください。
コメントで大まかな説明はしていますが強調と追加説明をしていきます。

(w,h) = (800,600)   # 画面サイズ

ここで指定するサイズは背景に使う画像を同じサイズにしておくことをお勧めします。

~
player = pygame.image.load("hogehoge.png").convert_alpha()      #プレイヤー画像の取得
~
bg = pygame.image.load("hogehoge.png").convert_alpha()             #背景画像の取得
~
enemy1 = MySprite("hogehoge.png", enemy_x, enemy_y)                #敵の画像を指定
~

上記三つの項目のhogehoge.pngの場所をそれぞれ対応する画像の名前に書き換えてください。もちろん例ではpngになっていますが拡張子も合わせて書き換えてください。

  # pygame.mixer.music.load("") #引数にwaveやmp3のファイル名を指定することによって音が出せる

そのままだと使えないので引数に画像を保存したファイルの同じ階層に置いてあるwaveまたはmp3ファイルを指定してあげることで音を鳴らすことが出来ます。 使う場合はコメント化されているので解除してから使ってください。

pygame.display.update()                                        #描画のアップデート

描画のアップデートをすることによって手前のscreen.blite()などで宣言したもの表示するのでアップデートをかけるタイミングを間違えるとうまく表示されなかったりします。

あとはスプライトのグループなんかを使ったりしていますが、出現させるものを一体に絞っているので使わなくてもいいと思います。使ってみたかったのと書き方がいまいちわからなかったので先人の知恵(サイト)を借りて採用しました。
いまいちスプライトやグループの使い方がわかっていないので遠回りしているかもしれませんがご了承ください。 参考にさせて頂いサイトはこちらです。

algorithm.joho.info

westplain.sakuraweb.com

teratail.com

aidiary.hatenablog.com

動作確認

次に動作確認をしていきます。
先ほどのプログラムを実行してみましょう。私の場合はコマンドプロンプトで保存してあるディレクトリアで移動して

cd \Uses\UserName\Desktop\test

testGame.pyで保存したので

python3 testGame.py

で実行します。そうすると  こんな感じになりました。
画像は前述したサイトと背景はHaLaKeの写真を使ってみました。
画像はそれぞれで用意してもらう必要がありますので好きな画像を使って楽しんでみてください。
内容は敵の画像の上にカーソルを合わせてクリックすると左上のカウンタが増えるのでそれだけです。
 前述したように音声を付けると少しはそれなりの雰囲気にはなります。(妥協)

まとめ

Pygameは初心者にとっては少し難しいと感じました。時間をかければもっといろいろなこともできると思いますが、本格的なゲームを作る気もないのと時間もないのでここまでにします。プログラムも雑だったり間違っている部分もあるかと思いますが誰かの参考になれば幸いです。

コメント

このブログの人気の投稿

Phaser3 + Typescriptを使ってRPGゲームの基礎を作ろう!その2

前回の記事 に引き続きPhaser3+Typescriptを使って RPG の基礎を作っていきます。 この記事は前回の記事を呼んだ前提で説明していきますので、ぜひそちらを先に読むことをお勧めします。 また、今回の記事は前回よりも難易度と内容量が上がっていますが、記事の最後に作業後の リポジトリ のリンクがありますので、そちらを先にダウンロードしてそちらと比較しながら学習することができます。 前回まで作成した状態のプログラムが以下の リポジトリ からダウンロードできますので前回まででうまくいっていない方は参考にしてみてください。 github.com 最終目標(再掲) ・Phaser3とTypescriptで RPG ゲームの基礎を作る。 ・Phaser3をTypescriptで使う方法を学ぶ ・Phaser3の使い方を学ぶ 今回の目標 ・ゲームの作り方の断片を知る ・キャラの表示できるようにする ・キャラを移動できるようにする ・当たり判定をつける ・ NPC の追加してみる ・話しかけられるようにする 開発前提(再掲) ・Nodejsの環境・知識がある ・ Javascript ・Typescriptがある程度かける ・当ページ紹介の環境を試す場合はgit・ github の知識がある 使用した主要Nodeモジュール(再掲) ・typescript(Typescriptの コンパイル 用) ・phaser(フロントの Javascript 用ゲームライブラリ) ・live-server(ソースを監視してブラウザのページをリロード) ・ts-loader(webpackがTypescriptをバンドルする用)webpack(言わずと知れたモジュール依存をいい感じに解決しバンドルする) ・webpack- cli (webpackを コマンドライン で使用するのに必要) 注:各Nodeモジュールバージョンは後述 当ブログ仕様の画像素材の注意点 当ブログで使用する画像素材は『 ピポヤ倉庫 』より許可なしで無償再配布・改変が認められたものを改変して作成されたものです。 中には許可なく再配布・改変してはいけない素材もインターネット上には多く存在するのでそれらを使用するときは十分に規約を呼んでから使用しましょう。 1. キャラの表示 想定画面 今回は、はじめにキャラつまり操作

M5Stackで、においセンサー(TGS2450)を使ってみる。(LCDに表示編)

今回は、においセンサー(TGS2450)から取得したデータをM5Stackの LCD にグラフ表示をしていきます。 今回主に使用したもの M5Stack 10Ω抵抗 5本 Pch  MOSFET  2SJ334(スイッチとして利用) M5StackSideBB(ブレッドボード) M5Stackのピンはそのままだと配線するとき手間がかかるかと思いますので、今回はM5StackSideBBを利用しました。 ブレッドボードも付いているので、手軽に電子工作できるので個人的にオススメです。 SideBB for M5Stack www.switch-science.com 諸注意 本ブログのプログラムはArduinoIDEまたはPlatformIOでM5Stackの開発ができる状態であること前提のものですので、各自導入をお願いします。 過去に Windows のArduinoIDEで M5Stackの開発環境を構築する記事 があるので、参考にしてください。 においセンサー(TGS2450)について 今回使用したセンサーは 秋月電子通商 で購入できます。 http://akizukidenshi.com/catalog/g/gP-00989/ akizukidenshi.com TGS2450には4つのピンがあり、使用するのはそのうちの3本でヒーターを温めるピン、センサー情報を得るピン、GNDがあります。 ここで注意したいのは、ヒーター電圧は1.6Vと記述されているのでM5Stackで利用するときは分圧して3.3Vを1.6V近くまでに降圧することをお勧めします。 TGS2450のセンサーは可変抵抗になっており、データシートには5.62kΩ〜56.2kΩの間を抵抗が変化し、においが強いとより低くなると記述されていました。 よって、センサーの値をM5Stackで取得するにはセンサー抵抗と外部に接続する任意の値の抵抗による分圧回路によって求めることができます。 TGS2450の動作方法は、250ms周期でセンサーに電圧を5ミリ秒on、245ミリ秒offの状態にしてヒーターは8ミリ秒on、242ミリ秒offにすることで値を取得します。 配線 においセンサーとM5Stackの配線 上の図が配線図です。 30Ωの抵抗は10Ωの抵抗を三つ直列に接続して作成しました。 また、上部の抵抗10Ω二

Phaser3 + Typescriptを使ってRPGゲームの基礎を作ろう!その1

今回はPhaser3とTypescriptを使って簡単な RPG ゲームを作る方法を紹介していきます。 内容はPhaser3およびゲーム作りについての記事なので、Nodejsの周辺モジュールなどの説明は一部省いての説明になりますのでご了承ください。 またこの記事では Phaser2 ではなく Phaser3 を使用するので注意してください。 この記事は二部構成になりますので、この記事を読んだ際はぜひ次の記事も読むことをお勧めします。 最終目標 ・Phaser3とTypescriptで RPG ゲームの基礎を作る。 ・Phaser3をTypescriptで使う方法を学ぶ ・Phaser3の使い方を学ぶ 今回の目標 ・開発環境を整える ・Phaser3の開発構成を知る ・スタート画面を作る ・マップ表示をさせる 開発前提 ・Nodejsの環境・知識がある ・ Javascript ・Typescriptがある程度かける ・当ページ紹介の環境を試す場合はgit・ github の知識がある 使用した主要Nodeモジュール ・typescript(Typescriptの コンパイル 用) ・phaser(フロントの Javascript 用ゲームライブラリ) ・live-server(ソースを監視してブラウザのページをリロード) ・ts-loader(webpackがTypescriptをバンドルする用)webpack(言わずと知れたモジュール依存をいい感じに解決しバンドルする) ・webpack- cli (webpackを コマンドライン で使用するのに必要) 注:各Nodeモジュールバージョンは後述 1. 最低限の開発環境の準備 今回最低限の環境を整えるために、『Typescript + Phaser3』の開発テンプレートを github リポジトリ で公開しました。 以下からZIPをダウンロードするか、 git clone コマンドで各自環境に展開してみてください。 ここから先は リポジトリ のプログラムを元に説明していきます。 github.com 展開するとファイル構造は以下のようになっているかと思われます。 注: 他にもファイルやフォルダがあるかと思われますが、表記されているのは今回使うものになっています。 - src/ (これから書くプログラムの保存領域)