こんにちは。
いま、当たり判定に苦戦しています。
それは、単純に言えば「色あたり判定」です。
picture1とpicture2があって、互いの赤い部分が
重なった時にプログラムが終わるなどと言うプログラムを作っているのですが
なかなかできません。
RGB関数かと思ったのですが、いざやってみると使えないのが現状でした。
どうかご教授お願い致します。
RGB関数は、色の3原色から色コードの値を求めるもので、この場合には
ふさわしくないですね。
ある座標の色コードを求める関数はPoint関数です。
point関数について、もう少し説明いただけませんでしょうか?
> LESIA 2005/02/16(水) 21:24:52
> ぞうくん 2005/02/16(水) 21:38:48
到底、調べたとも思えないな。
知らないキーワードが出たら、最低でも
30分は自分で努力して探して見ましょう。
自分で探して解決する能力が身に付きますし、
それでも見つからない時には、
試行錯誤をし、悩んだ分だけ、
いつまでも頭に残って忘れないと思います。
脊髄反射で安直に聞いていては、いつまでも成長できません。
すみませんでした。
反省してます
私なりにいろいろ調べたところ、
pointメソッド
というのがいい。というのがわかりました。
確か構文が
object.point(x,y)
だったと思います。
しかし、これをpicture1/2ふたつに当てはめて調べさせて
当たり判定を作るとなるとわからなくなってしまいます
ご教授いただけないでしょうか?
Point関数ではなくてPointメソッドでしたね。失礼しました。
Picture1とPicture2の赤い部分が重なっているということは、フォームの座標でみると同じ座標ということなので
Picture1.Point(x1, y1) = vbRed
Picture2.Point(x2, y2) = vbRed
だとすると
If x1 + Picture1.Left = x2 + Picture2.Left then
If y1 + Picture1.Top = y2 + Picture2.Top then
MsgBox "あたり"
End If
End If
という感じで出来ます。
pintメソッドを自分でやってみました。
が、なかなか上手くはいきません。
自分なりに、
for X= 0 to 100
for Y= 0 to 80
for X2= 20 to 32
for Y2= 20 to 32
If Picture1.Point(X, Y) = vbRed and Picture2.Point(X2, Y2) = vbRed then
If X + Picture1.Left = X2 + Picture2.Left then
If Y + Picture1.Top = Y2 + Picture2.Top then
MsgBox "あたり"
End If
End If
End if
をsubに入れてみて、
10ミリ秒のタイマーで実行してみたのですが
以前より数十倍重くなり、どうしようもない状態に・・・
どうしたらいいのでしょうか?
なにか他の方法があるのでしょうか?
それともソースがおかしいのでしょうか?
教えてください。お願いします
書きそびれがありました。
2005/02/19(土) 21:12:43
の発言ですが、for文を使っているのは、
それぞれのpictureの赤に該当しうるおおよその場所を
常時チェックすることで、精度を上げたかったからです。
これをふまえてご教授お願いします。
実行速度を速くするコツを…自分でつかめばいいと思われ(ぇ
とりあえず
> for X
> for Y
> for X2
> for Y2
> If Picture1.Point(X, Y) = vbRed and Picture2.Point(X2, Y2) = vbRed > then
> next...
で、Picture1.Point(X, Y) = vbRed の値は、XとYが変わらなければ変わらないと思われ…。
あとループ中に、プロパティをかなり参照しているがプロパティの参照そのものは関数の呼び出しくらい遅いと考えられる。
…まぁ、だからどうしろとかは言えないけどなw
※実行速度を速くするのもプログラマのお仕事だと思われる。
技術が無いなら、サンプルコードをガンガン読むといい。
(´Д`;)<初心者だから無理とか、そういう当たり前のことは言わないように;
pictureの中身が変わらなければ、事前に赤い部分の座標を配列に入れて
おくと便利かもしれません。
あと、多重ループの時、判断はループの一番奥ですべてやるんじゃなくて
途中で出来るものは、そこでやったほうが余計なループを回らなくて済み
ますよ。
本当はサンプルを書くと勉強にならないんだけど、まぁいいか(^^;
手書きなのでスペルミスとかあるかも・・・
Private Pic1X() As Long
Private Pic1Y() As Long
Private Pic2X() As Long
Private Pic2Y() As Long
Private Sub Command1_Click()
Dim n As Long
Dim x As Long
Dim y As Long
n = 0
For x = 0 To 100
For y = 0 To 80
If Picture1.Point(x, y) = vbRed Then
ReDim Preserve Pic1X(n)
ReDim Preserve Pic1Y(n)
Pic1X(n) = x
Pic1Y(n) = y
n = n + 1
End If
Next y
Next x
n = 0
For x = 20 To 32
For y = 20 To 32
If Picture2.Point(x, y) = vbRed Then
ReDim PreServe Pic2X(n)
ReDim PreServe Pic2Y(n)
Pic2X(n) = x
Pic2Y(n) = y
n = n + 1
End If
Next y
Next x
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Dim x1 As Long
Dim y1 As Long
Dim x2 As Long
Dim y2 As Long
Dim Pic1Left As Long
Dim Pic1Top As Long
Dim Pic2Left As Long
Dim Pic2Top As Long
Pic1Left = Picture1.Left
Pic1Top = Picture1.Top
Pic2Left = Picture2.Left
Pic2Top = Picture2.Top
For x1 = LBound(Pic1X) to UBound(Pic1X)
For x2 = LBound(Pic2X) to UBound(Pic2X)
'まずX座標が同じかチェック
If Pic1X(x1) + Pic1Left = Pic2X(x2) + Pic2Left Then
For y1 = LBound(Pic1Y) to UBound(Pic1Y)
For y2 = LBound(Pic2Y) to UBound(Pic2Y)
'次にY座標も同じかチェック
If Pic1Y(y1) + Pic1Top = Pic2Y(y2) + Pic2Top Then
MsgBox "あたり"
'1つでもあたったら残りのループ処理は不要
Exit Sub
End If
Next y2
Next y1
End If
Next x2
Next x1
End Sub
ツイート | ![]() |