ゲーム開発では、部品として''シーン''と''ノード''の2種類を配置して作ります。
- シーンはゲーム画面のベースとなる部品でUI部品の中のViewのことです。
- ノードはシーンに組み込んで表示するオブジェクト部品のことです。
ゲーム部分の開発では''.pyui''ファイルは使わずに全てスクリプトに書いていきます。
ゲーム開発
オブジェクトを動かす
▼シーンにスプライトを追加してupdate関数によりスプライトの位置を変化させています。

▼スクリプトの全体です。関数の詳細は以下に記載します。

▼Scene継承クラス:Sceneクラスを継承したクラスのインスタンスを変数とし、run(SceneInstance())としてシーンを表示することができます。
from scene import *
class SampleScene(Scene):
#背景色の設定
self.background_color = '#88ffff'
run(SampleScene())
▼シーンにスプライトを追加する:スプライトはSpriteNodeクラスのインスタンスとして生成し、Add_childでシーンに追加することができます。
def setup(self): #スプライトの生成
self.sprite = SpriteNode('emj:Alien_Monster') #スプライトの位置設定
self.sprite.position = self.size / 2 #スプライトをシーンに追加する
self.add_child(self.sprite)
▼スプライトを動かす:update関数では毎秒60回実行され位置を更新しています。
#移動距離の設定
dx = 10
dy = 10
def update(self):
position = self.sprite.position
position.x += self.dx
position.y += self.dy
if position.x <= 0:
self.dx = 10
if position.x >= self.size.w:
self.dx = -10
if position.y <= 0:
self.dy = 10
if position.y >= self.size.h:
self.dy = -10
self.sprite.position = position
既存のスプライトデータの使用方法
▼スクリプトの右下の+マークをタップします。

▼Image,Sound,Color,Fontの既存データを使用することができ、選択するとコピーペーストされます。

オブジェクトを変化させてタップした位置に移動させる
▼画面をタップしたところに回転・拡大縮小・透明化しながら移動させる。

▼スクリプトの全体です。関数の詳細は以下に記載します。

▼タッチしたときに呼び出される関数:タップの動作によって呼び出される関数は3種類あります。
touch_began | タッチしたときに1度だけ呼び出される。 |
touch_moved | ドラッグ中に繰り返し呼び出される。 |
touch_ended | タップし話したときに1度だけ呼び出される。 |
▼タッチ後のアクション関数:アクションには回転・拡大縮小・フェードイン/アウトに加えて、エフェクト(モード)を設定することができます。
- 指定の時間で動かす
Action.move_to(x座標, y座標, 時間, モード) |
Action.move_by(x座標, y座標, 時間, モード) |
- ノードの回転
Action.rotate_to(角度, 時間, モード) |
Action.rotate_by(角度, 時間, モード) |
- ノードの拡大縮小
Action.scale_to(倍率, 時間, モード) |
Action.scale_by(倍率, 時間, モード) |
Action.scale_x_to(x軸倍率, 時間, モード) |
Action.scale_y_to(y軸倍率, 時間, モード) |
- ノードのフェードイン/アウト
Action.fade_to(アルファ値, 時間, モード) |
Action.fade_by(アルファ値, 時間, モード) |
- モードの種類
TIMING_LINEAR | 直線的に等速で移動 |
TIMING_EASE_IN | 開始時になめらかに加速 |
TIMING_EASE_OUT | 終了時になめらかに減速 |
TIMING_EASE_IN_OUT | 開始時になめらかに加速し、終了時になめらかに減速 |
TIMING_SINODIAL | TIMING_LINEARとTIMING_EASE_IN_OUTの間(加速減速が弱い) |
TIMING_EASE_BACK_IN | 開始時に1度戻ってから進む |
TIMING_EASE_BACK_OUT | 終了時に1度越してから戻る |
TIMING_EASE_BACK_IN_OUT | 開始時に1度戻ってから進み、終了時に1度越してから戻る |
TIMING_ELASTIC_IN | 開始時に輪ゴムで打ち出されるような効果 |
TIMING_ELASTIC_OUT | 終了時に輪ゴムで打ち出されるような効果 |
TIMING_ELASTIC_IN_OUT | 開始/終了時時に輪ゴムで打ち出されるような効果 |
TIMING_BOUNCE_IN | 開始時にバウンドするような効果 |
TIMING_BOUNCE_OUT | 終了時にバウンドするような効果 |
TIMING_BOUNCE_IN_OUT | 開始/終了時にバウンドするような効果 |
▼複数のActionを行う場合
Action.repeat(<Action>, 回数) | Actionを指定の回数分だけ行う動作 |
Action.group(<Action>, <Action>, ...) | 複数のActionを1つのActionとしてグループ化する動作 |
Action.sequence(<Action>, <Action>, ...) | 複数のActionを順に実行する動作 |
▼タップ時の動作:スプライトに動作を加えるときには、sprite.run_action(<Action>)とする。
def touch_began(self, touch):
p = touch.location #直線移動
act1 = Action.move_to(p.x, p.y, 3.0, TIMING_LINEAR) #回転
act2 = Action.rotate_by(4 * pi, 3.0, TIMING_LINEAR) #フェードイン/アウト
act3 = Action.fade_to(0.5, 0.5, TIMING_LINEAR)
act4 = Action.fade_to(1.0, 0.5, TIMING_LINEAR) #拡大縮小
act5 = Action.scale_to(2, 0.5, TIMING_LINEAR)
act6 = Action.scale_to(1, 0.5, TIMING_LINEAR) #フェードイン/アウトを順に実行する
act_s = Action.sequence(act3, act4) #拡大縮小を順に実行する
act_s2 = Action.sequence(act5, act6) #act_sを3回繰り返す
act_rp = Action.repeat(act_s, 3) #act_s2を3回繰り返す
act_rp2 = Action.repeat(act_s2, 3) #act1,act2,act_rp,act_rp2をグループ化する
act_g = Action.group(act1, act2, act_rp, act_rp2)
self.sp.run_action(act_g)
タップしたオブジェクトを生成・削除する
▼何もないところをタップするとスプライトが生成され、スプライトをタップするとスプライトが削除される。

▼スクリプトの全体です。関数の詳細は以下に記載します。

▼複数のスプライトを生成させるのでスプライトのクラスを作っておきます。スプライトはタッチされると削除という動作があるのでタッチされたかどうかを真偽する関数を作っておきます。タッチされた位置とスプライトの位置の差が13(スプライトの大きさ)である場合に真を返します。
class SampleSprite(SpriteNode):
def __init__(self, img):
super().__init__(img)
self.d = Point(0, 0)
def is_touched(self, pt):
p = self.point_from_scene(pt)
return -13 < p.x < 13 and -13 < p.y < 13
▼タッチされた際にスプライトを生成する関数です。各スプライトには初めにランダムで変数dとして速度ベクトルを設定しておきます。
def create_sprite(self, p):
sp = SampleSprite('emj:Alien_Monster')
sp.position = p
d = Point(random.randint(-3, 3), random.randint(-3, 3))
sp.d = d
fo = Action.fade_to(0.0, 0.0)
sp.run_action(fo)
fi = Action.fade_to(1.0, 1.0, TIMING_LINEAR)
act = Action.sequence(fo, fi)
sp.run_action(act)
self.add_child(sp)
▼複数のスプライトをランダムに移動させています。シーンにあるスプライトはchildrenという変数に格納されているので、そこからスプライトを取り出します。各スプライトに対して現在位置に速度ベクトル分を加えて更新します。
def update(self):
for sp in self.children:
sp.position += sp.d
if sp.position.x <= 0 or sp.position.x >= self.size.width:
sp.d.x *= -1
if sp.position.y <= 0 or sp.position.y >= self.size.height:
sp.d.y *= -1
▼画面をタッチした際に動作する関数です。各スプライトに対して、タッチされた場合にはスプライトの削除関数(remove_from_parent)を呼び出します。一つもなかった場合にはスプライトが生成されます
def touch_began(self, touch):
for sp in self.children:
if sp.is_touched(touch.location):
fo = Action.fade_to(0.0, 1.0, TIMING_LINEAR)
rm = Action.call(sp.remove_from_parent)
act = Action.sequence(fo, rm)
sp.run_action(act)
return
self.create_sprite(touch.location)
まとめ
今回はゲーム開発というよりスプライトの動かし方を書いただけになってしまいました。
次回はゲームのようなプログラムを作っていこうと思います。