- スペシャル
- Shade 12 関連記事
- Shadeユーザー訪問記
- ジプシーIKEDAの制作日記
- Vue つまみ食い!
Shadeユーザーのための連携講座 - modo つまみ食い!
Shadeユーザーのための連携講座 - 園田浩二の立体視マニアックス
- SPEEDフォーマットについて
- Shadeギャラリー
- ムービー
- ユーザ作品ギャラリー1
- ユーザ作品ギャラリー2
- ユーザ作品ギャラリー3
- TOP画像ギャラリー
Shadeユーザー訪問記:マンガ家 寺沢武一先生 ~心さえ新しければアイデアはいつでも生まれる~(12.14) 日本の「デジタルマンガ」の生みの親、マンガ界の大御所である寺沢武一先生の仕事部屋にお邪魔しました。いつまでも熱くて格好いい男、寺沢先...
Shade 12 ムービーツアー:ミラーリングとマグネット (12.14)Shade 12 に新規に追加されたミラーリング機能、マグネット機能についてご紹介します。
でった☆のスクリプト天国 Shadeゲーム化大作戦
第4回 ニュー・記憶・パラダイス
(掲載日:10.02.19)
こんにちは、でった☆です。
今回は、先週ご紹介した「記憶ゲーム」作りをご紹介します。サンプルをダウンロードして、この記事からコードをコピー&ペーストするだけでも完成しますので、ぜひ作って遊んでみてくださいね。
◆ポリゴンメッシュの面をランダムに選択する「Widget」作り
「記憶ゲーム」では、最初にランダムな順番でポリゴンメッシュの面を次々と選択していきます。まず最初に、この部分を作ってみましょう。
◇面の総数を調べる
最初にポリゴンメッシュの面の総数を「number_of_faces」で調べます。スクリプトウインドウに次のコードを入力して実行すると、選択しているポリゴンメッシュの面の総数がメッセージウインドウに出力されます。
print xshade.scene().active_shape().number_of_faces
◇リストの作成
このコードを「range」を使って面の番号のリストを作成するように変更しましょう。
print range(xshade.scene().active_shape().number_of_faces)
◇リストをバラバラに並べ替える
「random.shuffle」で作成したリストの順番をバラバラに並べ替えます。実行すると毎回違う順番のリストが出力されますよ。
import random #外部モジュールのインポート
pshape = xshade.scene().active_shape() #形状を変数に入れる
f_list = range(pshape.number_of_faces) #面の番号のリストを作る
random.shuffle(f_list) #ランダムに並べ替える
print f_list #出力して確認
このコードの赤字の部分を「コードA」としておきます。
◇リストの最初の番号で面を選択する
それでは、バラバラにしたリストの最初の番号で、ポリゴンメッシュの面を選択しましょう。図面は選択面が見えるように、「形状編集モード」+「面選択モード」にしておきます。
面を選択するには、面の番号を指定して「active」を「True」に設定します。
設定しただけでは画面が変化しないので、「update」で画面を更新して、面の選択を反映します。
上の「コードA」に次の3行のコードを追加して実行すると、ポリゴンメッシュの面がランダムに選択されます。
xshade.scene().selection_mode = 0 #面モードを再選択して選択解除
pshape.face(f_list[0]).active = True #リストの最初の番号で選択
xshade.scene().figure_view.update() #画面を更新して反映させる
この3行を「コードB」とします。
◇「Widget」を作る
「Widget」のベースになる「sample04」を用意しましたので、こちらよりダウンロードしてください。
インストールの方法や、編集の方法については、こちらを御覧下さい。
◇「index.html」の2箇所に「Python」を書き込む
「index.html」を開き、「ランダムなリスト作成」用の「コードA」と、「面の選択」用の「コードB」を、それぞれ別の「textarea」に書き込みます。
「#◆◆ここからPythonを書く(1)◆◆」に、「コードA」を書きこみます。
「コードA」の最後には「JavaScript」にリストを渡すための処理を追加します。
result = str(f_list) #JavaScriptにリストを文字に変換して渡す
「#◆◆ここからPythonを書く(2)◆◆」に、「コードB」に処理を追加した次のコードを書きこみます。赤字の部分が元の「コードB」の3行です。
xshade.scene().selection_mode = 0 #面モードを再選択して選択解除
if f_list == []: #リストが空になった時
result = '-1' #表示終了の「-1」を渡す
else: #リストが空でない場合は表示
pshape = xshade.scene().active_shape() #形状を変数に入れる
pshape.face(f_list[0]).active = True #リストの最初の番号で選択
xshade.scene().figure_view.update() #画面を更新して反映させる
f_list.pop(0) #リストの最初の要素を削除
result = str(f_list) #JavaScriptにリストを文字に変換して渡す
◇Shadeで確認
「sample04」には「Python」以外の「HTML」と「JavaScript」が書いてありますので、「Python」を書き入れたらすぐに動作確認ができるようになっています。スクリプトメニューから「sample04」を実行して、ポリゴンメッシュの面がランダムに選択されることを確認しましょう。
ここまでの手順のムービーは、こちらからご覧になれます。
◆ゲーム要素を追加する
この「Widget」に「選択した面の順番をすべて当ててもらう」モードを追加して、ゲームを完成させましょう。
◇選択面の数を調べる
まず、ユーザーが面をすべて選択しているかどうかを「active」で調べます。
スクリプトウインドウに次のコードを入力して実行すると、選択されている面の番号リストが出力されます。
※Shade11では、「active_face_indices」で直接リストを作成できます。
af_list = []
pshape = xshade.scene().active_shape()
for i in xrange(pshape.number_of_faces):
if pshape.face(i).active:
af_list.append(i)
print af_list
これを「コード1」とします。
◇総数の数と比較する
作成したリストの中身の数が、面の総数と同じになれば「選択完了」となります。
スクリプトウインドウに次のコードを追加して実行すると、全部選択されている場合に「OK」が、そうでない場合に「NO」が出力されます。
if len(af_list) != pshape.number_of_faces:
print 'NO'
else:
print 'OK'
このコードは「コード2」とします。
◇選択順のリストに並べ替える
作成したリストは「選択されている面の番号が0から順番に入っている」リストなので、これを「選択された順番で面の番号が入っている」リストに「active_order」と「sort」を使って並べ替えます。実行すると、作成途中のリストがそれぞれ出力されます。
コード1の赤字の部分を「選択番号と面」のセットを追加するように変更します。
if pshape.face(i).active:
af_list.append([pshape.face(i).active_order,i])
コード2の赤字の部分にリストの並べ替え処理を追加します。
else:
print 'OK'
af_list.sort() #リストを選択順に並べ替える
print af_list #確認用出力
afl = [] #空のリスト作成
for i in af_list:
fl.append(i[1]) #af_listの面番号だけを追加する
print fl #確認用出力
◇ランダムリストと比較する
すべての面が選択されたら「答え合わせ」に移ります。上で作成したリストとランダムリストを比較して、同じならば正解、違えば不正解とします。
ここでは仮のランダムリストとして、選択しているポリゴンメッシュの面が4つなので、[3,1,0,2]というリストを用意しました。
スクリプトウインドウの一番上に次のコードを追加します。
rfl = [3,1,0,2]
コード2に、次のコードを追加します。
print fl #確認用出力
if rfl == fl: #ランダムリストと比較
print '正解'
else:
print '不正解'
ポリゴンメッシュの面をすべて選択して実行すると、結果を出力します。
◇「index.html」に「Python」を追加する
「#◆◆ここからPythonを書く(2)◆◆」に、メッセージ表示処理を追加します。赤字の部分が追加した部分です。
if f_list == []: #リストが空になった時はメッセージ表示
xshade.show_message_box('選択された順番で面をすべて選択してください',False)
result = '-1' #表示終了の「-1」を渡す
「#◆◆ここからPythonを書く(3)◆◆」にスクリプトウインドウのコードを書きこみます。「print」のいくつかを「result」に変更し、不要な「print」は削除しました。赤字の部分が変更した部分です。1行目の「rfl=」も削除します。
af_list = [] #空のリスト作成
pshape = xshade.scene().active_shape()
for i in xrange(pshape.number_of_faces): #選択状態を調べる
if pshape.face(i).active: #選択されている場合
#選択順と面番号をセットにしてリストに追加
af_list.append([pshape.face(i).active_order,i])
if len(af_list) != pshape.number_of_faces: #全部選択されていない場合
result = "0" #JavaScriptに「0」を渡す
else: #全部選択されている場合
af_list.sort() #リストを選択順に並べ替える
fl = [] #空のリスト作成
for i in af_list:
fl.append(i[1]) #af_listの面番号だけを追加する
if rfl == fl: #ランダムリストと同じなら正解の「1」を渡す
result = "1"
else: #ランダムリストと違うなら不正解の「-1」を渡す
result = "-1"
◇「JavaScript」の終了処理をタイマー呼び出し処理に変更する
「index.html」の「function view_face」のコードを一箇所書き換えます。
if(f_list == "-1"){
alert('終了しました');
上の赤字の部分を、下の赤字部分のように「選択状態と正解判定処理用」タイマー呼び出しコードに書き換えます。
/*面の表示を繰り返す*/
function view_face(f_list){
clearTimeout(timerID);
py_src = "f_list = " + f_list + "\n";
py_src += document.getElementById('view_face_src').value;
f_list = window.external.setScript(py_src);
if(f_list == "-1"){
timerID = setTimeout("check_selected_face()",100);
} else {
timerID = setTimeout("view_face('" + f_list + "')",1000);
}
}
◆ゲームの完成
これで記憶ゲームの完成です。実行すると面がランダムな順番で選択されたあとにメッセージが表示されます。shiftキーを押しながら、表示された順番にすべての面を選択して当ててみてください。タイマーのセット時間を300や100にして表示時間を短くし、難易度をあげることもできますよ。面の複雑なポリゴンだともっと難しくなりそうですね。
完成までの手順のムービーは、こちらからご覧になれます。
◆次回は「育成ゲーム」
タイマー処理は色々遊べそうですね。次回は複数のタイマーを使って、育成シミュレーションゲーム(もどき)を作ってみましょう。
※この連載では、広く皆様のご意見・ご要望などを募集しています。「artists side」に専用コミュニティ「でった☆のスクリプト天国」を開設していますので、どうぞお気軽にお寄せ下さい。