この記事は、岩手県八幡平市のプログラミング教室「アクセルキャンプ」の公開教材です。
アクセルキャンプ(フリースペースプラウド)のリンク
教材の作成依頼等も承っております。ご意見等は、リンク先の問い合わせ欄からお願いします。
教材の転用・利用等は自由です。
寒くなってきたぜ!
風邪ひかないようにね!先生は天才なので、いつ風邪をひくかいつもひやひやしています。それに加えてイケメンなので、気が気じゃありません。
PygameでRPG風な画面を作ってみよう。
今の君たちに言っても全然伝わらない可能性があるけど、先生の時代はファミコンからスーパーファミコンに切り替わったり、初代プレイステーションがでて、「すげー!CGやべえ!!ゲームすげー!!!」てなった時代です。中学生になってFF10が出たときなんかもう、グラフィックがきれいすぎてぶったまげたもんです。今のゲームと比べると全然ですが、なんていうか、そういう感動が今のゲームにはない気がします。
今日みんなに作ってもらいたいのは、こういう感じの、いわゆる「ドット絵」風な、1980年代くらいのゲーム「風な」画面です。
これに、今後動きを付けたり、戦闘の描写を付けたりしていきます。
「なにこれ、だっさ」とか言ったそこの君!廊下に立ってなさい!!ドット絵のすばらしさについて3時間お説教の刑です!
冗談ですが。やっていくうちに「ドット絵のゲームでさえこんなだから、実際のゲーム作ってる人ってすごいんだなぁ」みたいな感覚はもってほしいです.
①まずは呪文から
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()
これ、いちいち打つの超めんどいですよね?
こういうとき、いつも授業で使ってるpycharmでは、ライブテンプレートという機能が使えます。
詳しくはこことかを見るといいと思いますが、pygameと入力しただけで、この初期状態のコードがまるっと出てくるわけです。
ではまず、スライムくんの画像を表示しましょう。
ここで、pythonプロジェクトのディレクトリについて、話しておく必要があります。
②フォルダの使い方:
pycharmの左側を見てみましょう。こんなのが表示されています。
ここには、作成したプロジェクトの中にどんなパーツが入っているかが書いてあります。
ゲームを作るには、ソースコードだけではできませんよね。スライムや勇者の画像、音楽などのパーツをおいておき、それらを使いたいときに使えるように、整理しておいておくのがいいですね。例えば、画像のファイルが音楽のファイルと一緒になっていたら、それをソースコードから使いたいときに、ちょっと面倒ですよね。
ソースコードは、ゲームを作るのに必要なパーツの一つでしかありません。一般的に「フォルダ」と言われるものが、プログラミング的には「ディレクトリ」と呼ばれたりします。
では、プロジェクトディレクトリ(一番大きいでディレクトリ)の下にimgディレクトリを作って、その中にスライムの画像を入れてみましょう。画像のファイル名は「slyme.png」という名前にしましょう。すると、こんな感じの後世になります。
slyme.pngはどこ?
ここで、main.pyの気持ちになって、slyme.pngを探してみてください。
main.pyさんの住んでいる部屋には、imgという小部屋があります。そのなかに、slyme.pngさんがいます。すると、
「imgの部屋のなかのslyme.pngさん」というふうに指定すると、会いたい人(ほしいデータ)に出会えそうですね。そのことを意識したうえで、次のコードを、メインループの前に追加してみましょう。
import pygame
from pygame.locals import *
import sys
def main():
pygame.init() # Pygameの初期化
screen = pygame.display.set_mode((800,600)) # 400 x 300の大きさの画面を作る
pygame.display.set_caption("いけめんがつくったげえむ") # 画面上部に表示するタイトルを設定
#追加部分
slyme_image = pygame.image.load("image/slyme.png")
# 以下省略
slyme.pngという画像ファイルの情報を、slyme_imageという変数に入れます。loadって、ゲームで見たことないですかね?「now loading(ロード中)」とかってやつです。load=読み込み 的な意味です。これで画像をいつでも使える準備ができました。
ここの、"image/slyme.png"というところに注目です。ここの / は、「~ディレクトリのなかの~」というのを表しています。たとえば "A / B / C" となると、「AディレクトリのなかのBディレクトリの中のC」となります。
画像の表示:screen.blit(画像, 座標)
では、この画像を表示してみましょう。
画像などのデータを表示するには。次のメソッドを使います。
screen.blit(表示したい画像,(表示したい座標))
ここでちょっと気をつけなくちゃいけないのが、表示したい座標についてです。ここでは、画像の中心ではなく、左上をこの座標に合わせることになるので、狙った場所に画像を出すには、その画像の縦幅・横幅の半分だけずらして表示する必要があります。このsylme.pngはたて・よこともに400のサイズになっていますので、どまんなかやや上に表示してRPGっぽく表示するには、こんな感じになります。
screen.blit(slyme_image, (400-(400 / 2), 0))
これを、メインループ内に追加します。
※ちなみに、画像の縦横の長さを取得する方法もあるのですが、ややこしくなってしまうのでここでは省略します。
では、画面下部に文字を表示するための枠線を描画しましょう。
長方形の枠線を描画するには、以下のメソッドを使います。
pygame.draw.rect(screen,(255, 255, 255),Rect(20, 400, 760, 180), 10)
255が三つ並んでる時点で、「お!これ絶対RGBじゃん!白い枠線じゃん!」みたいになった人は、ちゃんと勉強してますね!恐ろしい子!
このpygame.draw.rect()メソッドには4つの引数があります。
①どの画面に出力するか・・・この場合は1つしかないscreenですね
②枠線のRGB
③Rect型のオブジェクト
④枠線の太さ
この中で一番イミフなのは、③番じゃないでしょうか?Rectは、英語で長方形を意味するRectanfular(レクタンギュラー)の略です。この中にさらに4つの引数がありますが、それぞれ
①左上の角のx座標
②左上の角のy座標
③横(x方向)の長さ
④縦(y方向)の長さ
となっています。
※(長さはそれぞれ自分で計算しなくてもいいのですが、コードが長くなるために事前に計算してあります。)
実行すると、こんな感じで枠線が出ます。
あとは、文字だけですね。
③文字の表示方法
文字の表示には、少し特殊な作業が必要になります。
まず、ひとくちに文字といっても、いろんな文字がありますね?きれいな字でピシッと書いた書道のような字や、パソコンで表示される機会みたいな字、お化け屋敷の看板みたいな字がありますよね。それらの文字の種類のことを「フォント」といいます。フォント次第で、ゲームやチラシなどの雰囲気がまるで変わってきます。
フォントの選択
今回使うのは、DragonQuestFCというフォントです。フォントファイルを調べてみて、気づいた人がいるかもしれません、そう、漢字に対応していないのです。昔のゲームの画像で、
「リッキーに、300の 攻撃!」としたいところを
「りっきーに 300の こうげき!」などとしているのを、見たことないですか?昔はゲームのハード(ファミコンとかプレステとかの、ゲームを動かすための機械)の容量がとても小さくて、文字をきれいにするために容量を割けなかったんです。そういうのにしっかり容量を割けるようになってきたのって、プレステ2くらいかなぁ。今回はその雰囲気に慣れてもらうために、わざとこのフォントを選びました。
フォントはここからダウンロードできるので、imgフォルダと同じように、fontフォルダをプロジェクトフォルダの下に作成して、その中に入れましょう。
では、このフォントを使って、文字を表示していきます。
文字を表示するには、
①使うフォントを決める
②フォントから作成したい文字列を画像に変換する
③画像を表示する
という3つのステップを踏みます。「リッキー」という文字を表示したい場合は、リッキーという文字の「画像」を作成して、それを表示するんですね。
フォントを決めるには、「どこのフォルダにある、なんていうフォントを使うか」を指定してあげる必要があります。
先ほどのファイルの指定方法を思い出してみて下さい。
font = pygame.font.Font("font/DragonQuestFC.ttf", 30)
これで、第一引数にフォントファイルの場所、第二引数に文字の大きさを指定します。今のところフォントはこの一種類しか使わないですが、メインループの直前に書いてあげましょう。
文字の「画像」を作る
次に、フォントの情報と、表示したい文字列の情報を与えて、それらを一枚の画像としてtextという変数に入れましょう。
text = font.render("りっきーが あらわれた!", True, (255, 255, 255))
第一引数では、表示したい文字列
第二引数は、アンチエイリアスの設定
第三引数は、文字のRGB
アンチエイリアスは、「文字をきれいに表示するための機能」とだけ言っておきます。とりあえずtrueにしとけばOKです。
画像を出力(表示)する 475
変数名がtextとなってるので混乱するかもしれませんが、これは画像データとして考えましょう。画像を出力するので、↑のスライムの画像の出力を参考にすればイチコロです。
screen.blit(text, (40, 420))
pygame に慣れていないと、これらの処理をどこに書いたらいいか、最初は難しいと思いますが、
「用意しておくデータはメインループの前」
「ゲーム中に行いたい処理はメインループの中」
と考えればいいです。
コード全体はこんな感じです。
import pygame
from pygame.locals import *
import sys
def main():
pygame.init() # Pygameの初期化
screen = pygame.display.set_mode((800,600)) # 400 x 300の大きさの画面を作る
pygame.display.set_caption("いけめんがつくったげえむ") # 画面上部に表示するタイトルを設定
slyme_image = pygame.image.load("image/slyme.png")
font = pygame.font.Font("font/DragonQuestFC.ttf", 30)
while (1):
screen.fill((0,0,0)) # 画面を黒色に塗りつぶし
screen.blit(slyme_image, (400 - (400 / 2), 0))
pygame.draw.rect(screen,(255, 255, 255), Rect(20, 400, 760, 180), 10)
text = font.render("りっきーが あらわれた!", True, (255, 255, 255))
screen.blit(text, (40, 420))
pygame.display.update() # 画面を更新
# イベント処理
for event in pygame.event.get():
if event.type == QUIT: # 閉じるボタンが押されたら終了
pygame.quit() # Pygameの終了(画面閉じられる)
sys.exit()
if __name__ == "__main__":
main()
おまけとして、座標を計算する部分で、自分で計算しないでプログラムで計算するようにすると、こんなかんじになります。
import pygame
from pygame.locals import *
import sys
def main():
pygame.init() # Pygameの初期化
screen = pygame.display.set_mode((800,600)) # 400 x 300の大きさの画面を作る
pygame.display.set_caption("いけめんがつくったげえむ") # 画面上部に表示するタイトルを設定
rect_x = 20 #長方形左上のx座標
rect_y = 400 #長方形左上のx座標
rect_width = 800 - (rect_x * 2) #長方形の幅
rect_height = 600 - (rect_y + 20) #長方形の高さ
slyme_image = pygame.image.load("image/slyme.png")
font = pygame.font.Font("font/DragonQuestFC.ttf", 30)
while (1):
screen.fill((0,0,0)) # 画面を黒色に塗りつぶし
screen.blit(slyme_image, (400 - (400 / 2), 0))
pygame.draw.rect(screen,(255, 255, 255), Rect(rect_x, rect_y, rect_width, rect_heithg), 10)
text = font.render("りっきーが あらわれた!", True, (255, 255, 255))
screen.blit(text, (40, 420))
pygame.display.update() # 画面を更新
# イベント処理
for event in pygame.event.get():
if event.type == QUIT: # 閉じるボタンが押されたら終了
pygame.quit() # Pygameの終了(画面閉じられる)
sys.exit()
if __name__ == "__main__":
main()
今週は課題なしです!どんなゲームになるか楽しみにしながら、また来週!