見出し画像

Rosso Laboratory

第7回その3 1つのキーでパンタグラフを上げ下げしよう

【第1章】車両で遊ぼう
第7回 パンタグラフを上げ下げしよう
その3 1つのキーでパンタグラフを上げ下げしよう
カウンタとなる変数を使ってみましょう。

【使用するPython命令】global
関数内からグローバル変数を扱うための宣言です。

【使用するPython命令】%
剰余演算子で、割り算してその余りを返す。

前回は4つのキーを使ってパンタグラフの4つの状態を再現しましたが、今回はそれを1つのキーを押すたびに変化していく形にしてみましょう。

【やってみよう】「親子で学ぼう用レイアウト(2初期状態).vrmnx」を開き、編成「TRAIN_11」にスクリプトをこのように書こう。書くのが大変ならコピペしよう。完成品は「親子で学ぼう用レイアウト(7-3).vrmnx」です。

#OBJID=11
import vrmapi
keyCount = 0
def vrmevent_11(obj,ev,param):
    if ev == 'init':
        car = obj.GetCar(1)
        car.SetPantograph(0,False)
        car.SetPantograph(1,False)
        obj.SetEventKeyDown('X',106)
(中略)
    elif ev == 'keydown':
        global keyCount
        keyCount = keyCount + 1
        surplus = keyCount % 4
        car = obj.GetCar(1)
        if param['eventUID'] == 106:
            if surplus == 1:
                car.SetPantograph(0,True)
                car.SetPantograph(1,False)
            if surplus == 2:
                car.SetPantograph(0,False)
                car.SetPantograph(1,True)
            if surplus == 3:
                car.SetPantograph(0,True)
                car.SetPantograph(1,True)
            if surplus == 0:
                car.SetPantograph(0,False)
                car.SetPantograph(1,False)
        vrmapi.LOG(surplus)

【解説】さて4つのキーをまとめて1つのキーにするには1回目、2回目、3回目、4回目と回数をカウントする必要があります。また4回目の次は5回目ですが、プログラムにはまた1回目として認識させなければなりません。

では解説です。まず「import vrmapi」の次に「keyCount = 0」が来ています。グローバル変数ですね。あまり使うべきではないのですがカウンタを作る上ではグローバル変数の方が簡単なので一旦グローバル変数で作ります。あとでこれをグローバル変数を使わない形に改造したものも紹介します。

'init'イベント内では前回やったことが書かれ、初期状態はパンタグラフが両方下降した状態になっています。そしてXキーで呼び出される'keydown'イベント内ではまず「global keyCount」と関数外で宣言したグローバル変数をこのイベント内で使うことが宣言がされています。初期値は0で「keyCount = keyCount + 1」を実行する度に1が足されていきます。ここでグローバル変数を使わないとどうなるかというと

def vrmevent_11(obj,ev,param):
    keyCount = 0
    if ev == 'init':

またはこうしても

    elif ev == 'keydown':
        keyCount = 0
        keyCount = keyCount + 1

となるので毎回カウンターがリセットされてしまいカウンターの役目が果たせません。ですのでグローバル変数を使う必要が出てきてしまいます。その後の「surplus = keyCount % 4」は変数surplusにカウンタの数値を4で割った余りを代入しなさいという命令です。よって1回目は1÷4で答え0余り1、2回目は2÷4で答え0余り2、3回目は3÷4で答え0余り3、1回目は4÷4で答え1余り0、5回目は5÷4で答え1余り1・・・となって1、2、3、0を繰り返していきます。よってそれを「if surplus == 1:」などで場合分けしてパンタグラフの昇降を実行しています。またその1、2、3、0をスクリプトLOGウィンドウで確認できるように「vrmapi.LOG(surplus)」が「if param['eventUID'] == 106:」と同列の部分に追加されています。

【実践】それでは「運転」を押してビューワーを起動させましょう。Xキーを押して順番に変化していれば成功です。スクリプトLOGウィンドウも表示して動作を確認してみましょう(^^)/

【使用するVRMNX命令】色々な部品にある命令:GetDict()
dict型メンバー変数を参照します。

【発展】グローバル変数を使わない方法です。完成品は「親子で学ぼう用レイアウト(7-3dict).vrmnx」です。

#OBJID=11
import vrmapi
def vrmevent_11(obj,ev,param):
    di = obj.GetDict()
    if ev == 'init':
        di['keyCount'] = 0
        car = obj.GetCar(1)
        car.SetPantograph(0,False)
        car.SetPantograph(1,False)
        obj.SetEventKeyDown('X',106)
(中略)
    elif ev == 'keydown':
        di['keyCount'] = di['keyCount'] + 1
        surplus = di['keyCount'] % 4
        car = obj.GetCar(1)
        if param['eventUID'] == 106:
            if surplus == 1:
                car.SetPantograph(0,True)
                car.SetPantograph(1,False)
            if surplus == 2:
                car.SetPantograph(0,False)
                car.SetPantograph(1,True)
            if surplus == 3:
                car.SetPantograph(0,True)
                car.SetPantograph(1,True)
            if surplus == 0:
                car.SetPantograph(0,False)
                car.SetPantograph(1,False)
        vrmapi.LOG(surplus)

【解説】辞書(dictionary)型変数diを使います。以前から出てきていますが改めて、辞書型とは{}の中にキーと値の組み合わせが並んだ変数で{キー1:値1,キー2:値2,キー3:値3・・・・}となっています。そしてdi['キー1']と書くと値1を返します。「if ev == 'init':」の前の位置(関数内で有効となる位置)で「di = obj.GetDict()」を書いて変数diを作成し、'init'イベントで「di['keyCount'] = 0」を書いてkeyCountというキーに0を代入(初期化)します。以降はグローバル変数と同様に扱います。こちらが理解出来たらカウンタにはグローバル変数は使わずに辞書型変数を使うようにしましょう。

【余談】なぜ辞書型変数なら大丈夫なのか
def vrmevent_11(obj,ev,param):
    di = obj.GetDict()
    if ev == 'init':
        di['keyCount'] = 0
ここですね。'init'の前で辞書型変数diを定義してvrmevent_11内にスコープがあり、'init'の後で辞書型変数diのキー'keyCount'を初期化しているから初期化は1回しか行われないという点です。di = obj.GetDict()はイベントが発生するたびに実行されますからここにkeyCount = 0みたいな普通のローカル変数を置くと毎回初期化されてしまいますが、辞書型変数定義はここにおいても値は影響を受けません。非常に上手いやり方ですが、これを考え出したのは私ではなく「「鉄道模型シミュレーターnx」で学ぶpythonプログラミング」の著者である角卓さんです。
←戻る 目次 進む→
PVアクセスランキング にほんブログ村


ランキングに参加中。クリックして応援お願いします!

名前:
コメント:

※文字化け等の原因になりますので顔文字の投稿はお控えください。

コメント利用規約に同意の上コメント投稿を行ってください。

 

※ブログ作成者から承認されるまでコメントは反映されません。

  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最新の画像もっと見る

最近の「Pythonスクリプト」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事