この記事は、岩手県八幡平市のプログラミング教室「アクセルキャンプ」の公開教材です。
アクセルキャンプ(フリースペースプラウド)のリンク
教材の作成依頼等も承っております。ご意見等は、リンク先の問い合わせ欄からお願いします。
教材の転用・利用等は自由です。
陸上競技会、おつかれっす
先生の学校は運動会が10月にあったので、岩手に来てちょっと不思議でした。(岩手も場所によるみたいね)なんで10月に運動会やらんのやろって思ってたけど、冷静に考えて寒くてそれどころじゃねえ!ってことかなーと思ってます。しらんけど。先生は足が遅くても顔の良さでカバーするタイプだったので、小学校最後の50mの記録が8.7とかだったのは覚えてます。
ライブラリを使ってみよう
前回は、「モジュール」というのを使いました。モジュールって何かというと、もとからpythonに入ってるけど、そのまんまでは使えない機能のことで、random()モジュールとかを紹介しました。
今回はモジュールではなく**ライブラリ**というのを使ってみます。ライブラリとは
pythonにもともと用意されてないけど、どこかのすごい人が作った便利な機能で、python(などのプログラミング言語)で使えるやつのことです。
<注意>いつも使っているpaizaでは、ライブラリを使うことができません。今回は読むだけの記事って言うことで、今日のところは見逃してやるよ┐(´д`)┌ヤレヤレ
今回はpygameという、文字通りpythonで2Dゲームを作るためのライブラリを使います。「paizaでは実行できない」とはいったものの、「しっかりした手順でインポートしないとどうなるのか」というエラーを出すことはできるので、やってみましょう
では、とりあえず↓のコードを打ってみましょう。
import pygame
さてさて、どんなエラーが出るやら。
Traceback (most recent call last):
File "Main.py", line 1, in
import pygame
ModuleNotFoundError: No module named 'pygame'
エラー文の一番下を見てみましょう
ModuleNotFoud → Module Not Found
さて、英語の勉強の時間です。Foundというのは、Findという動詞が変化したものなんですが、Findは「見つける」ていう意味です。(辞書をひいてみましょー!)
つまり、「pygameなんてう名前のモジュール (Module) 見つかんねーよ(Not Found) バーカ!」と、イキリ気味にpythonくんに言われているわけです。イキってるかはしらんけど。
ここで使えるようにするには、pipという機能を使ってインストールする必要があるのですが、そのやり方はまた今度。とりあえず今は、なんとなーくモジュールとライブラリの違いをわかっておいてくれれば十分です、
pygameの初期設定をしてみよう
先に言っときますが、今回の内容だけでは、ゲームが出来上がったりしないどころが、ゲームを作り始めもしません、なので結構地味な内容になります。ほらそこ、寝ない!!
今日は、どんな2Dゲームを作るにも、最初は絶対ここはやるよね!という、初期画面作成までやっていきます。
もはや呪文: pygameプログラムの初期コード
プログラマー業界で、「なんかよくわかんなくてもこういう時は脳死でこう書くよね」みたいなコードのことを、「呪文」といったりします。(たまに、「なんで動いてるかわからないけどとりあえずちゃんと動いてるコード」みたいな意味になったりもします。)
pygame初期設定の呪文コードはこんなかんじ↓
import pygame
from pygame.locals import *
import sys
def main():
pygame.init() # Pygameの初期化
screen = pygame.display.set_mode((400, 300)) # 400 x 300の大きさの画面を作る
pygame.display.set_caption("クソゲー") # 画面上部に表示するタイトルを設定
while (1):
screen.fill((0,0,0)) # 画面を黒色に塗りつぶし
pygame.display.update() # 画面を更新
# イベント処理
for event in pygame.event.get():
if event.type == QUIT: # 閉じるボタンが押されたら終了
pygame.quit() # Pygameの終了(画面閉じられる)
sys.exit()
if __name__ == "__main__":
main()
長いと思うか短いと思うかは人それぞれだと思いますが、この中にはpygameで死ぬほどよく使う機能が結構沢山入ってますので、中身を解説していきますね
まず、このコードを見たときに、このコードの9割はmain()関数でできていて、残りの1割はやさしさでできていることに気づきますか?(元ネタはググってみよう)上のインポート文や、main()関数を呼び出しているところは、今回詳しくは解説しません。main()関数の上のほうに3行くらいの初期設定があって、その下にwhilleの繰り返し文がありますね。
ここのwhileこそ,メインループという、ゲームを実行する上で超絶重要な繰り返しです。このメインループが終わるとゲームが終了してしまいますし、メインループがうまく動かないと、ゲームの色んな所がおかしくなってしまいます。
では、まずメインループ前の3行を見てから、その後でメインループの中を見ていきましょう。
メインループ前の3行(初期化、スクリーンサイズの設定、タイトルの設定)
1行づつ見ていきましょう。
初期化
pygame.init()
ゲームの初期化をしています。みなさんはゲームセンターでゲームをしたことはありますか?そのときに、前にプレイした人のデータとかが無理やり引き継がれたら、いやですよね。この一行は、必要のないデータを引き継がないようにする機能があると考えてください。(初期化といいます。)
スクリーンサイズの設定
screen = pygame.display.set_mode((400, 300))
ここでは、画面のサイズを設定しています。ここで、変数screenに、画面の上方が一つ追加されました。このあと、画面の色を変えたり、ボタンを追加したりするときに、このscreenという変数はめちゃくちゃ使うことになります。
ゲームの途中で画面のサイズを変えることなんてそうそうないと思うので、「こういう書き方をするんだな」程度に思ってくれればいいですが、一つだけ注目してほしいのは、set_mode()関数に、引数として、(400,300)が与えられてます。これは正確には「タプル型」という名前のデータで、400は横の長さ、300は縦の長さを表しているのですが、pygameではこのような、セットになっている数字データを()で囲って、一つのデータとして扱います。なので、()の中に()がありますよね。これは、ここ以外でもよく使われる書き方なので、覚えておくといいです。
タイトルの設定
pygame.display.set_caption("クソゲー")
「クソゲー」というタイトルを、ゲーム画面上部に表示します。こういうことです↓
以上がメインループ前の3行の解説でした。では、メインループの解説に入ります。
メインループ(背景色の設定、画面の更新、終了処理)
では、最初の行から。
背景色の設定
screen.fill((0, 0, 0))
先ほどと同じく、タプル型で引数が渡されているので、()が二重になっています。
さて、この3つの数字は何でしょう?
これは、色を表すRGBという数字の組み合わせです。それぞれ
R-RED(赤)
G-Green(緑)
B-Blue(青)
の色を表していて、0から255の間の数字で、それぞれの色がどれだけ強いかを表し、その組み合わせで色を決めています。絵の具を混ぜ合わあせて、どの絵の具をどのくらい混ぜるか、みたいな漢字です。RGBについての詳しい解説はこの記事とかがわかりやすいと思います。
もう一つ。覚えておいてほしいのは、ここで背景色を設定した上に、ボタンや画像などのパーツを置いていくわけですが、このscreen.fill()は、画面にペンキのぶちまけるイメージで、下に何があっても全部塗りつぶしてしまいます。なので、しっかり順番を考えないと
①ボタンを表示
②screen.fill()をする
③あれ?ボタンがない!
みたいなことが起こる可能性があります。ので、注意が必要です。
画面の更新
pygame.display.update()
背景の色を設定したので、その上にボタンを置いたり、線を引いたり、画像をおいたりするわけですが、それらの変更を、いっぺんに反映させるのがこのupdate()関数です。どういうことかというと。。。
例えば、先程のscreen.fill()のところで、赤色を指定して、わざとupdate()関数をコメントアウトして無効化してみましょう。
import pygame
from pygame.locals import *
import sys
def main():
pygame.init() #初期化
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("kusoge-")
while True:
#赤(255,0,0)
screen.fill((255, 0, 0))
# pygame.display.update()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()
あれ、赤くしたはずなのに、真っ黒のままですね? update関数をもとに戻すと、しっかり赤くなってるはずです。
そう、screen.fill()を始めとするコードは、「これからこういう変更をしますよ!」という内容を追加しているだけで、その場で変更しているわけではないんです。update関数は1フレーム(アニメでいいう絵一枚)ごとに実行されるので、背景色を変えるとか、ボタンを設置するとかの変更を、1フレームごとにまとめて実行します。
終了処理
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
for文で繰り返していますね。何を何回繰り返しているかですが、ざっくりいうと、
・pygame.event.get()という配列(リストのようなもの)の要素を繰り返している。その際、各要素にeventという名前をつけている。
・eventの中のtypeとう情報がQUIT(正確にはpygame.locals.QUIT)となっていたとき,pygame.quit()とsys.exit()でアプリを終了する。
てなかんじです。来週ちょっとこの部分を深掘りしていくので、お楽しみに。
宿題
↑でもいった通り、pygameはpaizaのサイトでは動かせませんので、宿題は、今までの復習になります。
次の算数の問題を、pythonでかいけつしてみましょう。
リッキー先生は毎日晩ごはんを自分で作ってます。料理のジャンルで、「昨日は和食だったから、今日は中華にしよう」みたいに、変えたりしています。
dinner_listという変数に、一週間の料理のジャンルが、リスト形式で入っています。ジャンルは「和」「洋」「中」の3種類のみとします。リストは、こんな感じです。
dinner_list = ["和", "中", "洋", "洋", "中", "和", "和"]
このリストの中に、和・洋・中がそれぞれ何回入っているかを、繰り返しを使って数え、結果を次のように出力して欲しいです。
和:3
洋:2
中:2
ーーー
paizaのサイトで実行してみましょう。また、一度できたら、リストの中身を変えても大丈夫か確認してみましょう。
できた場合や、どうしてもわからない場合は、ここにサンプルコードがあるので、チェックしてね。