みんなの感動をかたちに
旧製品情報

Shade 11



最新バージョン発売のため、本製品の販売は終了しております。ぜひ最新バージョンをご検討ください。

Shade 12 製品情報・予約

でった☆のスクリプト天国 Shadeゲーム化大作戦

第4回 ニュー・記憶・パラダイス

(掲載日:10.02.19)

こんにちは、でった☆です。
今回は、先週ご紹介した「記憶ゲーム」作りをご紹介します。サンプルをダウンロードして、この記事からコードをコピー&ペーストするだけでも完成しますので、ぜひ作って遊んでみてくださいね。

◆ポリゴンメッシュの面をランダムに選択する「Widget」作り

「記憶ゲーム」では、最初にランダムな順番でポリゴンメッシュの面を次々と選択していきます。まず最初に、この部分を作ってみましょう。

◇面の総数を調べる

最初にポリゴンメッシュの面の総数を「number_of_faces」で調べます。スクリプトウインドウに次のコードを入力して実行すると、選択しているポリゴンメッシュの面の総数がメッセージウインドウに出力されます。

print xshade.scene().active_shape().number_of_faces

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◇リストの作成

このコードを「range」を使って面の番号のリストを作成するように変更しましょう。

print range(xshade.scene().active_shape().number_of_faces)

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◇リストをバラバラに並べ替える

「random.shuffle」で作成したリストの順番をバラバラに並べ替えます。実行すると毎回違う順番のリストが出力されますよ。

import random                      #外部モジュールのインポート
pshape = xshade.scene().active_shape()          #形状を変数に入れる
f_list = range(pshape.number_of_faces)          #面の番号のリストを作る
random.shuffle(f_list)              #ランダムに並べ替える

print f_list                              #出力して確認

このコードの赤字の部分を「コードA」としておきます。

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◇リストの最初の番号で面を選択する

それでは、バラバラにしたリストの最初の番号で、ポリゴンメッシュの面を選択しましょう。図面は選択面が見えるように、「形状編集モード」+「面選択モード」にしておきます。
面を選択するには、面の番号を指定して「active」を「True」に設定します。
設定しただけでは画面が変化しないので、「update」で画面を更新して、面の選択を反映します。
上の「コードA」に次の3行のコードを追加して実行すると、ポリゴンメッシュの面がランダムに選択されます。

xshade.scene().selection_mode = 0                  #面モードを再選択して選択解除
pshape.face(f_list[0]).active = True                  #リストの最初の番号で選択
xshade.scene().figure_view.update()                  #画面を更新して反映させる

この3行を「コードB」とします。

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◇「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ゲーム化大作戦 ニュー・記憶・パラダイス

◇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」とします。

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◇総数の数と比較する

作成したリストの中身の数が、面の総数と同じになれば「選択完了」となります。
スクリプトウインドウに次のコードを追加して実行すると、全部選択されている場合に「OK」が、そうでない場合に「NO」が出力されます。

if len(af_list) != pshape.number_of_faces:
      print 'NO'
else:
      print 'OK'

このコードは「コード2」とします。

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◇選択順のリストに並べ替える

作成したリストは「選択されている面の番号が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 #確認用出力

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◇ランダムリストと比較する

すべての面が選択されたら「答え合わせ」に移ります。上で作成したリストとランダムリストを比較して、同じならば正解、違えば不正解とします。
ここでは仮のランダムリストとして、選択しているポリゴンメッシュの面が4つなので、[3,1,0,2]というリストを用意しました。
スクリプトウインドウの一番上に次のコードを追加します。

rfl = [3,1,0,2]

コード2に、次のコードを追加します。

      print fl #確認用出力
      if rfl == fl: #ランダムリストと比較
            print '正解'
      else:
            print '不正解'

ポリゴンメッシュの面をすべて選択して実行すると、結果を出力します。

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◇「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);
      }
}

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

◆ゲームの完成

これで記憶ゲームの完成です。実行すると面がランダムな順番で選択されたあとにメッセージが表示されます。shiftキーを押しながら、表示された順番にすべての面を選択して当ててみてください。タイマーのセット時間を300や100にして表示時間を短くし、難易度をあげることもできますよ。面の複雑なポリゴンだともっと難しくなりそうですね。

完成までの手順のムービーは、こちらからご覧になれます。

サンプル動画
クリックして再生

◆次回は「育成ゲーム」

タイマー処理は色々遊べそうですね。次回は複数のタイマーを使って、育成シミュレーションゲーム(もどき)を作ってみましょう。

でった☆のスクリプト天国 Shadeゲーム化大作戦 ニュー・記憶・パラダイス

※この連載では、広く皆様のご意見・ご要望などを募集しています。「artists side」に専用コミュニティ「でった☆のスクリプト天国」を開設していますので、どうぞお気軽にお寄せ下さい。

▲ページ上部へ