【Kivy】Pythonで落ちもの系ゲーム開発(テトリス風)Part5
こんにちは、にわこまです。
今回は、kivyでアプリケーションを開発していくにあたって、導入のようなことをしていきます。具体的には、元となるウィンドウの作成とタイトル画面の作成とプレイ画面の一部の作成を行います。
誤字脱字など何かございましたらご連絡お願いいたします。
スポンサードサーチ
落ちもの系ゲーム開発Part5
Part1で紹介した、今回作成するゲームの概要を改めて説明します。
今回開発するゲームは、テトリスに似ています。テトリスのルールは、以下のような7つのミノと呼ばれるブロックを積み重ねていき、横一列をミノで満たしたらその行が消され得点します。
作るゲームの概要
テトリスではミノが消される条件は、「横一列にミノがいっぱいになったら」ですが、今回開発するゲームでは「隣り合うブロックが10になったら」消されるというものです。
ゆえに、ブロック1つひとつには1~9までの数字が代入されます。
以下のような場合、オレンジ色の線で囲まれたブロックが消されます。
さらに、ブロックが消されたら、その列上で消されたブロックの座標より高い位置にあるブロックは消されたブロックの数だけ下がります。(左図から右図のようになります。)
開発環境
OS : Windows10
Python Version : 3.7
Kivy Version : 1.11.1
Numpy Version : 1.18.1
開発手順
1.全てのミノに共通する関数を作成します。(共通の初期値、動作、関数)
2.7種類のミノ(Iミノ、JミノLミノ、Oミノ、Sミノ、Tミノ、Zミノ)を作成します。
3.ブロックの削除関係
4.kivyを使ってアプリケーションを開発します。
1、2、3は4のための準備であるため、簡単です。4は1番ボリュームがあります。
今回は、
元となるウィンドウの作成とタイトル画面の作成とプレイ画面の一部を作成します。
ファイル作成
アプリケーションのファイル(tenplusapp.py)とkvファイル(tenplusapp.py)を作成します。アプリケーションファイルでは、たくさんのインポートを行うため、その説明を行います。
以下は、アプリケーションファイルに記述するコードです。tenplusapp.pyファイルを作成し、記述します。
import kivy
kivy.require('1.11.1')
import tenplus as tenplus
from tenplus import Imino, Jmino, Lmino, Omino, Smino, Tmino, Zmino
import random
import numpy as np
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.graphics import Color, Line, Rectangle
from kivy.properties import ObjectProperty, NumericProperty
from kivy.core.window import Window
Window.size = (910, 720)
from kivy.lang import Builder
Builder.load_file('tenplusapp.kv')
class TenplusApp(App):
def build(self):
return
if __name__ == '__main__':
TenplusApp().run()
以下は、kvファイルに記述するコードです。tenplusapp.kvファイルを作成し、記述します。
# -*- coding: utf-8 -*-
コードの解説(Pythonファイル)
1行目の「import kivy」は、今回使用するGUIライブラリをインポートしています。
2行目の「kivy.require(‘1.11.1’)」は、今回使用するGUIライブラリのバージョンを指定しています。基本的には必要ありませんが、私は心配性であるため記述しています。
4行目の「import tenplus」は、Part1からPart4で作成したtenplus.pyファイルをインポートしています。これによって、tenplus.pyファイル内のグローバル変数や関数を使うことができます。
5行目の「from tenplus import Imino, Jmino, Lmino, Omino, Smino, Tmino, Zmino」は、tenplus.pyファイルからミノクラスをインポートしています。これによって、ミノクラスを使うことができます。
6行目の「import random」は、ランダムな数字を取得するときに使用するため、インポートしています。
7行目の「import numpy as np」は、配列の操作を行うときに使用するするため、インポートしています。
9行目の「from kivy.app import App」は、アプリケーションを実行させるために必要なためインポートしています。
10行目の「from kivy.clock import Clock」は、時間に関係するkivyのライブラリをインポートしています。ミノを一定間隔で落とすために使用します。
11行目の「from kivy.uix.floatlayout import FloatLayout」は、タイトル画面などのレイアウトに使用するためにインポートしています。
12行目の「from kivy.uix.widget import Widget」は、ミノを表現するときに使用するためインポートしています。次パート以降で使用します。
13行目の「from kivy.uix.label import Label」は、ブロックに数字を代入するために使用するためインポートしています。
14行目の「from kivy.graphics import Color, Line, Rectangle」は、ミノの色や盤面の縦横線などを表現するために使用するためインポートしています。
15行目の「from kivy.properties import ObjectProperty, NumericProperty」は、オブジェクトが変化したとき、または数値が変化したときにイベントを発生させるために使用するためインポートしています。
17行目の「from kivy.core.window import Window」は、ウィンドウサイズを指定するためにインポートしています。
18行目の「Window.size = (910, 720)」は、ウィンドウサイズを横910、縦720に設定しています。
20行目の「from kivy.lang import Builder」は、使用するkvファイルを指定するためインポートしています。
21行目の「Builder.load_file(‘tenplusapp.kv’)」は、使用するkvファイルを指定しています。
24行目から26行目の「TenplusApp」は、アプリケーションの基となるクラスです。kivyライブラリのAppを継承しています。
25行目の「build関数」は、アプリケーションを初期化し、ウィジェットを表示させるための関数です。
29、30行目は、アプリケーションを実際に実行しているコードです。kivyにおいて、アプリケーションを実行するにはこの方法しかありません。覚えるようにしましょう。
コードの解説(kvファイル)
1行目の「# -*- coding: utf-8 -*-」は、kvファイル内で使用する文字コードを指定しています。
実行結果
コマンドプロンプトを開き、ファイルを保存したフォルダまで移動します。移動したら以下のコードを入力し、実行します。
python tenplusapp.py
以下のような、真っ黒の画面が生成されます。
黒いウィンドウを確認したら、実行結果の確認は完了です。
スポンサードサーチ
元となるウィンドウの作成
タイトル画面やプレイ画面をウィジェットとして追加する、元のレイアウトを作成します。基本的には、このレイアウトにタイトル画面のレイアウトなどを追加したり、削除したりして画面の切り替えを行います。
以下は、元となるレイアウトのコードです。tenplusapp.pyに追記します。
# 上記省略
class RootWidget(FloatLayout):
pass
class TenplusApp(App):
def build(self):
root = RootWidget()
return root
if __name__ == '__main__':
TenplusApp().run()
以下は、元となるレイアウトを装飾するためのコードです。tenplusapp.kvに追記します。
# -*- coding: utf-8 -*-
<RootWidget>:
canvas.before:
Color:
rgba: [1, 1, 1, 1]
Rectangle:
pos: self.pos
size: self.size
コードの解説(Pythonファイル)
3行目の「RootWidgetクラス」は、元となるレイアウトを表しています。FloatLayoutを継承しています。
8行目の「root = RootWidget()」は、変数rootにRootWidgetクラスオブジェクトを代入しています。
9行目の「return root」は、8行目で作成したオブジェクトをウィンドウに表示させるため、変数rootを返却しています。
コードの解説(kvファイル)
2行目から8行目の「<RootWidget>」は、RootWidgetクラスを装飾するためのコードです。さらに言うと、背景を指定するためのコードです。
3行目の「canvas.before」は、一番後ろ側のキャンバスを指定しています。
4行目の「Color」は、色を指定するためのkivyライブラリのクラスです。
5行目の「rgba: [1, 1, 1, 1]」は、実際に白色を指定しています。左から赤、緑、青、透明度になります。また、パーセントで指定します。
6行目の「Rectangle」は、長方形の図形を指定するためのkivyライブラリのクラスです。
7行目の「pos: self.pos」は、表示位置を指定しています。RootWidgetの表示位置と同じ場所を原点としています。
8行目の「size: self.size」は、Rectangleのサイズを指定しています。RootWidgetのサイズを同じサイズを指定しています。
動作確認
コマンドプロンプトを開き、ファイルが保存されているフォルダまで移動します。移動したら以下のコマンドを入力し、実行します。
python tenplusapp.py
以下のような、真っ白の画面が表示されます。
真っ白な画面を確認したら、動作確認は完了です。
タイトル画面の作成
タイトル画面の作成を行います。それにともないプレイ画面の一部も作成します。
タイトル画面には、スタートボタンを設置します。そのスタートボタンを押したときに、プレイ画面に切り替わるようにするために、プレイ画面の一部も作成します。
以下は、タイトル画面とプレイ画面の一部を表すコードです。tenplusapp.pyに追記します。
# 上記省略
class PlayWidget(FloatLayout):
pass
class TitleWidget(FloatLayout):
pass
class RootWidget(FloatLayout):
def gotoTitle(self):
self.clear_widgets()
self.add_widget(TitleWidget())
def gotoPlayDisplay(self):
self.clear_widgets()
self.add_widget(PlayWidget())
pass
class TenplusApp(App):
def build(self):
root = RootWidget()
root.gotoTitle()
return root
if __name__ == '__main__':
TenplusApp().run()
以下は、タイトル画面とプレイ画面の一部を装飾するためのコードです。tenplusapp.kvに追記します。
# -*- coding: utf-8 -*-
<PlayWidget>:
canvas.before:
Color:
rgba: [1, 1, 1, 1]
Rectangle:
pos: self.pos
size: self.size
<TitleWidget>:
canvas.before:
Color:
rgba: [1, 1, 1, 1]
Rectangle:
pos: self.pos
size: self.size
Label:
bold: True
color: [0, 0, 0, 1]
font_size: 24
pos_hint: {"center_x":0.5, "center_y":0.75}
text: "Fallen games. (Tetris-like)"
Label:
bold: True
color: [0, 0, 0, 1]
font_size: 60
pos_hint: {"center_x":0.5, "center_y":0.65}
text: "10 Plus"
Button:
background_normal: ""
background_color: [0, 0, 0, 1]
color: [1, 1, 1, 1]
font_size: 36
pos_hint: {"center_x":0.5, "center_y":0.4}
size_hint: [None, None]
size: [200, 100]
text: "Start."
on_press: app.root.gotoPlayDisplay()
<RootWidget>:
canvas.before:
Color:
rgba: [1, 1, 1, 1]
Rectangle:
pos: self.pos
size: self.size
コードの解説(Pythonファイル)
3行目の「PlayWidgetクラス」は、プレイ画面を表現するクラスです。FloatLayoutを継承しています。このクラスには、後々盤面や操作系のボタンを追加していきます。
6行目の「TitleWidgetクラス」は、タイトル画面を表現するクラスです。FloatLayoutを継承しています。このクラスの中身は、kvファイルで表現しています。
10行目から12行目の「gotoTitle関数」は、タイトル画面に入れ替わらせる関数です。
11行目の「self.clear_widgets()」は、RootWidgetに追加されているウィジェットを全て削除しています。
12行目の「self.add_widget(TitleWidget())」は、RootWidgetにタイトル画面のクラスを追加しています。
13行目から15行目の「gotoPlayDisplay関数」は、プレイ画面に入れ替わらせる関数です。
14行目の「self.clear_widgets()」は、RootWidgetに追加されているウィジェットを全て削除しています。
15行目の「self.add_widget(PlayWidget())」は、RootWidgetにプレイ画面のクラスを追加しています。
21行目の「root.gotoTitle()」は、タイトル画面に入れ替わる関数を実行しています。
コードの解説(kvファイル)
2行目から8行目の「<PlayWidget>」は、プレイ画面の装飾を行うためのコードです。コードの中身は、RootWidgetの背景色を設定したときのコードをほぼ同じです。
3行目の「canvas.before」は、一番後ろ側のキャンバスを指定しています。
4行目の「Color」は、色を指定するためのkivyライブラリのクラスです。
5行目の「rgba: [1, 1, 1, 1]」は、実際に白色を指定しています。左から赤、緑、青、透明度になります。また、パーセントで指定します。
6行目の「Rectangle」は、長方形の図形を指定するためのkivyライブラリのクラスです。
7行目の「pos: self.pos」は、表示位置を指定しています。PlayWidgetの表示位置と同じ場所を原点としています。
8行目の「size: self.size」は、Rectangleのサイズを指定しています。PlayWidgetのサイズを同じサイズを指定しています。
10行目から38行目の「<TitleWidget>」は、タイトル画面の装飾を行うためのコードです。コードの中身は、RootWidgetの背景色を設定したときのコードをほぼ同じです。
11行目の「canvas.before」は、一番後ろ側のキャンバスを指定しています。
12行目の「Color」は、色を指定するためのkivyライブラリのクラスです。
13行目の「rgba: [1, 1, 1, 1]」は、実際に白色を指定しています。左から赤、緑、青、透明度になります。また、パーセントで指定します。
14行目の「Rectangle」は、長方形の図形を指定するためのkivyライブラリのクラスです。
15行目の「pos: self.pos」は、表示位置を指定しています。TitleWidgetの表示位置と同じ場所を原点としています。
16行目の「size: self.size」は、Rectangleのサイズを指定しています。TitleWidgetのサイズを同じサイズを指定しています。
17行目から22行目の「Label」は、TitleWidgetに後述する文字列を表示するためのkivyライブラリのクラスです。
18行目の「bold: True」は、太字にするための設定です。
19行目の「color: [0, 0, 0, 1]」は、文字列の色をrgbaで指定しています。今回指定した色は黒です。
20行目の「font_size: 24」は、フォントサイズを24に設定しています。
21行目の「pos_hint: {“center_x”:0.5, “center_y”:0.75}」は、ラベルの表示位置を設定しています。ラベルの横幅の中心が画面横幅の中心になるように、ラベルの縦幅の中心が画面縦幅の4分の3になるように設定しています。
22行目の「text: “Fallen games. (Tetris-like)”」は、ラベルに表示する文字列です。
23行目から28行目の「Label」は、後述する文字列を表示するためのkivyライブラリのクラスです。
24行目の「bold: True」は、太字にするための設定です。
25行目の「color: [0, 0, 0, 1]」は、文字列の色をrgbaで指定しています。今回指定した色は黒です。
26行目の「font_size: 60」は、フォントサイズを60に設定しています。
27行目の「pos_hint: {“center_x”:0.5, “center_y”:0.65}」は、ラベルの表示位置を設定しています。ラベルの横幅の中心が画面横幅の中心になるように、ラベルの縦幅の中心が画面縦幅の20分の13になるように設定しています。
28行目の「text: “10 Plus”」は、ラベルに表示する文字列です。
29行目から38行目の「Button」は、プレイ画面に入れ替わるためのボタンです。
30行目の「background_normal: “”」は、ボタンの背景色を設定するために必要なコードとなります。
31行目の「background_color: [0, 0, 0, 1]」は、背景色を設定しています。今回は、黒色です。
32行目の「color: [1, 1, 1, 1]」は、文字列の色を設定しています。今回は、白色です。つまり、黒字に白字のボタンを作成します。
33行目の「font_size: 36」は、フォントサイズを36に設定しています。
34行目の「pos_hint: {“center_x”:0.5, “center_y”:0.4}」は、ボタンの表示位置を設定しています。ボタンの横幅の中心が画面横幅の中心になるように、ボタンの縦幅の中心が画面縦幅の5分の2になるように設定しています。
35行目の「size_hint: [None, None]」は、ボタンのサイズを固定値にしたいため、比率で設定するsize_hintにNoneを代入しています。固定値を使用する場合は必ず必要な処理です。
36行目の「size: [200, 100]」は、ボタンのサイズを横幅200、縦幅100で設定しています。
37行目の「text: “Start.”」は、ボタンに表示する文字列を設定しています。
38行目の「on_press: app.root.gotoPlayDisplay()」は、ボタンが押されたときにgotoPlayDisplayを実行するように設定しています。app.rootによって実行中のアプリケーションの中で一番最下層のレイアウトを指定しています。この場合は、RootWidgetのことを指します。
動作確認
コマンドプロンプトを開き、ファイルが保存されているフォルダまで移動します。移動したら以下のコマンドを入力し、実行します。
python tenplusapp.py
以下のような画面が表示されます。
次に、真ん中のスタートボタンをクリックします。以下のような真っ白な画面が表示されます。
タイトル画面とプレイ画面の真っ白い画面を確認できたら、動作確認は完了です。
スポンサードサーチ
まとめ
今回は、アプリケーションの基となるレイアウトの作成とタイトル画面の作成、プレイ画面の一部を作成しました。
どれも初歩的なことしか行っていませんが、重要ではあるため理解するよう、お願いいたします。
本記事で作成したコードを以下に示します。
【Kivy】Pythonで落ちもの系ゲーム開発(テトリス風)Part5 コード
次回Part6では、盤面を表示させるウィジェットを作成します。
最後までお読みいただきありがとうございます。
スポンサードサーチ