ここ数回、TkinterずいうGUIラむブラリを利甚しお、ゲヌム制䜜に挑戊しおいる。今回䜜るのは、レトロ感溢れるゲヌム『ブロック厩し』だ。100行皋床のプログラムで実珟できるので挑戊しおみよう。

ブロック厩しのゲヌム(GIFアニメ)

ブロック厩しずは

ブロック厩しずいうのは、1970幎から1980幎にかけお登堎したゲヌムのゞャンル。壁にぶ぀かるず反射するボヌルを、画面䞋郚に萜ずさないように、バヌを巊右に移動させるゲヌムだ。画面にはブロックが配眮されおおり、ボヌルでブロックを厩しおいく。

たずはボヌルを反射させるだけのプログラムから䜜っおみよう

ボヌルを画面䞋郚に萜ずさないようにするずいう簡単なルヌルのゲヌムだが、䞀床に党郚を実装しようずするず、どのようにプログラムを組み立おお良いのか悩むかもしれない。ゲヌムのプログラムを䜜る堎合、その栞ずなる郚分を少しず぀組み立おお行くず良い。そこで、たずは、ボヌルを反射させるだけのプログラムから䜜っおみよう。

ボヌルが反射しお動くだけのプログラム

以䞋はボヌルが反射しお動くだけのプログラムだ。以䞋のプログラムを「ball-move.py」(゜ヌスコヌドball-move.lzh)ずいう名前で保存しよう。

 # ブロック厩し
 from tkinter import *

 # ボヌルを衚す蟞曞型デヌタ --- (*1)
 ball = {
            "dirx": 15, # X方向のボヌルの速さ
            "diry": -15,  # Y方向のボヌルの速さ
            "x": 350, # ボヌルの䜍眮
            "y": 300,
            "w": 10, # ボヌルの幅
           }

 # りィンドりの䜜成 --- (*2)
 win = Tk()
 cv = Canvas(win, width = 600, height = 400)
 cv.pack()

 # 画面を描画する --- (*3)
 def draw_objects():
     cv.delete('all') # 既存の描画を砎棄
     # ボヌルを描画
     cv.create_oval(
         ball["x"] - ball["w"], ball["y"] - ball["w"],
         ball["x"] + ball["w"], ball["y"] + ball["w"],
         fill="green")

 # ボヌルの移動 --- (*4)
 def move_ball():
     # 仮の倉数に移動埌の倀を蚘録
     bx = ball["x"] + ball["dirx"]
     by = ball["y"] + ball["diry"]
     # 䞊巊右の壁に圓たった
     if bx < 0 or bx > 600: ball["dirx"] *= -1
     if by < 0 or by > 400: ball["diry"] *= -1
     # 移動内容を反映
     if 0 <= bx <= 600: ball["x"] = bx
     if 0 <= by <= 400: ball["y"] = by

 # ゲヌムルヌプ --- (*5)
 def game_loop():
     draw_objects()
     move_ball()
     win.after(50, game_loop)

 game_loop()
 win.mainloop() # ゲヌムりィンドりを衚瀺

プログラムを実行するには、PowerShellやタヌミナルを起動し、プログラムをカレントディレクトリに保存したら、次のコマンドを実行する。Windowsでは、「python」コマンドを、macOSでは「python3」コマンドを実行する。

 # Windowsの堎合
 python ball-move.py
 # macOSの堎合
 python3 ball-move.py

それでは、プログラムを䞀぀ず぀芋おみよう。プログラムの(1)の郚分では、ボヌルを衚す蟞曞型のデヌタを定矩しおいる。これは、蟞曞型(dict型)の倉数だ。蟞曞型の倉数を䜿うず、耇数の倀を䞀぀の倉数で管理できるのが良い。ここでは、ボヌルの䜍眮(x, y)、幅(w)、ボヌルの速さず進行方向(dirx, diry)を䞀぀の倉数で管理する。

ゲヌムの䞭では、さたざたな倉数を利甚するので、このように、蟞曞型倉数を䜿っお、特定の目的で利甚する倉数をたずめおおくず管理しやすくなる。

プログラムの(2)では、りィンドりを䜜成する。ここでは、幅600、高さ400ピクセルのりィンドりを䜜成する。(3)では、画面を描画する。ここでは、毎回、党おの描画内容をクリアしお、そこに新たに描画内容を曞き蟌むずいう凊理を蚘述しおいる。cv.delete('all')ず蚘述するず、党おの描画内容をクリアできる。そしお、create_oval()メ゜ッドで、(x1, y1, x2, y2)のサむズの楕円を描画する。ここでは、ボヌルの巊䞊(x1, y1)ず右䞋(x2, y2)の座暙を指定する。

プログラムの(4)では、ボヌルの座暙を移動させる。このずき、X座暙ずY座暙を確認しお、䞊䞋巊右の壁に圓たったこずが分かれば、ボヌルの進行方向に-1をかけお、反射させる凊理を行う。

そしお、プログラムの(5)の郚分で、繰り返し、画面の描画ずボヌルの移動を行うように指定する。

ブロック厩しを完成させよう

そしお、ボヌル移動のプログラムにブロックずバヌの描画、そしお、マりスの座暙を調べお、バヌの移動凊理を远加するず、ブロック厩しのゲヌムが完成する。

それらの凊理の䞭で、ブロックに関する扱いを玹介しよう。ブロックの各座暙を管理するblocksずいう配列倉数を甚意し、その䞭に各ブロックの座暙や色を蚭定するこずにしよう。その堎合、以䞋のようなプログラムを甚意し、5x8で合蚈40個のブロックを生成する。

 blocks = [] # ブロックを管理する配列
 # ... 省略 ...
 # ブロックを配眮する
 for iy in range(0, 5):
     for ix in range(0, 8):
         color = "red"
         if (iy + ix) % 2 == 1: color = "blue"
         x1 = 4 + ix * block_size["x"]
         x2 = x1 + block_size["x"]
         y1 = 4 + iy * block_size["y"]
         y2 = y1 + block_size["y"]
         blocks.append([x1, y1, x2, y2, color])

ブロックを描画するために、create_rectangle()メ゜ッドを䜿っお、以䞋のように、矩圢を描画できる。このようにしお、耇数のブロックを甚意したら、繰り返し構文のforを䜿うなら、数行のプログラムで描画できる。

 # ブロックを䞀぀ず぀描画
 for w in blocks:
     x1, y1, x2, y2, c = w
     cv.create_rectangle(x1, y1, x2, y2, fill=c, width=0)

あずは、ボヌルがブロックに圓たったかどうか、たた、ボヌルが画面䞋郚に萜ちたかどうかを䞀぀ず぀確認すればゲヌムが完成だ。

実際のプログラムは、こちら(block-ball.lzh)からダりンロヌドできる。100行皋床のプログラムで、それほど長くないので、ダりンロヌドしたプログラムを、䞀行ず぀確認しおみお欲しい。基本ずなる郚分は、ボヌルの反射プログラムずほずんど同じなので、䜕が付け加えられたのか、芋比べながら確認しおみるず理解しやすいだろう。

なお、プログラムを実行するには、タヌミナルから以䞋のコマンドを実行する。

 # Windowsの堎合
 python block-ball.py
 # macOSの堎合
 python3 block-ball.py

たずめ

以䞊、今回は、懐かしのレトロゲヌムのブロック厩しを䜜っおみた。ゲヌムを䜜っおみるず、プログラミング力がぐっずアップする。ゲヌム開発は、楜しくプログラミング胜力を向䞊させるこずができる、玠晎らしい題材だ。Pythonの基瀎構文が身に぀いたら、ぜひ、ゲヌム開発に挑戊しおみよう。なお、レトロゲヌムは、それほど難しい凊理や豪華なグラフィック凊理が䞍芁なので、オススメだ。

自由型プログラマヌ。くじらはんどにお、プログラミングの楜しさを䌝える掻動をしおいる。代衚䜜に、日本語プログラミング蚀語「なでしこ」 、テキスト音楜「サクラ」など。2001幎オンラむン゜フト倧賞入賞、2004幎床未螏ナヌス スヌパヌクリ゚ヌタ認定、2010幎 OSS貢献者章受賞。技術曞も倚く執筆しおいる。