VB6.0でタイマーを使用し、交差点での信号機の動きを、タイムチャートをもとに作成したいと思います。例えば、ひとつの信号の赤を4秒、黄色を1秒、青を3秒とします。もうひとつの信号は、ひとつ目の信号が赤のときは青から黄色になって、ふたつ目の信号が赤になったら、ひとつ目の信号が青になるようなプログラムを作成したいと思います。何をどうすればよいのか分かりません。具体的に言えば、記述方法が分かりません。ヒントや、参考になるHPなどを教えてもらえたら助かります。
自分のやりたいことをフローチャートにでもしてみて(イベント駆動型なら状態遷移図のほうがいい?)
それぞれの処理でどのようなプログラムを書かなければならないかを1つ1つ考えてみてください。
それで具体的にやり方が分からないところを1つずつ解決していきましょう。
今されている質問だとまるでこういう仕様のソフトを作って下さいといってるように見えます。
ABCさんと内容が被るのですが…
>記述方法が分かりません。
と書かれていますが、質問が漠然としすぎて
回答するほうも何を答えていいのか分かりません。
動きの流れがもうできているということは、
コーディングのどこかで詰まっているのでしょうか?
めりさんが投稿した中で、何が分からない部分なのですか?
タイマーコントロールの使い方でしょうか?
青→黄色→赤と変化させる方法でしょうか?
片方の信号が赤になったら、もう片方の信号を青にする方法でしょうか?
それとも他の何かでしょうか?
そこを明らかにし、もう一度質問しなおしてください。
あと、蛇足ですが投稿文には改行を入れてくれると読みやすいです(^^;
全くもってその通りだと思います。先のお二方に加えて新しく言う事はありません。
一度に全てを考えようとせず、処理を分割して1つ1つ考えていって下さい。
それでも何も思い浮かばないなら、発想の基となる部品が脳の中に全くできて
いないのでしょう。そのレベルなら、入門本を買ってより多くのサンプルを自分で
つくり、動かして見て下さい。
ま、お金が取れないレベルのサンプルなら…
…時間があると気まぐれにその場で作って載っける事はありますがw。
動作保障はいたしません。
[VB6.0]
Option Explicit
Private mSignalA(7) As ColorConstants
Private mSignalB(7) As ColorConstants
Private mClock As Integer
Private Sub Form_Load()
Dim i As Integer
' 信号1 - 色遷移情報
For i = 0 To 3
mSignalA(i) = vbRed
Next
For i = 4 To 6
mSignalA(i) = vbBlue
Next
mSignalA(7) = vbYellow
' 信号2 - 色遷移情報
For i = 0 To 2
mSignalB(i) = vbBlue
Next
mSignalB(3) = vbYellow
For i = 4 To 7
mSignalB(i) = vbRed
Next
' 初期化
For i = 0 To 1
' Shape
With Me.Shape1(i)
.BackStyle = 1 ' 不透明
.Shape = vbShapeCircle ' 円
End With
Next
mClock = 0
Call Timer1_Timer
' Timer
With Me.Timer1
.Interval = 1000 ' 1秒
.Enabled = True
End With
End Sub
Private Sub Timer1_Timer()
With Me.Timer1
.Enabled = False
End With
Me.Shape1(0).BackColor = mSignalA(mClock)
Me.Shape1(1).BackColor = mSignalB(mClock)
If mClock = 7 Then
mClock = 0
Else
mClock = mClock + 1
End If
With Me.Timer1
.Enabled = True
End With
End Sub
一番分からないのは、例えば赤4秒の間に、青3秒、黄色1秒にするという記述が
分からないです。
今のところ、赤,青,黄に変化をさせることはできるのですが、
今の記述ではインターバルが全て3秒のため、片方が赤のときに、
もう一方は黄色になっていたりしています。道路にある信号と
同じ動きをさせたいので、うまくインターバルを取りたいのですが
タイマーを何個か使ってもうまくいかず、困っています・・・。
最も簡単な方法は各信号のサイクルを8秒にし、
青(123)→黄(4)→赤(5678)と変化させることです。
そして希望のカウント数に達した時に、2つ目の信号のサイクルを
スタートさせれば終わりですね。
あとは何もしなくても動きの同期は取れるでしょう。
(考え方としては、まるるうさんのサンプルとほぼ同じです)
しかしこの方法では、各信号のサイクルが違う時には対応できませんが…
カウントと色の遷移を文字で表すとこんな感じですね。
1つ目:青(123)→黄(4)→赤(5678)
2つ目:青(567)→黄(8)→赤(1234)
にょもさんへ
サイクルの設定はどのような記述にすればよいのでしょうか?
…めりさんへの回答はにょもさんに任せてw
各信号のサイクルが違う時は…もう、青と黄の遷移だけ制御して
残りは赤…ってのでできそうですね。
・1組目の信号が青から黄の表示(2組目の信号はずっと赤)
・終わったら赤にして2組目に制御を渡す
・2組目の信号が青から黄の表示(1組目の信号はずっと赤)
・終わったら赤にして1組目に制御を渡す
このパターンなら6差路とかでも有効ですねぇ。
…時差信号になるともう一工夫?
……でも制御を渡すまでにその組の中で片方だけ色を変えれば
いいのかな?青と黄の遷移が順に発生していく感じ。特に
同期とか考えないけどこのパターンの方が応用が利きそうですね。
いずれもタイマーは1個でOK。初心者ほどタイマーを多く
使いたくなるけど、ほとんどのプログラムが1個でできます。
>サイクルの設定
まるるうさんがサンプルを作ってくださっていますが、
そちらは動かしてみたのでしょうか?
その中に全てつまっているのですが…(--;
先に書いているように基本的な考え方はまるるうさんと同じです。
サンプルを例に出させてもらいますと、
> If mClock = 7 Then
> mClock = 0
> Else
> mClock = mClock + 1
> End If
の部分が1つのサイクルを意味しています。
私は1〜8と言っていますが、通常プログラムは0で始まることが多いので
0〜7となっているだけなのですが…
希望のカウント数の時に、希望通りの動きを指示してあげれば良いわけです。
サンプルではここの部分ですね。
> Me.Shape1(0).BackColor = mSignalA(mClock)
> Me.Shape1(1).BackColor = mSignalB(mClock)
mSignalA(0 to 7)、mSignalB(0 to 7)の配列には、カウントに対応した
色の情報が入っています。
(Form_Load時に設定しています)
そしてタイマーイベントが起こるたびに、配列内の色情報を
シェイプコントロールに入れてあげてるわけです。
まるるうさんのおっしゃる通り
>青と黄の遷移だけ制御して残りは赤
とする方が汎用性もあり、動きの複雑な信号の動きも再現することが
できるでしょうが、今回は説明を省かせてもらいます。
もう一度サンプルの動きをトレースしてみてください。
まるるぅさんのサンプルを試したのですが、
動かなかったために、再び質問させていただきました。
やりたいことは分かるのですが、記述の方法に手間取っています・・・。
なぜ動かないか、予想はつきます(1つしかないので)
つきますがここではあえて書きません。
以下、老婆心ながら進言させてもらいます。
-----------------------------------------------------
基本的に「動かない」だけではこちらでは解決策の提案はできません。
せめて、「どの行で止まり」「どんなエラーが帰ってくるのか」程度は記述して欲しかったです。
質問すること、それに答えることは、お互いのスキルアップに役立つ貴重な要素です。
しかし、それには相互の情報提供が前提になります。
前回のめりさんの質問によって、私が得られた情報は
「サイクルの設定はどのような記述にすればよいのか分からない」
のみであり、私はサンプルが動かなかったことは全く知りませんでした。
よって、私が出した情報は「サイクルの記述方法」であり、
おまけとして「大まかな動きの流れ」だったわけです。
それに対してのめりさんの次の質問は「実はサンプルが動きません」と言うことでした。
これはサイクルがうんぬんと言う以前に質問すべきことではないですか?
質問の仕方は自由ですが、最低限度の順序と言うものは存在します。
その順序がちぐはぐであったり、理解できないまま先に進んだりすると、
相手を不快にさせたり、自分の理解も中途半端に終わったりと良いことはありません。
一つ一つ理解を深めて行かないと、必ず後で痛い目を見ますのでご注意下さい。
-----------------------------------------------------
以上を踏まえて再度質問させてもらいます。
「めりさんが理解できていないのはいったいどこなんですか?」
回りくどい回答になって申し訳ありませんが、今私がめりさんに求めているものは、
今後プログラマーとして必ず必要になるスキルの一つです。
是非ともこのスキルを身につけて欲しいと思います。
追記:
もし余計なお世話と思われているのであれば、その旨を一言下さい。
次の回答でなぜ動かないかをお答えして、この件は終わりにしたいと思いますm(__)m
まるるぅさんのサンプルを見て、今の自分のプログラムにも
サイクルを記述すれば動くのではないかと思い、まずサイクルの記述法を伺いました。
その上で何度か試してみたものの動かず、まるるぅさんのプログラムを参考に、
勉強してみようと思い、サンプルを動かしてみるというのが後になってしまいました。
そのことによって不快な思いをさせてしまったのなら、申し訳ないという気持ちです。
-------------------------------------------------------------------
実行した結果は、
For i = 0 To 1
' Shape
With Me.Shape1(i)←この部分のエラーでした。
後に色々考えてみた結果、エラーの原因はわかりましたが、実行してもフォームに
何も表示されていませんでした。それがなぜなのかわかりません・・・。
よろしくお願いします。
>後に色々考えてみた結果、エラーの原因はわかりましたが、実行してもフォームに
>何も表示されていませんでした。それがなぜなのかわかりません・・・。
なんか自己完結してて何をしたのか説明してくれてませんが…(^^;)
…それは Shape1 が Shape コントロールをフォームに貼り付けたもので、
『引数の数が一致していません。または不正なプロパティを指定しています。』
のエラーが出て、コントロール配列になってない事に気づいて、コントロール配列に
したと言う事ですか?。
↑何のことを言ってるか分からない場合は[Shape コントロール]と[コントロール配列]
についてヘルプで調べてきて下さい。
Shape コントロールを貼り付けた時点で黒い四角形は表示されてるはずなので
>何も表示されていませんでした。
の状態がどうして起こったかこちらからでは想像できません。
For i = 0 To 1
' Shape
With Me.Shape1(i)
.BackStyle = 1 ' 不透明
.Shape = vbShapeCircle ' 円
End With
Next
はコントロール配列となっている2つの Shape コントロールを
不透明(デフォルトでは白くなります)の円形で表示するコードです。
ここだけ抜き出して実行するなど、どこが上手くいってないのか
デバッグして確認して下さい。
面倒な方法ですが、全ての色の指定をcase文で指定することで解決しました。
お騒がせしました。ありがとうございました。
おせっかいかも知れませんが
バグの根底を解決しない解決は
次回のバグを生み出す気がするのですが
私も力技で解決すること多々ありますが
後から後悔すること多々あります
後悔できるということは
そのソースを書いたときより多少はレベルアップしたという
証拠なのでしょうけど・・・
それに、教えていただいたことをどのように受け取り
どこまで参照し、どこを自分なりに変えたのかもよくわかりませんし・・・
できれば暇な時に少し時間をかけて
今の面倒な方法をシンプルに書き換えて同じ動作をするソースを
仕上げてみてはいかがでしょうか?
ツイート | ![]() |