part1「璃奈ちゃんボード」をiPadだけで自作する


#動画

https://www.nicovideo.jp/watch/sm38393401

#はじめに
最近りなちゃんボードを自作する人が増えていますが、マイコンを使ったり、3Dプリンターを使ったりするのは難しそう……~~高校生の璃奈ちゃんがあんな短期間で工作出来るわけないだろ~~、と思う方も多いでしょう。
私もそう思ったので、より現実的に、iPadやiPhoneだけで「りなちゃんボード」を再現(表示)するプログラムを作りました。
　コンセプトは、
**誰でも,簡単に,どんな時でも使える璃奈ちゃんボード**です。
使用する言語はpython3.xのみです。

#必要なもの
* iOS、iPadOSアプリ「**Pythonista3**」(1200円)
* iPhoneやiPad(原寸大で作るためには9.7インチか、10.2インチ、11インチのiPadが必要)

たったこれだけ！

1200円のアプリは確かに高いですが、このアプリを入れるだけでほとんどのpythonプログラムが実行できるので、初心者の方も玄人の方もおすすめです。今回はPythonista に入っているuiモジュールを使うので必須となります。

#用件定義
#####りなちゃんボードとは

　「ラブライブ！虹が咲学園スクールアイドル同好会」内に登場する高校1年生の女の子、天王寺璃奈は人前で感情を伝えることが大の苦手。そこで、様々な自分の表情を描いた「璃奈ちゃんボード」を常備し、それを顔前に掲げることで相手に思いを伝え易くなった。日常生活ではスケッチブックに描いたボードを使っているが、ライブの時には画面のついたヘッドセットを装着し、音楽に合わせて様々な顔を表示するボードを使う。
　今回はこのボードの画面を完全に再現しようと思う。
#####ボードの仕様
　ボードのマス目の数はアニメ、ゲーム漫画など、媒体により画面比が異なっているが、ここではアニメ版の画面比構成を採用する。
　すなわち、実質的な描画領域は横32マス×縦18マスくらいの長方形で、領域の外にも白マスが途切れなく続いている。

<details><summary>参考写真</summary><div>

![FB965227-233B-4FDC-AA2A-C7FEB6BFCF89.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/fee74fa7-15a4-0c42-68f4-fcb48b82d392.jpeg)
![F270C791-9980-40AD-9A81-F27E59BEE2B2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/2008bc03-d824-481f-5d3d-a22924227e44.jpeg)
![71C57C12-5D23-4C9B-B5D8-FB0D0839FC35.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/fe1b8179-191f-591a-1bf8-f2dbedff0318.jpeg)

</div></details>
#####機能
<実装する機能>

* 画面上のドット絵で顔を表現（これは必須！）
*  時間経過に応じた**遅延のないアニメーション**
*  曲に合わせたり、セリフに合わせたりなど、様々な場面で使えるように、**スクリプトを簡略化**。作業時間を短縮する。
*  

<いつか実装したい機能>

* BlueToothLEを用いた通信を行うことで、マイコンや３Dプリンターで作った本物の「璃奈ちゃんボード」と接続。データをリアルタイムで出力する。（Pythonista3はBluetooth通信ができるので理論上可能）

#実践(試行錯誤)
###顔の描画方法

　とりあえず、まずはドット絵だけでも再現しようと思い、2日間の試行錯誤の末以下のようになった。
　18×32個のボタンを並べ、押したところがピンク色に変化するだけ。![16078A7E-3683-4910-AAB9-970653DA5B49.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/3ef093db-a236-8bb8-c997-022f90418abb.jpeg)
どこに色が付いているか分かるように左上のマスを基準にして座標を設定。![B177EC23-8F49-4092-A7AC-5DBE99B6921B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/d6c1022c-90db-466f-d0c1-89e2f4e1729d.png)
折角作ったこの顔を残せないのは勿体ない……

ヨシ、csvファイルにして保存しよう！
![133203D7-0116-488A-9CDF-24BBA06AE649.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/0e54ce6f-2db9-3ac0-25b7-1c5879338e83.jpeg)


ピンク色になっているボタンの座標を1行に列挙してcsvに保存する。次回このcsvファイルを読み込めば、この顔が表示される。
そしてこれを何行も書いていけば、顔をスライドショーのように表示できるのだが……↓
![83DF992B-63F4-4804-A883-CE191FA79A49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/c58d4583-60b5-c24b-8a9c-01d322263db2.png)

* **見づらい！**
* 1つの顔を表示するための文章量が大きい。
* データを見ただけで、どんな顔が表示されるのか分からない。
* 顔を部分的に修正することが困難(例えば、「目」のパーツだけを変えたいとき、顔全体を作り直す必要がある)。

など、問題点が多い。
これでは「使いやすい璃奈ちゃんボード」というコンセプトに合わない。

　そこで思いついたのが**プリセットの登録機能**である。
よく使う「目」や「口」のパーツを別ファイルに登録しておいて、短い単語で簡単に呼び出せる(表示できる)ようにすれば良い。

mouth1,mouth2などの名前をプリセットに登録して…
![367E0E88-06D5-4973-AD1D-D4188E97D49C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/2ae2e889-32a0-a3da-99bc-d1c923143971.jpeg)
![EE235303-F6CB-4085-8690-63BC3F4A45D8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/06613417-88fc-1260-bf62-163ac12618dc.jpeg)
![55E7C296-7F38-49C2-920E-EC114F1AE849.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/3c18e158-9ef6-fbb2-f53a-09ac1074e8df.jpeg)

実際に使う時には↓
![4FEAE9EC-1688-4224-80A7-DD4DDEA676AA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/e170aadc-ec16-eeec-5950-146248ba20c5.jpeg)
このわずか4行で、顔を上から順に4種類表示するスクリプトが書けた。(表示時間は3秒ずつ)


**プリセット一覧は別の記事で**

https://qiita.com/NSmagnets/items/06c41d931b3e6fe2c6a3


###デザイン


ここで画面のデザインも本物そっくりに作り直し。


(アンカーポイントの設定が曖昧で、端のマスが切れているところも再現した)
~~もう少しいい顔はなかったのだろうか...~~
![F36AC497-0F9D-431B-99D2-03B9AAA54483.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/68890fc7-76a5-efd4-06e4-c9e37f729a33.png)

　白の正方形の図形ノード(Pythonista3ではShapeNode)を端まで敷き詰めて、各ブロックの背景色をピンクと白に切り替えてドット絵を表現している。
![9F13DB99-6C41-43AD-AAE4-2E804A3E0CEF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/c691bd4f-d405-cdd1-5178-2ee73f943274.png)
ボード外枠の画像を付けるとこんな感じ↓
　背景色を白→灰色にしてみた。
![3EA6E312-7E45-4AB0-945C-9F3AA533C451.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/aab87bda-8aae-e98b-561e-3c23382e5c5b.png)
璃奈ちゃんボード、「にっこりん❤️」
![258FD215-8A6F-4BF4-BAC6-35F1BFC321D6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/a67afa77-5ae0-419b-6d7f-4b5200a135c4.png)




　


#導入方法(まずは再生するところまで)



#####配布しているデータについて
　課題曲はアニメ第6話挿入歌「**ツナガルコネクト**」。私はこのMVを見て璃奈ちゃんボードの制作を志しました。
最初の40秒だけ再現しています。
#####ダウンロード方法
* ファイルをダウンロードする。https://drive.google.com/file/d/1DuUxXomse99Obtm-KDTkHj83iGSeNrqX/view?usp=sharing

**ファイルに保存してから、zipを解凍。**

* iPadの場合、マルチタスクの状態でドラッグして配置
![イメージ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/1e38a2d4-1b42-4c5d-9c58-2bb603be88ad.gif)



* RinachanBoard.pyを実行する
![6A9EBE9E-97BB-465F-A61A-078A46E91BC5.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/1e674b38-d206-831b-808e-19e075e4f491.jpeg)
　
　

* 音源とスクリプトを選択する。
![93E8E173-A26D-466B-BC10-38470F817AB6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/f20bbdb8-978c-f32c-e781-d0ea3d82373e.jpeg)

　**connect.csv**と**Rinachan.aiff**を選択してチェックマークをタップ


#####タイミング(誤差)調整作業

* 起動後、**画面中央**をタップ(端をタップすると別機能が起動します)。最後までスクリプトを再生する。

**<この時点では時間の誤差、上下左右のずれがあるので、これから補正します>**

* 画面右上の×で実行を終了して、コンソールをチェックする。たくさんの数字の羅列が出力されています。


![13E3C8CE-DC15-40B4-B987-51DFF43E471E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/b7beac99-79d4-5c5e-47df-d395422b8d89.jpeg)
　これは、スクリプトに書いてある時間と、実際に描画が完了した**時間の誤差**です。各フレームごとについて出力されています。正の値はスクリプトより遅い、負の値は早いことを示しています。
　**これが0に近づくように調整をします。**

　

　`RinachanBoard.py`の始めの部分にはパラメータの変更をする場所があります。
今回は、写真の26行目`timeduration`に誤差(秒)を入力します。負の値は表示を早め、正の値は表示を遅らせます。(わざわざ表示を遅らせる人は少ないと思うので、多くの人は負の値を記入すると思います。)
![9998C68A-E9A0-4F46-8E6F-5E9B1540B323.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/47cf723c-65f0-a615-638f-f87a3012f71d.jpeg)

　（参考までに、iPadPro 11インチでは-0.02で丁度良くなりました。）

#####位置調整作業
　続けて、表示される顔の上下左右のズレを直します。変更するパラメータは`offsetX`と`offsetY`です。
34,35行目に移動するピクセル数を入力します。しかし、このままではどれくらいズラせば良いのかわかりません。
　そんなときに役に立つのは`DEBUGMODE`です。`DEBUGMODE=True`とすることで起動画面に1ブロック（1ドット）のサイズを表示してくれます。(サイズは端末の大きさに応じて自動計算されます)![3CD222A6-378B-492B-A092-6BB0D9F44B8A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/edf64917-5d76-dde5-1dad-750bf4eacace.jpeg)

　例えば、1マス41ピクセルで2.5マス分ずらしたいときは、41*2.5=102.5ピクセルずらせば良い、という感じです。　

#操作方法(基礎編)

* 起動後、「チャリーン♪」となったら読み込み完了です。画面のどこか(デバッグモードの時は、画面中央)をタップすると再生が始まります。

* 再生中に画面を数回タップするともう一度最初から再生します。
* 〈デバッグモードのみ〉再生中に画面右端をタップすると1つ先のフレームに進みます。左端をタップすると1つ手前のフレームに戻ります。(まだバグが残っていて、表示が乱れることがあります)


#設定できる項目一覧

`RinachanBoard.py`の始めの部分にはいくつか調整できるパラメータがあります。必要に応じて弄ってください。

```python:RinachanBoard.py(抜粋)



'''
###########↓設定/config##########
'''

scriptFile='connect.csv'
musicFile='Rinachan.aiff'
timeduration=-0.02#時間ズレ補正,単位は秒
sizemode=0      #0:縦幅を基準　1:横幅を基準に合わせます。横画面時は0が規定値
DEBUGMODE=True    #True,False
boadcolor=[('#cccccc'),('#d00fd9')]#ボードの色[白,ピンク]   
linecolor='#eaeaea'    #枠線の色.   line's color


offsetX=42#x軸ズレ補正
offsetY=-10#y軸ズレ補正
blockSize=0#ブロックのサイズ。0の時、自動設定

'''
##########↑設定ここまで##########
'''


```
* **scriptFile**:使用するスクリプトのファイル名を入れる。拡張子(.csv)も忘れずに。
* **musicFile**:音源のファイル名を入れる
* timeduration:時間補正(前述)
* **sizemode**:横画面の時は0が良い
* **DEBUGMODE**:デバッグ画面を出したい時はTrue、消す時はFalse
* **boadcolor**:ボードの色を設定。list形式になっていて、形は[白,ピンク]
* **linecolor**:ブロックの輪郭線の色を設定
* offsetX:位置補正(前述)大きくすると右に動く
* offsetY:位置補正(前述)大きくすると上に動く
* blockSize:本来、端末の画面サイズに応じて一つ一つのブロックのサイズが自動設定されるが、手動で設定したい時はこの値をいじる。


#コード

<details><summary>一応載せておきますが、長いので折りたたみ。上のリンクからダウンロードした方が早い。</summary><div>

```python:qiita.py

from scene import *
import sound
import random
import math
import ui
import csv
import  re
import time
import ast
'''
#####################
璃奈ちゃんボードビューアー ver2.8
Rina-chan Board Viewer ver2.8
#####################
Created by @NSmagnets 
If you find any bugs,please inform me on Twitter(@NSmagnets)

使い方/How To Use
1、準備中……

###########↓設定/config##########
'''

scriptFile='connect.csv'#connect.csv
musicFile='Rinachan.aiff'
timeduration=-0.02#時間ズレ補正,単位は秒
sizemode=0      #0:縦幅を基準　1:横幅を基準に合わせます。横画面時は0が規定値
DEBUGMODE=False    #True,False
boadcolor=[('#cccccc'),('#d00fd9')]#ボードの色[白,ピンク]   Board's Color[(white),(pink)]
#boadcolor=[('#ffffff'),('#b700bf')]
linecolor='#eaeaea'    #枠線の色.   line's color
#boadcolor=[('#c9c9c9'),'#f400ff']

offsetX=42#x軸ズレ補正
offsetY=-10#y軸ズレ補正
blockSize=0#ブロックのサイズ。0の時、自動設定

'''
##########↑設定ここまで##########
'''



























#


'''
#「script」「music」というファイルを作り、そこにスクリプト(csv)と曲(wavなど)を入れれば、
#ファイルが整理されます。その際には' ' 'を削除してください
scriptFile='./script/'+scriptFile
musicFile='./music/'+musicFile
'''


global scene
color=[]#[9_9,2_3,3_4]
boforecolor=[]
global boad

class boad  (SpriteNode):
	def setup(self):
		bby = SpriteNode('ii.jpg', position=(self.size.w/2, self.size.h/2))
		#SpriteNode(self, 'shp:RoundRect', **kwargs)
		self.add_child(bby)
class MyScene (Scene):

	def csv_import(self):
		tapp=[]
		ee=[]
		self.boadU=[]
		#bill=[]
		self.preset={}
		self.dataprev=[]
		with open('preset.csv') as f:
		    reader = csv.reader(f)
		    l=[row for row in reader]
		    #print(l)
		    for yo in range(len(l)):
		     #print(l[yo])
		     #preset.update(dict(l[yo]))
		     p=str(l[yo]).replace('["', '')
		     q=p.replace('"]','')
		     #m=q.replace('"','')
		     s1=q.replace("/'",'')
		     
		     ss=ast.literal_eval(s1)
		     self.preset.update(ss)
		with open(scriptFile) as f:
		    reader = csv.reader(f)
		    l=[row for row in reader]
		    #self.deta=l
		    #print(l)
		    for yo in range(len(l)):
		     if '<' in l[yo][0]:
		      pass
		     else:
		      self.dataprev.append([l[yo]])
		      tapp=[]
		      ee=[]
		      #a=int(l[yo][0])
		      a=int(yo)
		      k=l[yo][1]
		      b=l[yo][2]
		      c=float(l[yo][3])
		     #print(type(k))
		    #reader2= csv.reader(l)
		    #for row in reader2:
		      if '_' in k:
		       p=k.replace('(', '')
		       q=p.replace(')','')
		       m=q.replace('"','')
		       s=re.split(', ',m)
		      else:
		       p=re.split('//',k)
		       #print(p)
		       for e in p:
		        qq=[self.preset[e][e1] for e1 in range(len(self.preset[e]))]
		        ee.extend(qq)
		       #print(ee)
		       s=[uu for uu in ee]#配列外しの0。変更禁止
		      #print(s,'s')
		     
		      for i in s:
		       if type(i)==tuple:
		        s1=str(i).replace("('",'')
		        s2=s1.replace("')",'')
		        s5=re.split('_',str(s2))
		        s6=[re.sub('\\D','',ty) for ty in s5]
		       #print(s6)
		       else:
		        s2=i.replace("/'",'')
		       # s11=s1.replace("")
		        s4=re.split('_',str(s2))
		      
		      #s5=ast.literal_eval(s4)
		       
		       s3=(int(s4[0])-1,19-int(s4[1]))#***+1,,19-***
		       tapp.append(s3)
		      #print(tapp)
		      self.boadU.append([a,tapp,b,c])
		      print(l[yo])
		    
		#print(self.dataprev)
		#print(boadU[0][2])
		
		
		
	def setup(self):
		global offsetX,offsetY
		print(self.size.h)
		if blockSize==0:
		 c=41#36.7
		 c=(self.size.h//21)+2
		 if sizemode==1:
		  c=(self.size.w//30)
		 elif sizemode==2:
		  c=35
		  offsetX=120
		  offsetY=0
		  timeduration=0.03
		  
		else:
		 c=blockSize
		 
		self.alltime=0.0
		self.epoctime=0.0
		self.duration=0.0
		self.ready= False
		self.boad=[]
		self.block={}
		self.playing=False
		self.background_color = '#d9d9d9'
		#self.background_color = 'black'
		colorNo=0
		self.scenes=0
		self.touchcount=0
		#self.music=musicFile
		self.debugmode=DEBUGMODE
		self.onlights=[]
		self.offlights=[]
		self.dataprev=[]
		path = ui.Path()
		path.line_width = 3
		path.move_to(0, 0)
        #path.line_to(200, 0)
		path.line_to(0, self.size.h)
		path.close() 
		
              #②
		path2=ui.Path()
		path2.line_width = 1
		path2.move_to(0, 0)
        #path.line_to(200, 0)
		path2.line_to(0, c)
		path2.line_to(c, c)
		path2.line_to(c, 0)
		path2.close()
		#path = ui.Path.rect(0, 0, c, c)
		for x in range(34):
			
			for y in range(28):
				self.rectangle3=ShapeNode(path2,fill_color=boadcolor[0],stroke_color=linecolor,position=(c*(x-1)+offsetX,c*y+offsetY))
				#self.rectangle = SpriteNode(boadtex[0], position=(c*x+10, c*y))
				z=(x,y)
				self.boad.append([z,colorNo])
				self.block[z]=self.rectangle3
              #④
				self.add_child(self.rectangle3)
		self.rectangle3.fill_color=boadcolor[1]
		z=(7,9)
		'''
		
		'''
		self.boadcopy=self.boad
		if self.debugmode==True:
		 score_font = ('Futura', c*1)
		 self.score_label = LabelNode('0', score_font, parent=self)
		 self.score_label.position = (self.size.w / 2, self.size.h - 120)
		 self.score_label.z_position = 1
		 self.score_label.color='#0016ff'
		 self.add_child(self.score_label)
		 self.score_label.text='DEBUG MODE ver2.8 block='+str(c)
		 self.triangle2 = ShapeNode(path,fill_color='#66ffc3', stroke_color='#18a56e',position=(self.size.w/2, self.size.h/2), parent=self)
		 self.add_child(self.triangle2)
		 #self.block[z].texture=boadtex[1]
		 sound.play_effect('arcade:Coin_2')
		self.csv_import()
		#sound.play_effect('arcade:Coin_1')
		for i in range( len(self.boadU)):	
		 self.preload(i)
		#print(self.onlights)
		del offsetX,offsetY
		if sizemode==2:
		 bby = SpriteNode('boad.png', position=(self.size.w/2, self.size.h/2),size=(self.size.w,self.size.h))
		#SpriteNode(self, 'shp:RoundRect', **kwargs)
		 self.add_child(bby)
		sound.play_effect('game:Ding_3')
	def preload(self,scene):
		 global color
		 
		 #scene=scenepic.text
		 on=[]
		 off=[]
		 boforecolor=color
		 color=[]
		 
		 
		 #for r in len(boadU):
		 #if scene== len(boadU):
		 #print('heheheowowowoowo')
		 v=self.boadU[int(scene)][1]
		 duration=self.boadU[int(scene)][3]
		 #t = threading.Timer(float(duration)-0.05,lambda:autoupdate(sender , int(scene)+1) )
		 #clear(sender)
		 #for qq in range():
		 
		 for www in self.boadcopy:
		  we=www[0]
		  #buttonbg= sender.superview[we]
		  if [we,0] in self.boadcopy:
		   ww=self.boadcopy.index([we,0])
		  else:
		   ww=self.boadcopy.index([we,1])
		  #tt=colored[ww]
		  self.boadcopy[ww:ww+1]=[[we,0]]
		  #print(self.boad)
		  #buttonbg.background_color= ('#ffffff')
 #vv=list(v)
		 '''colored
		 '''
 #u=sender.name
 #if [uu,False] in colored:
  #ww=colored.index([uu,False])
 #else:'''
		 for x in v:
		  y=[]
		  
		   
		  #y=x.replace('"','')
		  #print(colored)
		  if [x,0] in self.boadcopy:
		   ww=self.boadcopy.index([x,0])
		  else:
		   ww=self.boadcopy.index([x,1])			  
		  tt=self.boadcopy[ww]
		  #buttonbg= sender.superview[y]
		  #self.boad[ww:ww+1]=[[x,1]]
  #buttonbg.background_color= ('#fb99ff')
		  color.append(self.boadcopy[ww][0])
  #tup
		 if boforecolor==None:
		  pass
		 else:
		  for bef in boforecolor:
		   #buttonbg=sender.superview[bef]
		   if bef in color:
		     pass
		   else:
		    #self.block[bef].fill_color=boadcolor[0]
		    off.append(bef)
		    #buttonbg.background_color= ('#ffffff')
		 
		 for co in color:
		  #buttonbg=sender.superview[co]
		  if co in boforecolor:
		    pass
		  else:
		  	#self.block[co].fill_color=boadcolor[1]
		  	
		   on.append(co)
		    #buttonbg.background_color= ('#fb99ff')
		  
		 self.onlights.append(on)
		 self.offlights.append(off)
		 
		 
		 #ssd=(time.time()-self.epoctime-self.alltime+self.duration)
		 
		 #print('.                     .',ssd,self.scenes,str(self.checkcolor)+'Blocks')
		 
		 
		

	def autoupdate(self,scenes):
		 global color
		 
		 #scene=scenepic.text
		 
		 boforecolor=color
		 color=[]
		 self.checkcolor= len(color+boforecolor)
		 '''colV= sender.superview['colorView']'''
		 #for r in len(boadU):
		 #if scene== len(boadU):
		 #print('heheheowowowoowo')
		 v=self.boadU[int(self.scenes)-1][1]
		 duration=self.boadU[int(self.scenes)-1][3]
		 #t = threading.Timer(float(duration)-0.05,lambda:autoupdate(sender , int(scene)+1) )
		 #clear(sender)
		 #for qq in range():
		 
		 for www in self.boad:
		  we=www[0]
		  #buttonbg= sender.superview[we]
		  if [we,0] in self.boad:
		   ww=self.boad.index([we,0])
		  else:
		   ww=self.boad.index([we,1])
		  #tt=colored[ww]
		  self.boad[ww:ww+1]=[[we,0]]
		  #print(self.boad)
		  #buttonbg.background_color= ('#ffffff')
 #vv=list(v)
		 '''colored
		 '''
 #u=sender.name
 #if [uu,False] in colored:
  #ww=colored.index([uu,False])
 #else:'''
		 for x in v:
		  y=[]
		  
		   
		  #y=x.replace('"','')
		  #print(colored)
		  if [x,0] in self.boad:
		   ww=self.boad.index([x,0])
		  else:
		   ww=self.boad.index([x,1])			  
		  tt=self.boad[ww]
		  #buttonbg= sender.superview[y]
		  self.boad[ww:ww+1]=[[x,1]]
  #buttonbg.background_color= ('#fb99ff')
		  color.append(self.boad[ww][0])
  #tup.append([ww])
		  
		 if boforecolor==None:
		  pass
		 else:
		  for bef in boforecolor:
		   #buttonbg=sender.superview[bef]
		   if bef in color:
		     pass
		   else:
		   	self.block[bef].fill_color=boadcolor[0]
		   	
		    #buttonbg.background_color= ('#ffffff')
		 
		 for co in color:
		  #buttonbg=sender.superview[co]
		  if co in boforecolor:
		    pass
		  else:
		  	self.block[co].fill_color=boadcolor[1]
		    #buttonbg.background_color= ('#fb99ff')
		 
		 
		 ssd=(time.time()-self.epoctime-self.alltime+self.duration)
		 
		 print('.                     .',ssd,self.scenes,str(self.checkcolor)+'Blocks')
		 if self.debugmode==False:
		  pass
		 else:
		  sse=int(ssd*1000)
		  #wwq=time.time()-self.epoctime-self.alltime+self.duration,self.scenes,str(self.checkcolor)
		  self.score_label.text=str(self.dataprev[self.scenes-1])+str(self.scenes)+'  '+str(sse)
		 
		 
		 
		 #colV.text = str(v)
#t.start()
		
		
		#AutoUpdateNEO

	def autoupdate2(self,scenes):
		 global color
		 
 
		 if self.offlights==None:
		  pass
		 else:
		  for bef in self.offlights[self.scenes]:
		   self.block[bef].fill_color=boadcolor[0]
		 for co in self.onlights[self.scenes]:
		  self.block[co].fill_color=boadcolor[1]
		 self.scenes+=1
		 ssd=(time.time()-self.epoctime-self.alltime+self.duration)
		 print('.                     .',ssd,self.scenes)
		 if self.debugmode==False:
		  pass
		 else:
		  sse=int(ssd*1000)
		  self.score_label.text='Auto'+str(self.dataprev[self.scenes-1])+str(self.scenes)+'  '+str(sse)	
		
		
	def timekeep(self,scenes):
		 if self.scenes==len(self.boadU):
		  self.ready=False
		  self.playing=False
		  pass
		 else:
		  self.duration=self.boadU[int(self.scenes)][3]
		  self.alltime =self.alltime + self.duration
		  self.autoupdate2(self.scenes)
		 
		
		
	def colorchange(self):
			#print(self.boad)
			pass
			
	def did_change_size(self):
		sound.stop_all_effects()
		self.ready=False
		self.playing=False
		#self.remove_all_actions()
		#self.setup()
		pass
	
	def update(self):
		#self.T=time.time()
		
		#print(self.T)
		if self.ready == True:
		 if self.alltime+timeduration<= time.time()-self.epoctime:
		  self.timekeep(self.scenes)
		 
		 
		
		
	
	def touch_began(self, touch):
		
		if self.playing==False:
		  global offsetX,offsetY,blockSize,linecolor,sizemode,scriptFile
		  try:
		   del offsetX,offsetY,blockSize,linecolor,sizemode,scriptFile
		  except :
		   pass
		  self.scenes=0
		  self.alltime=0.0
		  
		  for qwe in self.block.values():
		   qwe.fill_color=boadcolor[0]
		  sound.stop_all_effects()
		  sound.play_effect('arcade:Coin_4')
		  
		  time.sleep(1)
		  ee=time.time()
		  sound.play_effect(musicFile)
		  print(time.time()-ee)
		  t=touch.location
		  print(t)
		  self.playing=True
		  self.ready=True
		  self.epoctime=time.time()
		  self.timekeep(0)
		else:
		 self.touchcount+=1
		 if self.touchcount==3:
		  self.playing=False
		  self.touchcount=0
		  
		 pass
		t=touch.location.x
		if self.debugmode==False :
			pass
		else:
		 
		 if self.scenes==len(self.boadU):
		  
		  self.ready=False
		  self.playing=False
		  pass
		  
		 else:
		  
		  if self.size.w*0.1>=t:
		    print('prev')
		    self.ready=False
		    #self.playing=False
		    self.touchcount=0
		    self.scenes= self.scenes-1
		    #for qwe in self.block.values():
		     #qwe.fill_color=boadcolor[0]
		    self.autoupdate(self.scenes-1)
		    
		  else:
		   if self.size.w*0.8<=t:
		    print('next')
		    self.ready=False
		    #self.playing=True
		    self.touchcount=0
		    self.autoupdate2(self.scenes)
		  
		print(t)
	def stop(self):
	 sound.stop_all_effects()
	
	def touch_moved(self, touch):
		pass
	
	def touch_ended(self, touch):
		pass
		
if __name__ == '__main__':
	run(MyScene(),'portrait', show_fps=True)


```
</div></details>
#次回予告
長くなったので今回はここまで。次は、**スクリプトファイルの作り方**、を紹介します。

https://qiita.com/NSmagnets/items/b4b0f9dfd3673efe80c1