C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[36]: PictureBoxを左右に往復するループ [4]


(過去ログ 68 を表示中)

[トピック内 98 記事 (81 - 98 表示)]  << 0 | 1 | 2 | 3 | 4 >>

■39792 / inTopicNo.81)  Re[34]: PictureBoxを左右に往復するループ
  
□投稿者/ 魔界の仮面弁士 (1211回)-(2009/08/13(Thu) 13:45:28)
No39787 (へっぽこ さん) に返信
> ところで早速、修正して作ってみました。
大分良くなってきたと思います。あと少し。

No39675 で、「右端を越えそうなとき」に方向反転させたい、と書かれていましたが、
これだと、「右端を越えてしまった後」で方向反転させていますよね。

今のコードは、
  (1) PictureBox1.Left に idouryou を加算する。
  (2) 加算した結果を、右端の座標と比較し、右端を越えていたら:
   (2.1) idouryou にマイナスの乱数値をセット。
   (2.2) PictureBox1.Left に idouryou を再度加算しなおす。
という処理手順になっていますが、これを
  (1) 「PictureBox1.Left + idouryou」を右端の座標と比較し、右端を越えていたら:
   (1.1) idouryou にマイナスの乱数値をセット。
  (2) PictureBox1.Left に idouryou を加算する。
のようにして、『右端を超えるかどうかを、先に検証する』ようにした方が良いと思います。



> いかがなものでしょうか?
へっぽこさんが今回書かれたコードの動きを追ってみましょう。


>1: PictureBox1.Left += idouryou  '移動量10ずつ右へ進む
>2: If PictureBox1.Left > Me.Width - PictureBox1.Width Then  'もし右端を越えたら
>3:    idouryou = -rn.Next(10)    '負の数の移動量を生成し
>4:    PictureBox1.Left += idouryou  '生成した移動量で左へ進む
>5:  End If

たとえば、この部分を実行する直前の値が
 ・idouryou = 10
 ・「Me.Width - PictureBox1.Width」= 250
 ・PictureBox1.Left = 245
であったと仮定して、上記を一行ずつ追いかけてみます。



>1: PictureBox1.Left += idouryou  '移動量10ずつ右へ進む
ここで、PictureBox1.Left は 245 から 255 になりますよね。

>2: If PictureBox1.Left > Me.Width - PictureBox1.Width Then  'もし右端を越えたら
ここで、[If 255 > 250 Then] が成り立つので、If 文の中身が実行されます。

>3:    idouryou = -rn.Next(10)    '負の数の移動量を生成し
rn.Next(10) の結果は、「0〜9」という範囲になります。
たとえば乱数の結果が 2 だっとしたら、idouryou は -2 になりますね。

>4:    PictureBox1.Left += idouryou  '生成した移動量で左へ進む
idouryou が -2 なので、PictureBox1.Left は 255 から 253 になります。

>5:  End If
この場合、右端を微妙に越えてしまったままになりますね。


そして次回の処理では、
 ・idouryou = -2
 ・「Me.Width - PictureBox1.Width」= 250
 ・PictureBox1.Left = 253
の状態から開始されますが、実行すると PictureBox1.Left += idouryou により、
その座標は 253 から 251 に変化することになります。
左に進んではいますが、それでもまだ微妙に右端の座標(250)を越えたままですね。


そしてさらに次の回では、251 から 249 に変化します。
ようやくここで、右端から離れる事になります。


左端を越えた場合についても同様で、多少、画面の端に食い込んだ状態で
方向転換が始まることになりますね。



> 思った通りの動きをしているのですが、
画面の端ぴったりの位置で反転させたいのであれば、まだ修正の余地がありますが、
上記が目的の動作であるならば、今のままでも問題無いと思います。

引用返信 編集キー/
■39793 / inTopicNo.82)  Re[35]: PictureBoxを左右に往復するループ
□投稿者/ biac (153回)-(2009/08/13(Thu) 13:57:11)
biac さんの Web サイト
>>思った通りの動きをしているのですが、いかがなものでしょうか?(これも教えて君になるかな?)
>
> 「思った通りの動きをしている」んならいぃんじゃないすか。

…だけど。 ほんとに「思った通りの動きをしている」のかしらん?

・いままでの話の流れ
左右への動きは、 1回ごとに移動量を乱数で決定させる。

・今回のコード
左右への動きは、 端から端まで移動させている間は、 毎回同じ移動量。

あと、 コメントに「嘘」がありますね。
> PictureBox1.Left += idouryou  '移動量10ずつ右へ進む

PictureBox1.Left += idouryou  '以前に生成した移動量ずつ右へ (負のときは左へ) 進む
引用返信 編集キー/
■39796 / inTopicNo.83)  Re[35]: PictureBoxを左右に往復するループ
□投稿者/ 魔界の仮面弁士 (1212回)-(2009/08/13(Thu) 15:00:28)
No39792 (魔界の仮面弁士) に追記
> 多少、画面の端に食い込んだ状態で方向転換が始まることになりますね。
> 
>>思った通りの動きをしているのですが、
> 画面の端ぴったりの位置で反転させたいのであれば、まだ修正の余地がありますが、
> 上記が目的の動作であるならば、今のままでも問題無いと思います。

どのように実装すべきかは、へっぽこさんが作りたいアプリの仕様次第なのですが、
No39675
>>>> PictureBox1.Left が右端を越えそうなとき、あるいは左端を越えそうなとき
という仕様は、以下のいずれの動作を想定しておられますか?

# 下記のテキスト図の [@@@] が、移動対象の PictureBox を表しています。
# 右に +4 ずつ進んでいき、右端で移動量が -5 に変化するイメージです。


≪今のコードの動き≫
____________________@@@_________| 
      ↓+4移動
________________________@@@_____|
      ↓+4移動
____________________________@@@_|
      ↓+4移動させると右端を越えるが、そのまま移動させる
________________________________@@@  移動量を-5に変更
      ↓-5移動
__________________________@@@___|
      ↓-5移動
_____________________@@@________|
      ↓-5移動
________________@@@_____________|

→画面の端を越えてから移動方向が反転するため、画像の一部が隠れてしまう事がある。




≪修正案A≫
____________________@@@_________| 
      ↓+4移動
________________________@@@_____|
      ↓+4移動
____________________________@@@_|
      ↓+4移動させると右端を越えるので、右端で止める
_____________________________@@@|  移動量を-5に変更
      ↓-5移動
________________________@@@_____|
      ↓-5移動
___________________@@@__________|
      ↓-5移動
______________@@@_______________|

→画面の端ぴったりで反転させるために、端に到達する瞬間、移動量が小さくなってしまう。



≪修正案B≫
____________________@@@_________| 
      ↓+4移動
________________________@@@_____|
      ↓+4移動
____________________________@@@_|
      ↓+4移動させると右端を越えるので、右端到達前に移動方向を反転させる(例:-5にする)
_______________________@@@______|
      ↓-5移動
__________________@@@___________|
      ↓-5移動
_____________@@@________________|

→画面の端に到達するよりも前に、方向が反転しているように見えてしまう。



≪修正案C≫
画面端を越える事が無いよう、幅に対して、ちょうど割り切れる値を移動量に設定する。

引用返信 編集キー/
■39798 / inTopicNo.84)  Re[36]: PictureBoxを左右に往復するループ
□投稿者/ へっぽこ (40回)-(2009/08/13(Thu) 18:14:16)
2009/08/13(Thu) 19:41:44 編集(投稿者)
No39793 (biac さん) に返信

biac さん、お世話になりました。あらためてお礼申し上げます。
作りたかったプログラムはアバウトなものでしたので、左右に移動ループができればといった
程度のものでした。すみません。


解決済み
引用返信 編集キー/
■39800 / inTopicNo.85)  Re[36]: PictureBoxを左右に往復するループ
□投稿者/ へっぽこ (41回)-(2009/08/13(Thu) 18:26:40)
No39796 (魔界の仮面弁士 さん) に返信
非常に精緻に説明していただき恐れ入ります。
作りたいと思ったプログラムは、とにかく左右に移動ループをして、その速度が変化すればいいかな
といったアバウトな考えで取り組みました。
ですから、自分の思った通りのプログラムなのかと問われたら、そうではないのかもしれませんが、
今は、これで「いいかな^^;」といったところです(私はアバウトな人間なものですから)
教えていただいたことは、今後の課題にしたいと思ってます。また、いつかきっとやくにたつものと
思っています。

有り難うございました。



解決済み
引用返信 編集キー/
■39806 / inTopicNo.86)  Re[30]: PictureBoxを左右に往復するループ
□投稿者/ sos (2回)-(2009/08/13(Thu) 19:13:47)
> 嘘とは、「事実を曲げてこしらえたこと」ですよね。
> ここは、嘘ではなく「まちがい」と訂正してくださいね。(^_^;)

行間も読めない、ソースも読めない……。
引用返信 編集キー/
■39807 / inTopicNo.87)  Re[37]: PictureBoxを左右に往復するループ
□投稿者/ みきぬ (607回)-(2009/08/13(Thu) 19:21:33)
No39798 (へっぽこ さん) に返信
> 嘘とは、「事実を曲げてこしらえたこと」ですよね。
>
「嘘」には単に「事実でないこと」という意味もありますし、「まちがい」という意味もあります。
引用返信 編集キー/
■39808 / inTopicNo.88)  Re[38]: PictureBoxを左右に往復するループ
□投稿者/ へっぽこ (42回)-(2009/08/13(Thu) 19:34:30)
2009/08/13(Thu) 19:41:05 編集(投稿者)
No39807 (みきぬ さん) に返信
> ■No39798 (へっぽこ さん) に返信
>>嘘とは、「事実を曲げてこしらえたこと」ですよね。
>>
> 「嘘」には単に「事実でないこと」という意味もありますし、「まちがい」という意味もあります。

確かにそうですが、ニュアンス的にどうでしょうか?
sosという謎の人からも説明の足りないレス?がきてますので

私の発言が火種になっては困りますので削除します。
関係各位にご迷惑かけました

解決済み
引用返信 編集キー/
■39809 / inTopicNo.89)  Re[31]: PictureBoxを左右に往復するループ
□投稿者/ へっぽこ (43回)-(2009/08/13(Thu) 19:51:32)
感謝をこめて
このたびの私の質問には88ものレスがつきました。皆様にはお忙しいところ時間をさいて
書き込みをしていただきましたこと衷心よりお礼申し上げる次第です。
特にεπιστημη さんには解決のヒントをいただき深く感謝いたします。
失礼なこともたくさん申し上げたことと思います。この場をかりまして深くお詫びいたします。
皆様のますますのご健康とご発展を心より祈念いたしております。
ありがとうございました。

解決済み
引用返信 編集キー/
■39813 / inTopicNo.90)  Re[37]: PictureBoxを左右に往復するループ
□投稿者/ biac (154回)-(2009/08/13(Thu) 20:41:16)
biac さんの Web サイト
No39798 (へっぽこ さん) に返信
> 作りたかったプログラムはアバウトなものでしたので、左右に移動ループができればといった
> 程度のものでした。すみません。

ということは、ひとまず完成ですね。
おつかれさまでした。

ちなみに、日本語のカギ括弧の用法としては、会話や引用のほかに、強調したり、あるいは、本当はそうでは
ないということを表現するために使うことがあります。
wikipedia: http://ja.wikipedia.org/wiki/%E6%8B%AC%E5%BC%A7
/*
# 旧来、人の会話部分を庵点を示す「&#12349;」と改行を示す記号の鈎画の間とに囲まれていたところから、
  会話の箇所を囲む括弧として鉤括弧が出来たと言われている。
# 引用(引用符としての用法)、あるいは特に注意を喚起する語句を挿入する場合も用いられるように
   なった。
  * 題目(題名・表題・外題・箇条・主題・問題・名目)などを特に提示する場合に用いる。
  * 「いわゆる」「いわば」という、言葉を文字通りに受け取ってはいけないということを示す
*/


なお、 参考までに、できるだけロジックを変えないようにして、読みやすくしてみたコードを載せておきます。
この程度のロジックだと、Timer1_Tick の全部の内容が、ひとつの 入力〜処理〜出力 という流れとして、
書けます。 ( 入力〜処理〜出力 が入り組んできたら、それはメソッドを分割すべき徴候 )

Option Explicit On
Option Strict On
Option Infer On
Option Compare Binary

Public Class Form1

    Private _前回の横方向移動ベクトル As Integer = 10
    Private _乱数発生器 As Random = New Random()


    Private Sub Form1_FormClosed(ByVal sender As System.Object, _
            ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
        Me.Timer1.Enabled = False   'Dispose() 前にタイマーを止めておく。 (まぁ、不要だけど。 f(^^; )
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
            Handles Button1.Click
        Me.Timer1.Enabled = Not Me.Timer1.Enabled
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
            Handles Timer1.Tick
        Me.画像を移動させる()
    End Sub


    Private Sub 画像を移動させる()
        '* 入力 (処理に必要なデータを取得させる)
        Dim 現在のx座標 As Integer = Me.PictureBox1.Left
        'Dim 現在のy座標 As Integer = Me.PictureBox1.Top
        Dim 今回の横方向移動ベクトル As Integer = Me._前回の横方向移動ベクトル


        '* 処理 : 新しい位置を決定させる (注意: 処理中は、メンバー変数を書き換えさせないようにすること)

        Dim 新しいx座標 As Integer = 現在のx座標 + 今回の横方向移動ベクトル
        Dim 新しいy座標 As Integer = Me._乱数発生器.Next(400)

        If Me.画像が右端からはみ出しているか(新しいx座標) Then
            今回の横方向移動ベクトル = -Me._乱数発生器.Next(10)
            新しいx座標 = 新しいx座標 + 今回の横方向移動ベクトル
        ElseIf Me.画像が左端からはみ出しているか(新しいx座標) Then
            今回の横方向移動ベクトル = Me._乱数発生器.Next(10)
            新しいx座標 = 新しいx座標 + 今回の横方向移動ベクトル
        End If


        '* 出力 (メンバ変数へ書き出させる 〜 画像を新しい位置に移動させ、 横方向移動ベクトルを保存させる)
        Me.PictureBox1.Left = 新しいx座標
        Me.PictureBox1.Top = 新しいy座標
        Me._前回の横方向移動ベクトル = 今回の横方向移動ベクトル
    End Sub

    Private Function 画像が右端からはみ出しているか(ByVal 画像のx座標 As Integer) As Boolean
        Dim 画像右端のx座標 = 画像のx座標 + Me.PictureBox1.Width
        Return (Me.DisplayRectangle.Width < 画像右端のx座標)
    End Function

    Private Function 画像が左端からはみ出しているか(ByVal 画像のx座標 As Integer) As Boolean
        Return (画像のx座標 < 0)
    End Function

End Class

解決済み
引用返信 編集キー/
■39814 / inTopicNo.91)  Re[32]: PictureBoxを左右に往復するループ
□投稿者/ みきぬ (608回)-(2009/08/13(Thu) 20:48:51)
戯れに作ってみて、ごみ箱に捨てるのもアレなので載っけておきます。

    Dim 方向 As Point = New Point(1, 0)
    Dim 乱数 As Random = New Random()

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Dim 移動量 As Integer = 乱数.Next(1, 11)

        For i As Integer = 1 To 4
            Dim 進んだ先 As Rectangle = New Rectangle(PictureBox1.Location + New Point(方向.X * 移動量, 方向.Y * 移動量), PictureBox1.Size)

            ' 進んだ先も画面内かな?
            If Me.ClientRectangle.Contains(進んだ先) Then
                ' それじゃ、安心して進もうか
                PictureBox1.Location += New Point(方向.X * 移動量, 方向.Y * 移動量)
                Return
            End If

            ' 時計回りに方向転換
            方向 = New Point(-方向.Y, 方向.X)
        Next

        ' どうやっても進めない
        Timer1.Stop()
        MessageBox.Show("隊長、これ以上進めないであります><")

    End Sub

引用返信 編集キー/
■39815 / inTopicNo.92)  Re[32]: PictureBoxを左右に往復するループ
□投稿者/ biac (155回)-(2009/08/13(Thu) 20:53:29)
biac さんの Web サイト
では、 レスしてくれた方々 ( επι さん除く ) に宿題 f(^^;

タイマー割り込みごとに、 移動量を 0 〜 9 のいずれかに乱数で決めるとすると、 メンバー変数 idouryou だけを使う方法に問題は無いか? 移動量が 1 〜 10 ならばどうか?
また、同様のときに、端からはみだしていたら単純に反転させる (移動方向を逆にする) 方法に、問題は無いか?
解決済み
引用返信 編集キー/
■39831 / inTopicNo.93)  Re[38]: PictureBoxを左右に往復するループ
□投稿者/ へっぽこ (44回)-(2009/08/14(Fri) 11:39:07)
2009/08/14(Fri) 13:27:18 編集(投稿者)
No39813 (biac さん) に返信
> ということは、ひとまず完成ですね。
> おつかれさまでした。

ありがとうございます。お世話になりました。

さすがは、上級者のソースですね。とても参考になります。私はいつになったらこのような芸術的なソースをかけるのかしら(^^;)

愚鈍な私にもわかるように日本語で書いていただきありがとう。
 
> Option Explicit On
> Option Strict On
> Option Infer On
> Option Compare Binary
> 
> Public Class Form1
> 
>     Private _前回の横方向移動ベクトル As Integer = 10
>     Private _乱数発生器 As Random = New Random()
> 
> 
>     Private Sub Form1_FormClosed(ByVal sender As System.Object, _
>             ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
>         Me.Timer1.Enabled = False   'Dispose() 前にタイマーを止めておく。 (まぁ、不要だけど。 f(^^; )
>     End Sub
> 
>     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
>             Handles Button1.Click
>         Me.Timer1.Enabled = Not Me.Timer1.Enabled
>     End Sub
> 
>     Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
>             Handles Timer1.Tick
>         Me.画像を移動させる()
>     End Sub
> 
> 
>     Private Sub 画像を移動させる()
>         '* 入力 (処理に必要なデータを取得させる)
>         Dim 現在のx座標 As Integer = Me.PictureBox1.Left
>         'Dim 現在のy座標 As Integer = Me.PictureBox1.Top
>         Dim 今回の横方向移動ベクトル As Integer = Me._前回の横方向移動ベクトル
> 
> 
>         '* 処理 : 新しい位置を決定させる (注意: 処理中は、メンバー変数を書き換えさせないようにすること)
> 
>         Dim 新しいx座標 As Integer = 現在のx座標 + 今回の横方向移動ベクトル
>         Dim 新しいy座標 As Integer = Me._乱数発生器.Next(400)
> 
>         If Me.画像が右端からはみ出しているか(新しいx座標) Then
>             今回の横方向移動ベクトル = -Me._乱数発生器.Next(10)
>             新しいx座標 = 新しいx座標 + 今回の横方向移動ベクトル
>         ElseIf Me.画像が左端からはみ出しているか(新しいx座標) Then
>             今回の横方向移動ベクトル = Me._乱数発生器.Next(10)
>             新しいx座標 = 新しいx座標 + 今回の横方向移動ベクトル
>         End If
> 
> 
>         '* 出力 (メンバ変数へ書き出させる 〜 画像を新しい位置に移動させ、 横方向移動ベクトルを保存させる)
>         Me.PictureBox1.Left = 新しいx座標
>         Me.PictureBox1.Top = 新しいy座標
>         Me._前回の横方向移動ベクトル = 今回の横方向移動ベクトル
>     End Sub
> 
>     Private Function 画像が右端からはみ出しているか(ByVal 画像のx座標 As Integer) As Boolean
>         Dim 画像右端のx座標 = 画像のx座標 + Me.PictureBox1.Width
>         Return (Me.DisplayRectangle.Width < 画像右端のx座標)
>     End Function
> 
>     Private Function 画像が左端からはみ出しているか(ByVal 画像のx座標 As Integer) As Boolean
>         Return (画像のx座標 < 0)
>     End Function
> 
> End Class
> 

解決済み
引用返信 編集キー/
■39835 / inTopicNo.94)  Re[33]: PictureBoxを左右に往復するループ
□投稿者/ sdk (1回)-(2009/08/14(Fri) 13:18:47)
>変数を日本語で書けることは知りませんでした。しかし、初心者の私にはいささか抵抗があります。('_')
>わかりやすいとは思うのですが日本語はコメントだけでよいのでは、と思いました。生意気にすみません。

あなたのレベルに合わせた提案ですよ?

引用返信 編集キー/
■39836 / inTopicNo.95)  Re[34]: PictureBoxを左右に往復するループ
□投稿者/ へっぽこ (45回)-(2009/08/14(Fri) 13:25:53)
2009/08/14(Fri) 13:30:05 編集(投稿者)
No39835 (sdk さん) に返信
> あなたのレベルに合わせた提案ですよ?
 
気づきませんでした。おしえてくれてありがとね。(^O^)

解決済み
引用返信 編集キー/
■39838 / inTopicNo.96)  Re[35]: PictureBoxを左右に往復するループ
□投稿者/ みきぬ (611回)-(2009/08/14(Fri) 14:01:54)
> 変数を日本語で書けることは知りませんでした。しかし、初心者の私にはいささか抵抗があります。('_')
> わかりやすいとは思うのですが日本語はコメントだけでよいのでは、と思いました。生意気にすみません。

元の文章を直しちゃったみたいだけど…。日本語の変数名に違和感を感じるのは別におかしいことではないよ。
私も普段の開発ではまず使わないけど、説明が省けるぶん投稿が短くて済むんで、掲示板に貼り付けるときはたまにそうする。
引用返信 編集キー/
■39858 / inTopicNo.97)  Re[36]: PictureBoxを左右に往復するループ
□投稿者/ へっぽこ (46回)-(2009/08/14(Fri) 19:23:02)
No39838 (みきぬ さん) に返信
 
> 元の文章を直しちゃったみたいだけど…。日本語の変数名に違和感を感じるのは別におかしいことではないよ。
> 私も普段の開発ではまず使わないけど、説明が省けるぶん投稿が短くて済むんで、掲示板に貼り付けるときはたまにそうする。

そうですか。
みきぬさんのソースも参考にさせていただきます。ありがとう(^_^)/~

解決済み
引用返信 編集キー/
■39907 / inTopicNo.98)  Re[33]: PictureBoxを左右に往復するループ
□投稿者/ biac (156回)-(2009/08/17(Mon) 19:12:18)
biac さんの Web サイト
> では、 レスしてくれた方々 ( επι さん除く ) に宿題 f(^^;
>
> タイマー割り込みごとに、 移動量を 0 〜 9 のいずれかに乱数で決めるとすると、 メンバー変数 idouryou だけを使う方法に問題は無いか? 移動量が 1 〜 10 ならばどうか?
> また、同様のときに、端からはみだしていたら単純に反転させる (移動方向を逆にする) 方法に、問題は無いか?


この回答編を、 TDD.NET に書きました。↓

http://www.tdd-net.jp/2009/08/tdd-winform-gui.html
> [TDD の練習] WinForm を改造したい 〜 GUI に埋もれたロジックを分離して、ユニットテストを書く

また、 ( というか、 そっちが本題だったりするのですが、 ) WinForm のコードから、 ロジックを切り出してテスト可能にする手順の例も示しましたので、 そのあたりに興味のある方もどうぞ。


解決済み
引用返信 編集キー/

<前の20件
トピック内ページ移動 / << 0 | 1 | 2 | 3 | 4 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -