福岡人データサイエンティストの部屋

データサイエンスを極めるため、日々の学習を綴っています。

【PyGame】円(念)を動かしてみた【Python】



こんにちは!こーたろーです。


そう、皆さんご存知の通りHunter×Hunterの冨樫先生が頑張っておられます。


私も頑張らねば!と日々感じているところです。


念はやはり基礎修行が重要になってきます。


そこで、今回はPyGameのディスプレイ内に、円(念)を生成し、キー操作で動かしていきます!


それでは早速まいりましょう!


ライブラリのインポート



ライブラリは、sysとpygameを使っていきます。


キー操作で使うものは、別途インポートしておくと、取扱い易くなります。

import sys
import pygame
from pygame.locals import QUIT, KEYDOWN, K_ESCAPE, K_LEFT, K_RIGHT, K_UP, K_DOWN


ディスプレイの設定と各種パラメータの設定



まずは、PyGameのディスプレイを設定していきます。


wとhは、画面の幅と高さになります。今回も3:4で設定しています。


その後、pygameを初期化して、ディスプレイをセットします。


set_captionで、ディスプレイの名前をセットします。


get_surface()をつかって、ディスプレイ背景のインスタンスを作成しておきましょう。

w = 800
h = 600

pygame.init()
pygame.display.set_mode((w, h))
pygame.display.set_caption("moving circle")
surface = pygame.display.get_surface()

x = 400
y = 300
dx = 0
dy = 0
r = 8



次に、動かす円の初期設定を行っていきます。


x、yは、の初期位置の座標になります。ディスプレイサイズに合わせて設定してください。今回は、中心からのスタートです。


dx、dyは、1フレーム当たりの移動距離になります。こちらの初期値は0にしておきます。キー入力があったときにこのdx、dyを変化させて移動させていきます。


rは、円の半径です。

While文によるディスプレイの連続表示



以降のコードは、全てWhile文の中で動作させます。


説明のため、コードを分けますが、インデントなどに気を付けて行ってください。


while文では、いつもの通り、くり返し処理の状態がTrueである場合は連続で処理していきます。


pygame.display.update()で画面情報をアップデート掛けますが、そのまま処理をしてしまうと、読み込み回数が多すぎてコンピュータのリソースを使いすぎてしまします。


そこで、pygame.time.delay(100)を使って、1フレーム当たりのアップデート間隔を制御します。引数の100は、100ミリ秒を意味します。


surface.fillで、背景に色を付けます。引数はRGBのタプルで記述します。


while True:
    pygame.display.update()
    pygame.time.delay(100)
    surface.fill((50, 50, 50))

    pygame.draw.circle(surface, ( 0, 200, 0), (x, y), r*2)



今回の目玉である円(念)を、書いていきます。pygame.draw.circleのメソッドを使って、色をRGBのタプルで指定し、また中心座標x,yもタプルで指定。最後に円のサイズ(直径)を定義します。

キー入力などイベント情報の取り込み



while文のなかで、for ループを記述していきます。


pygame.event.get()でイベント入力を実行を捉えて、イベント発生時にforループ内の処理を実行していきます。


まずは、このファイルをpyファイルとしてスプリプとから実行する場合に、スクリプト上で「QUIT」が実行されるというイベントについてです。

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()



この場合、pygameを終了し、sysの方も終了させます。

指定したキー入力があった場合の処理



今回指定するキーは、ESCキー、上、下、左、右の5つのキーになります。


これらのキーはKEYDOWNというイベントタイプになるため、KEYDOWNが実行された場合のif文を記載します。


その中で、該当する指定キーの処理を記載します。


ESCキーが入力された場合は、QUIT実行時と同様に、Pygame並びにsysを終了します。


十字キーが押された場合は、その方向へ円を動かすため、dxやdyの値に変化量を与えます。

        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()

            if event.key == K_LEFT:
                dx = -r
                dy = 0

            if event.key == K_RIGHT:
                dx = r
                dy = 0

            if event.key == K_UP:
                dx = 0
                dy = -r

            if event.key == K_DOWN:
                dx = 0
                dy = r

    x += dx
    y += dy



今回は、変化量に対してrの数値を与えていますが、この値を大きくすれば見かけ上早く移動しますし、小さくすれば遅く移動します。


最後に、円の座標である(x、y)に移動距離を加えてあげれば、フレームが更新されるごとに移動していくようになります。

ディスプレイの範囲を考慮する



この円の動きですが、このままだと、円の座標がディスプレイの範囲を超える可能性が出てきます。


そのため、画面端まで円が移動した時の処理を加えていきます。

    if x < r:
        dx *= -1
    if x > w:
        dx *= -1
    if y < r:
        dy *= -1
    if y > h:
        dy *= -1



各座標の、x、yに対して、ディスプレイのサイズより大きかったり、小さかったりした場合の条件を付加します。


それから、その条件にマッチした時は、移動方向を反転させる処理を加えます。


これによって、画面端へ到達した時には円が折り返すようになります。


実際にやってみた画像がこちらになります。


初期位置





移動中





静止画では何もわからないですね・・・汗


今度からはできるだけGIF動画にしてアップしたいと思います!


データ容量があるので、さすがにproにアップグレードしないとダメかな?


ではでは。


Pythonでつくる ゲーム開発 入門講座 実践編