0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ワイ「Pythonista3 のscene モジュールを紹介するんだよ?」

Last updated at Posted at 2022-12-06

Pythonista3 Advent Calendar 2022 の 7 日目の記事を書き始めるワイ

ワイ「まずは書き出しのテンプレからやな、、、」カタカタ、、、


この記事は、Pythonista3 Advent Calendar 2022 の 07 日目の記事です。

👇 : 06 日目

👇 : 08 日目

一方的な偏った目線で、Pythonista3 を紹介していきます。

ほぼ毎日 iPhone(Pythonista3)で、コーディングをしている者です。よろしくお願いします。

以下、私の 2022 年 12 月時点の環境です。

sysInfo.log
--- SYSTEM INFORMATION ---
* Pythonista 3.3 (330025), Default interpreter 3.6.1
* iOS 16.0.2, model iPhone12,1, resolution (portrait) 828.0 x 1792.0 @ 2.0

他の環境(iPad や端末の種類、iOS のバージョン違い)では、意図としない挙動(エラーになる)なる場合もあります。ご了承ください。

ちなみに、model iPhone12,1 は、iPhone11 です。


ワイ「これでええな!」ッターン

ワイ「さてと、、、」

ワイ「scene モジュールを紹介すると言っても、何をどう紹介したらええんやろか、、、」

ワイ「どうしたの?ネタ切れなのかな?」

ワイ「ネネネ、ネタ切れちゃうわ!!」

ワイ「書きたいことはたくさんあるけど、書く速度と時間が全く釣り合ってないんや!」

ワイ「じゃあ、大好きな Shader をやればいいんだよ?」

ワイ「それば、次回の予定や!そもそも前回も、ui モジュールでニッチにdraw メソッドでクリエイティブコーディングをメインお届けしてしまったんや!」

ワイ「少ない Pythonista3 読者層の中で隙間産業すなよ!」

ワイ「Shader はあくまで、scene モジュールの副産物みたいなもんやろ」

ワイ「そうですわねぇ、SpriteKit Framework がベースですものねぇ」

SpriteKit | Apple Developer Documentation

ワイ「不要な情報を増やすなや、、、」

ワイ「そういったことは、objc_util のときにまとめて説明しようと思ってたんや、、、」

ワイ「ワンチャン、Pythonista3 をはじめようと読んでくれてた人が、混乱するやろ、、、」

ワイ「ごめんなさいだよ?(たぶん API の説明を前にしてたんだよ?)」

ワイ「紹介する順番をそれなりに考慮して進めてるんやから水差さんようにお願いしますやで」

充実のチュートリアル

ワイ「とにかく、scene モジュールは、Pythonista3 の中でもコードサンプルが多いんや」

ワイ「しかも、細かくパート分けされてたり、順を追って機能追加をしていったりと手厚くサポートされているなと思うで」

Game Tutorial

ワイ「サンプルコードがたくさん入っているExamples にも、Examples/Game Tutorial に part7 まで用意されてるんや!」

ワイ「Tutorial Part 1.py なんて、実装コードよりもコメント解説の方が多いんやで」

ワイ「フォントがUbuntu Mono で、Size は Pythonista3 最小の8 でやっと全体像がギリギリ見えるくらいや」

img221123_191121.png

ワイ「すごいね!壮観なのだね?」

ワイ「ゲームで使えるイラストなんかも Pythonista3 に準備されてるんやで」

img221123_193042.png

ワイ「キーボードの右上にある(+) をタップするとアイコンや画像、サウンドを簡単に選べるんや」

img221123_193101.png

img221123_193109.png

ワイ「ゲームつくる前に、材集めのためのサイト巡りが不要になるで!!」

ワイ「いたせりつくせりなんだね?」

ワイ「英語に抵抗あるなら、前に紹介した翻訳スクリプトを使えば少し楽になるやで」

Pythonista3 内だけで、英語を日本語に機械翻訳 | Pythonista3 の editor module を使い、Pythonista3 のコーディングを楽にする - Qiita

https://qiita.com/pome-ta/items/c3902a0f6a0de691df8d#pythonista3-%E5%86%85%E3%81%A0%E3%81%91%E3%81%A7%E8%8B%B1%E8%AA%9E%E3%82%92%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AB%E6%A9%9F%E6%A2%B0%E7%BF%BB%E8%A8%B3

scene モジュールの Documentation

ワイ「Documentation の充実っぷりも最高やで、特に introduction は、適宜かいつまんでサンプルが用意されているんや」

introduction | scene — 2D Games and Animations — Python 3.6.1 documentation

ワイ「[Open in Editor] でサンプルをひとつづつ挙動を確認すれば、scene モジュールの雰囲気が掴めるで」

ワイ「サンプルから、自分が思い描く改造チャレンジをしてみるのもええと思うで」

それにしても

ワイ「コードの内容にも触れずに、ただただ Pythonista3 にある事実を伝えているだけやんけ。。。」

ワイ「ui モジュールだと、add_subviewadd_child になっていたり、混同しないように気をつけるんやでー!しか伝えることがなさそうやで。。。」

ワイ「。。。」

ワイ「過去の完成してない、リポジトリの紹介しか道はないのかもしれんな。。。。」

ワイ「改めてコードをみてみると、意味不明なところやペンディングなところもあるから、いろいろ修正したいンゴ」

ワイ「だけど、そんなことしたら、時間が全然足りない。。。」

ワイ「納期という確定完成が存在しない、趣味プログラミングの悲しき性かもしれんな」

ワイ「そもそも、ゲームも下手だし。ゲーム作りたい。ってモチベーションもさほど持ってない系男子なんや、、、」

ワイ「もう前置きの言い訳は、いいからはやく紹介をするんだよ?」

ワイ「わかりましたやで、、、」

エアーホッケーゲーム

ワイ「昔の iPhone から引っ張り出してきたやで、、、」

img221124_123447.png

pystaAirHockeyGame.py

ワイ「2 人プレイのエアーホッケーゲームやな」

ワイ「2019 年の 4 月頃にぽちぽち作ってたみたいやで」

テストプレイ

img221124_123559.gif

ワイ「点数が入ると自エリアがピカピカする」

ワイ「パドルは自エリアしか移動できひんようになってるな」

img221124_123642.gif

ワイ「ボールがガクガクしとるのは、衝突判定がガバってる証拠やな」

ワイ「まあ必殺技みたいでカッコええからヨシ!やで」

ワイ「ヨシ!じゃないんだよ?しっかり修正をしてほしいんだよ?」

実装

ワイ「これは、コードを見返して気がついたんじゃなく、記憶が蘇ってきただけなんやが」

ワイ「パドルやゴールを個別に判断させたくて、ゴニョゴニョしてたのを思い出したわ」

ワイ「super で呼んでるところかな?継承の概念はないのかな?」

class Oval_obj(scene.ShapeNode):
  def __init__(self, _x, _y, wh, player, color, parent=None):
    p_path = ui.Path.oval(0, 0, wh, wh)
    super(Oval_obj, self).__init__(
      p_path, position=(_x, _y), fill_color=str(color), parent=parent)
    self.touch = None
    self.player = player
class Field(scene.Node):
  def __init__(self, parent=None):
    super(Field, self).__init__(parent=parent)

  def setup(self):
    r_path = ui.Path.rect(0, 0, x, y_cent)
    self.play1 = scene.ShapeNode(r_path, 'pink')
    self.play1.position = (x_cent, y_cent / 2)
    self.play2 = scene.ShapeNode(r_path, 'cyan')
    self.play2.position = (x_cent, y_cent + y_cent / 2)

ワイ「参考にしたコードがこんな感じだったのかも知れんな、もうその辺は覚えてないわ」

ワイ「2 つのものを捜査させて無駄感が半端ないねん」

  def update(self):
    self.ball.update()
    if self.ball.position[1] > y - self.ball.size[0] / 2:
      if self.goal1.position[0] - goal_var / 2 <= self.ball.position[0] < self.goal1.position[0] + goal_var / 2:
        #print('赤に加点')
        self.p1_points += 1
        self.field.p1_action()
        self.scr_p1.text = str(self.p1_points)

    if self.ball.position[1] < self.ball.size[0] / 2:
      if self.goal2.position[0] - goal_var / 2 <= self.ball.position[0] < self.goal1.position[0] + goal_var / 2:
        #print('青に加点')
        self.p2_points += 1
        self.field.p2_action()
        self.scr_p2.text = str(self.p2_points)

ワイ「class 名や、変数名も適当すぎるんだよ?」

ワイ「命名関係と、2 プレイヤーとしての処理を書き換える。衝突判定をしっかり書く。とかの書き直しが必要そうなコードやな」

ワイ「実装時の記憶じゃなくて、コードから意図を読み取れる書き方を目指したいやで」

テトリス目コピ

ワイ「これは、Pythonista3 で実装するネタ探しの時に『なんかネタくださいな』と相談したときに『テトリスでも作れば?』と言われたんや」

img221124_151922.png

ワイ「色々な言語で実装されてそうだったから、そんな情報を一切遮断したるでーと、Wikipedia と当時公式で出てたアプリを見るだけで作ってみたやつやね」

pome-ta/tetrisPysta: Pythonista3 (ios app) use scene module

テストプレイ

img221124_152523.gif

ワイ「ブロックが着地する。もしくは、壁にぶつかると、画面が揺れるエフェクトをつけてる」

ワイ「当時、触覚フィードバックを知らんかったから、視認てきなフィードバックを実装したんやね」

ワイ「テトリスが下手すぎてキャプチャ撮るのに時間かかってしもうたわ」

実装面

ワイ「今回の記事用に、試しにプレイしてみたんやけど、低確率でエラー出てしまうんよ」

ワイ「コードがスパゲッティ過ぎて、深追いできず諦めましたや」

ワイ「あと、下ボタン長押し処理を実装せずに終えてるみたいやな」

ワイ「ぽちぽち、下ボタン連打するんがホンマめんどくさいわ」

ワイ「いまは、なんとなくどう処理すればいいかイメージはつくな」

ワイ「ボタン周りだと、ボタン一つ一つをMainScene に個別で配置しとるから、ガバッとレイアウトの移動調節できへんのが面倒やな」

    # --- btn start
    path = ui.Path.oval(0, 0, 72, 72)
    self.d_btn = scene.ShapeNode(path=path, parent=self, fill_color='white')
    self.d_btn.position = self.size * .5
    self.d_btn.position -= (0, self.size[1] / 2 - self.d_btn.size[1] / 2)
    self.l_btn = scene.ShapeNode(path=path, parent=self, fill_color='red')
    self.l_btn.position = self.size * .5
    self.l_btn.position -= (+(self.l_btn.size[0]),
                            self.size[1] / 2 - self.l_btn.size[1])
    self.r_btn = scene.ShapeNode(path=path, parent=self, fill_color='blue')
    self.r_btn.position = self.size * .5
    self.r_btn.position -= (-(self.r_btn.size[0] * 1),
                            self.size[1] / 2 - self.r_btn.size[1])
    self.e_btn = scene.ShapeNode(path=path, parent=self, fill_color='yellow')
    self.e_btn.position = self.size * .5
    self.e_btn.position -= (0, self.size[1] / 2 - self.e_btn.size[1] * 1.5)

    self.s_btn = scene.ShapeNode(parent=self, fill_color='pink')
    self.s_btn.path = ui.Path.oval(0, 0, 32, 32)
    self.s_btn.position = self.size * .5
    self.s_btn.position -= (self.s_btn.size[0] - self.size[0] / 2,
                            self.size[1] / 3)
    # --- btn end

ワイ「地獄かな?」

ワイ「当時は、iPhone6 plus だったから良かったかもしらんが、画面レイアウトの柔軟性に欠けとる」

ワイ「ブロックの回転は、もっとスマートならないのかな?」

class SetUpMinos:
  def __init__(self):
    i_rotate = ([[-1, 0], [0, 0], [1, 0], [2, 0]], [[1, -2], [1, -1], [1, 0],
                                                    [1, 1]],
                [[-1, -1], [0, -1], [1, -1], [2, -1]], [[0, -2], [0, -1],
                                                        [0, 0], [0, 1]])
    mino_i = {'name': 'i', 'color': 'cyan', 'rotate': i_rotate}

    o_rotate = ([[0, 0], [0, 1], [1, 0], [1, 1]])
    mino_o = {'name': 'o', 'color': 'yellow', 'rotate': o_rotate}

    s_rotate = ([[-1, 0], [0, 0], [0, 1], [1, 1]], [[0, 1], [0, 0], [1, 0],
                                                    [1, -1]],
                [[-1, -1], [0, -1], [0, 0], [1, 0]], [[-1, 1], [-1, 0], [0, 0],
                                                      [0, -1]])
    mino_s = {'name': 's', 'color': 'green', 'rotate': s_rotate}

    z_rotate = ([[0, 1], [1, 1], [1, 0], [2, 0]], [[1, 0], [1, 1], [2, 2],
                                                   [2, 1]],
                [[0, 2], [1, 2], [1, 1], [2, 1]], [[0, 0], [0, 1], [1, 2],
                                                   [1, 1]])
    mino_z = {'name': 'z', 'color': 'red', 'rotate': z_rotate}

    j_rotate = ([[0, 0], [1, 0], [2, 0], [0, 1]], [[1, 1], [1, 0], [2, 1],
                                                   [1, -1]],
                [[0, 0], [1, 0], [2, -1], [2, 0]], [[1, 1], [1, 0], [0, -1],
                                                    [1, -1]])
    mino_j = {'name': 'j', 'color': 'blue', 'rotate': j_rotate}

    l_rotate = ([[0, 0], [1, 0], [2, 0], [2, 1]], [[1, 1], [1, 0], [2, -1],
                                                   [1, -1]],
                [[0, 0], [1, 0], [0, -1], [2, 0]], [[1, 1], [1, 0], [1, -1],
                                                    [0, 1]])
    mino_l = {'name': 'l', 'color': 'orange', 'rotate': l_rotate}

    t_rotate = ([[0, 0], [1, 0], [2, 0], [1, 1]], [[1, -1], [1, 0], [2, 0],
                                                   [1, 1]],
                [[1, -1], [1, 0], [2, 0], [0, 0]], [[1, -1], [1, 0], [1, 1],
                                                    [0, 0]])
    mino_t = {'name': 't', 'color': 'purple', 'rotate': t_rotate}

    self.mino_list = [mino_i, mino_o, mino_s, mino_z, mino_j, mino_l, mino_t]

ワイ「せやな、結局答え合わせ的に、他のテトリスのコードと見合わせてないねん」

ワイ「独自実装過ぎて、他のコードを読むの諦めた記憶があるわ」

ワイ「壁付近のブロック回転は、公式テトリスから動きをキャプチャして、その通りに動くように調整した記憶も出てきたわ」

ワイ「写真アルバムのテトリスキャプチャ汚染すごそうなんだよ?」

過去のコード

ワイ「なかなか、ガバガバでヘビーやったな、、、」

ワイ「一つのファイルで完結させるのをやめたらいいんだよ?」

ワイ「それは、モジュール設計が下手くそというのが本音。表向きは、試してみたい人が 1 ファイルの方がハードル低く参入できる意図があるんやで」

ワイ「本音と建前の説明順番が逆なんだよ?」

ワイ「frame_interval に依存して、ゲーム速度が変化してしまうのもよくないんだよ?」

ワイ「最近だと 120Hz の端末もあるんよね。ゲーム内時間を管理するのを入れんとあかんなぁ」

ワイ「ちょいちょい、過去のを引っ張り出してリファクタリングするのも、勉強になるかもなぁ」

ワイ「とりあえず酷くてもいいから、GitHub にあげてさらし首にすれば、意識してコード書くようになるかもな」

ワイ「つまり GitHub にあるコードは、意識してコード書いてるんだよ?」

ワイ「もうええわ、やめさせてもらうわ」

結局scene モジュールの紹介はどうすんねや?

ワイ「っは!?」

ワイ「夢ならよかったのに、、、」omz

ワイ「はやくscene モジュールでの Shader 遊びをしたいやで、、、」


ワイ、俺「皆さんここまで、読んでいただきありがとうございました!」

ワイ「って、なんで俺くんが!?
改めまして、ありがとうございました!」

本当の本当に終わり

👇 : 08 日目

せんでん

Discord

Pythonista3 の日本語コミュニティーがあります。みなさん優しくて、わからないところも親身に教えてくれるのでこの機会に覗いてみてください。

書籍

iPhone/iPad でプログラミングする最強の本。

その他

  • サンプルコード

Pythonista3 Advent Calendar 2022 でのコードをまとめているリポジトリがあります。

コードのエラーや変なところや改善点など。ご指摘や PR お待ちしておりますー

  • Twitter

なんしかガチャガチャしていますが、お気兼ねなくお声がけくださいませー

  • GitHub

基本的に GitHub にコードをあげているので、何にハマって何を実装しているのか観測できると思います。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?