トップ回答者
VS2017のVisual Basicプログラムについて

質問
-
'指定した位置にボールを動かす
Public Sub Move()
'以前の表示を削除
DeleteCircle()'新しい移動先の計算
Dim x As Integer = positionX + pitch * directionX
Dim y As Integer = positionY + pitch * directionY'壁で跳ね返る補正
If (x >= pictureBox.Width - radius * 2) Then '右端に来た場合の判定
directionX = -1
End If
If (x <= 0) Then '左端に来た場合の判定
directionX = +1
End If
If (y >= pictureBox.Height - radius * 2) Then '下端に来た場合の判定
directionY = -1
End If
If (y <= 0) Then '上端に来た場合の判定
directionY = +1
End If'跳ね返り補正を反映した値で新しい位置を計算
positionX = x + directionX
positionY = y + directionY'新しい位置に描画
PutCircle(positionX, positionY)'新しい位置を以前の値として記憶
previousX = positionX
previousY = positionY
End Sub上記はプログラムの一部なのですが、このプログラムでボールを動かした場合、仮に、positionXを14、pitchを20、directionXを-1とした場合(positionYは適当な数字にします。)、自分の考えでは、xは-6となり、跳ね返り補正を反映した値で新しい位置を計算した場合、positionXは-5となります。しかしプログラムを動かすとマイナスとならずにボールが画面上から消えずにx上の右へ跳ね返ります。どう考えてもわかりません。
どう考えればプログラム実行通りになるのか教えて頂きたいです。
何卒宜しくお願い致します。
回答
-
単に計算式を間違えてるだけじゃないかなぁ
Public Class Form1 Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.Controls.Add(Button1) Me.Controls.Add(Button2) Me.Controls.Add(pictureBox) End Sub Private pictureBox As New PictureBox() With {.Left = 50, .Top = 50, .Width = 200, .Height = 200, .Anchor = AnchorStyles.Left Or AnchorStyles.Right} Private WithEvents Button1 As New Button() With {.Text = "再描画", .Left = 0} Private WithEvents Button2 As New Button() With {.Text = "移動", .Left = 100} Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click DeleteCircle() PutCircle(positionX, positionY) End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click MoveTest() End Sub Private Sub DeleteCircle() Me.pictureBox.Image = Nothing End Sub Private Sub PutCircle(ByVal x As Integer, ByVal y As Integer) Dim bmp As New Bitmap(Me.pictureBox.Width, Me.pictureBox.Height) Using g As Graphics = Graphics.FromImage(bmp) g.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height) '描画は左上基準です g.DrawEllipse(Pens.Red, x, y, radius * 2, radius * 2) End Using Me.pictureBox.Image = bmp End Sub Dim positionX As Integer = 14 Dim positionY As Integer = 20 Dim directionX As Integer = -1 Dim directionY As Integer = 0 'てすとよう Dim radius As Integer = 6 Dim pitch As Integer = 20 Dim previousX As Integer Dim previousY As Integer '指定した位置にボールを動かす Public Sub MoveTest() '以前の表示を削除 DeleteCircle() '新しい移動先の計算 Dim x As Integer = positionX + pitch * directionX Dim y As Integer = positionY + pitch * directionY Dim xあまり As Integer Dim yあまり As Integer '壁で跳ね返る補正 If (x >= pictureBox.Width - radius * 2) Then '右端に来た場合の判定 directionX = -1 xあまり = x - (pictureBox.Width - radius * 2) positionX = (pictureBox.Width - radius * 2) - xあまり ElseIf (x < 0) Then '左端に来た場合の判定 directionX = +1 positionX = 0 - x Else positionX = x End If If (y >= pictureBox.Height - radius * 2) Then '下端に来た場合の判定 directionY = -1 yあまり = y - (pictureBox.Height - radius * 2) positionY = (pictureBox.Height - radius * 2) - yあまり ElseIf (y <= 0) Then '上端に来た場合の判定 directionY = +1 positionY = 0 - y Else positionY = y End If '新しい位置に描画 PutCircle(positionX, positionY) '新しい位置を以前の値として記憶 previousX = positionX previousY = positionY End Sub End Class
#跳ね返り補正を減衰という意味で使っているのでなければ個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク ディッセンバー 2018年2月22日 16:14
すべての返信
-
単に計算式を間違えてるだけじゃないかなぁ
Public Class Form1 Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.Controls.Add(Button1) Me.Controls.Add(Button2) Me.Controls.Add(pictureBox) End Sub Private pictureBox As New PictureBox() With {.Left = 50, .Top = 50, .Width = 200, .Height = 200, .Anchor = AnchorStyles.Left Or AnchorStyles.Right} Private WithEvents Button1 As New Button() With {.Text = "再描画", .Left = 0} Private WithEvents Button2 As New Button() With {.Text = "移動", .Left = 100} Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click DeleteCircle() PutCircle(positionX, positionY) End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click MoveTest() End Sub Private Sub DeleteCircle() Me.pictureBox.Image = Nothing End Sub Private Sub PutCircle(ByVal x As Integer, ByVal y As Integer) Dim bmp As New Bitmap(Me.pictureBox.Width, Me.pictureBox.Height) Using g As Graphics = Graphics.FromImage(bmp) g.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height) '描画は左上基準です g.DrawEllipse(Pens.Red, x, y, radius * 2, radius * 2) End Using Me.pictureBox.Image = bmp End Sub Dim positionX As Integer = 14 Dim positionY As Integer = 20 Dim directionX As Integer = -1 Dim directionY As Integer = 0 'てすとよう Dim radius As Integer = 6 Dim pitch As Integer = 20 Dim previousX As Integer Dim previousY As Integer '指定した位置にボールを動かす Public Sub MoveTest() '以前の表示を削除 DeleteCircle() '新しい移動先の計算 Dim x As Integer = positionX + pitch * directionX Dim y As Integer = positionY + pitch * directionY Dim xあまり As Integer Dim yあまり As Integer '壁で跳ね返る補正 If (x >= pictureBox.Width - radius * 2) Then '右端に来た場合の判定 directionX = -1 xあまり = x - (pictureBox.Width - radius * 2) positionX = (pictureBox.Width - radius * 2) - xあまり ElseIf (x < 0) Then '左端に来た場合の判定 directionX = +1 positionX = 0 - x Else positionX = x End If If (y >= pictureBox.Height - radius * 2) Then '下端に来た場合の判定 directionY = -1 yあまり = y - (pictureBox.Height - radius * 2) positionY = (pictureBox.Height - radius * 2) - yあまり ElseIf (y <= 0) Then '上端に来た場合の判定 directionY = +1 positionY = 0 - y Else positionY = y End If '新しい位置に描画 PutCircle(positionX, positionY) '新しい位置を以前の値として記憶 previousX = positionX previousY = positionY End Sub End Class
#跳ね返り補正を減衰という意味で使っているのでなければ個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク ディッセンバー 2018年2月22日 16:14