1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PygameでRPG制作 ーーそれっぽい画面を作ってみよう

Posted at

この記事は、岩手県八幡平市のプログラミング教室「アクセルキャンプ」の公開教材です。
アクセルキャンプ(フリースペースプラウド)のリンク
教材の作成依頼等も承っております。ご意見等は、リンク先の問い合わせ欄からお願いします。
教材の転用・利用等は自由です。

寒くなってきたぜ!  

風邪ひかないようにね!先生は天才なので、いつ風邪をひくかいつもひやひやしています。それに加えてイケメンなので、気が気じゃありません。  

PygameでRPG風な画面を作ってみよう。

今の君たちに言っても全然伝わらない可能性があるけど、先生の時代はファミコンからスーパーファミコンに切り替わったり、初代プレイステーションがでて、「すげー!CGやべえ!!ゲームすげー!!!」てなった時代です。中学生になってFF10が出たときなんかもう、グラフィックがきれいすぎてぶったまげたもんです。今のゲームと比べると全然ですが、なんていうか、そういう感動が今のゲームにはない気がします。  

今日みんなに作ってもらいたいのは、こういう感じの、いわゆる「ドット絵」風な、1980年代くらいのゲーム「風な」画面です。
  
これに、今後動きを付けたり、戦闘の描写を付けたりしていきます。  
image.png

「なにこれ、だっさ」とか言ったそこの君!廊下に立ってなさい!!ドット絵のすばらしさについて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の左側を見てみましょう。こんなのが表示されています。
image.png

ここには、作成したプロジェクトの中にどんなパーツが入っているかが書いてあります。
ゲームを作るには、ソースコードだけではできませんよね。スライムや勇者の画像、音楽などのパーツをおいておき、それらを使いたいときに使えるように、整理しておいておくのがいいですね。例えば、画像のファイルが音楽のファイルと一緒になっていたら、それをソースコードから使いたいときに、ちょっと面倒ですよね。

ソースコードは、ゲームを作るのに必要なパーツの一つでしかありません。一般的に「フォルダ」と言われるものが、プログラミング的には「ディレクトリ」と呼ばれたりします。
では、プロジェクトディレクトリ(一番大きいでディレクトリ)の下にimgディレクトリを作って、その中にスライムの画像を入れてみましょう。画像のファイル名は「slyme.png」という名前にしましょう。すると、こんな感じの後世になります。

slyme.pngはどこ?

ここで、main.pyの気持ちになって、slyme.pngを探してみてください。
image.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))

これを、メインループ内に追加します。
※ちなみに、画像の縦横の長さを取得する方法もあるのですが、ややこしくなってしまうのでここでは省略します。
img_4.png

では、画面下部に文字を表示するための枠線を描画しましょう。
長方形の枠線を描画するには、以下のメソッドを使います。

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()

今週は課題なしです!どんなゲームになるか楽しみにしながら、また来週!

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?