[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『がらがらを作りたいのですが・・・』(ラッキー男)
おもしろそうなので。 シェープの名前はなんでもいいけど、コードでは以下にしている。
かご "basket" この、かごの中にボールを。"ovlRed","ovlBlue","ovlBlack","ovlYellow","ovlGreen" これとは別に、当選ボールが入る枠を、【塗りつぶしなし】で、"winner"
ちょっと手を抜いていて、がらがら中、ボールがかごを少し飛び出してしまうけど。
Sub がらがら() Dim v(1 To 5) As Shape '玉の数分 Dim pos(1 To 5, 1 To 2) As Double '元の位置 Dim sp As Variant Dim z As Long Dim x1 As Long, x2 As Long Dim y1 As Long, y2 As Long Dim l As Long, t As Long Dim winner As Shape
With ActiveSheet Set v(1) = .Shapes("ovlBlue") Set v(2) = .Shapes("ovlred") Set v(3) = .Shapes("ovlblack") Set v(4) = .Shapes("ovlyellow") Set v(5) = .Shapes("ovlgreen") For Each sp In v z = z + 1 pos(z, 1) = sp.Left pos(z, 2) = sp.Top Next With .Shapes("basket") x1 = .Left x2 = x1 + .Width y1 = .Top y2 = y1 + .Height End With Set winner = .Shapes("Winner") End With
For z = 1 To 50 'ガラガラ数 For Each sp In v 'がらがら実行 With sp l = Int((x2 - x1 + 1) * Rnd + x1) t = Int((y2 - y1 + 1) * Rnd + y1) .Left = l .Top = t End With Next Sleep 10 DoEvents Next z = 0 For Each sp In v z = z + 1 sp.Left = pos(z, 1) sp.Top = pos(z, 2) Next
z = Int((UBound(v)) * Rnd + 1) 'Winner With v(z) .Left = winner.Left + winner.Width / 2 - .Width / 2 .Top = winner.Top + winner.Height / 2 - .Height / 2
End With
End Sub
(ぶらっと)
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
(ぶらっと)
なお、↑は、ガラガラ回数を、コードで規定しているけど、たとえば 何かのキー(シフトキーとか) を押すまでは、がらがら回し、キーをおしたときに止めるということもできる。
コードで規定するとしてアップしたコードの 50回は、すくなすぎるかも。 200回ぐらいのほうが、回しているという感じがでるかな?
(ぶらっと)
これどこかでリンクされていたのを試しに使ってみただけですが、色付ではないですが、 同じ事は出来ると思いますよ
ichinose
がらがら回数は特定せず、シフトキーを押したら終了させるコード。 なお、アップ済みのものは【インチキ】している。 (がらがらの状況には関係なく、最後に当然ボールを決めている)
以下では、あわせて、止めたときに一番右にあったボールを当選にしている。
Sub がらがら2() Dim v(1 To 5) As Shape '玉の数分 Dim pos(1 To 5, 1 To 2) As Double '元の位置 Dim sp As Variant Dim z As Long Dim x1 As Long, x2 As Long Dim y1 As Long, y2 As Long Dim l As Long, t As Long Dim winner As Shape Dim maxL As Double Dim winBall As Shape
With ActiveSheet Set v(1) = .Shapes("ovlBlue") Set v(2) = .Shapes("ovlred") Set v(3) = .Shapes("ovlblack") Set v(4) = .Shapes("ovlyellow") Set v(5) = .Shapes("ovlgreen") For Each sp In v z = z + 1 pos(z, 1) = sp.Left pos(z, 2) = sp.Top Next With .Shapes("basket") x1 = .Left x2 = x1 + .Width y1 = .Top y2 = y1 + .Height End With Set winner = .Shapes("Winner") End With
Do If GetAsyncKeyState(vbKeyShift) <> 0 Then Exit Do 'シフトキーがおされたら終了 For Each sp In v 'がらがら実行 With sp l = Int((x2 - x1 + 1) * Rnd + x1) t = Int((y2 - y1 + 1) * Rnd + y1) .Left = l .Top = t End With Next Sleep 10 DoEvents Loop
z = 0 For Each sp In v If sp.Left > maxL Then maxL = sp.Left Set winBall = sp End If z = z + 1 sp.Left = pos(z, 1) sp.Top = pos(z, 2) Next
With winBall .Left = winner.Left + winner.Width / 2 - .Width / 2 .Top = winner.Top + winner.Height / 2 - .Height / 2
End With
End Sub
● なお、モジュールの先頭に以下も追加。
Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long
(ぶらっと)
連投失礼。悪乗りして、がらがらする時に、かごもまわした。
Sub がらがら3() Dim v(1 To 5) As Shape '玉の数分 Dim pos(1 To 5, 1 To 2) As Double '元の位置 Dim sp As Variant Dim z As Long Dim x1 As Long, x2 As Long Dim y1 As Long, y2 As Long Dim l As Long, t As Long Dim winner As Shape Dim maxL As Double Dim winBall As Shape Dim basket As Shape Dim bRotation As Long
With ActiveSheet Set v(1) = .Shapes("ovlBlue") Set v(2) = .Shapes("ovlred") Set v(3) = .Shapes("ovlblack") Set v(4) = .Shapes("ovlyellow") Set v(5) = .Shapes("ovlgreen") For Each sp In v z = z + 1 pos(z, 1) = sp.Left pos(z, 2) = sp.Top Next Set basket = .Shapes("basket") With basket x1 = .Left x2 = x1 + .Width y1 = .Top y2 = y1 + .Height End With Set winner = .Shapes("Winner") End With
Do If GetAsyncKeyState(vbKeyShift) <> 0 Then Exit Do 'シフトキーがおされたら終了 For Each sp In v 'がらがら実行 With sp l = Int((x2 - x1 + 1) * Rnd + x1) t = Int((y2 - y1 + 1) * Rnd + y1) .Left = l .Top = t End With bRotation = bRotation + 1 basket.Rotation = bRotation Next Sleep 10 DoEvents Loop
z = 0 For Each sp In v If sp.Left > maxL Then maxL = sp.Left Set winBall = sp End If z = z + 1 sp.Left = pos(z, 1) sp.Top = pos(z, 2) Next
basket.Rotation = 0
With winBall .Left = winner.Left + winner.Width / 2 - .Width / 2 .Top = winner.Top + winner.Height / 2 - .Height / 2
End With
End Sub
(ぶらっと)
横から失礼します。 がらがら、作らせていただきました。 楽しくて何度も回してしまっています(笑) すごいです!
ちなみに、シフトキーを押してwinBallを決めた後、 再びがらがらする前に、winBallをbasketに戻して再スタートするには どうすればいいのでしょうか?
(茶々)
>八角形のバスケットの中で転がるように回れば完璧なのに・
確かにねぇ・・ ボールがバスケットの壁にぶつかって、跳ね返って別のところにとんでいくという効果は [[20111130100821]] 『図形を浮遊させる』(俊介) ここの、momoさんがアップしたコードのロジックを組み込めばいいと思うけど、かごが回るということに 対応させるのも含めて、かなりやっかいかもね。 おもしろそうなので、勉強をかねてやってみるけど、さて・・・ 完成に1年ぐらいかかりそう。
>再びがらがらする前に、winBallをbasketに戻して再スタートするには
これは、なんとかなりそうなのでやってみる。少し時間くださいな。
(ぶらっと)
かごの中の玉の動きは、基本的にかえていないけど、かごの中から飛び出さないようにしたので なんとなく、かごの中で、ゆさぶられているような、シャッフルされているようなイメージに近くなったのではと思うけど どうだろうか。
実行すると最初に、各玉が、どこにあろうと、かごの真ん中あたりにランダムにほうりこんで開始するので winBallとして、飛びでているものがあたとしても、そのまま実行可能。
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long
Sub がらがら4() Const adjustX As Long = 50 Dim v(1 To 5) As Shape '玉の数分 Dim sp As Variant Dim winner As Shape Dim maxL As Double Dim winBall As Shape Dim basket As Shape Dim bRotation As Long Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double
With ActiveSheet Set basket = .Shapes("basket") With basket bTop = .Top + adjustX bBottom = .Top + .Height - adjustX bLeft = .Left + adjustX bRight = .Left + .Width - adjustX End With Set v(1) = .Shapes("ovlBlue") Set v(2) = .Shapes("ovlred") Set v(3) = .Shapes("ovlblack") Set v(4) = .Shapes("ovlyellow") Set v(5) = .Shapes("ovlgreen") For Each sp In v sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) Next
Set winner = .Shapes("Winner") End With
Do If GetAsyncKeyState(vbKeyShift) <> 0 Then Exit Do 'シフトキーがおされたら終了 For Each sp In v 'がらがら実行 sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) bRotation = bRotation + 1 basket.Rotation = bRotation Next Sleep 10 DoEvents Loop
For Each sp In v If sp.Left > maxL Then maxL = sp.Left Set winBall = sp End If Next
basket.Rotation = 0
With winBall .Left = winner.Left + winner.Width / 2 - .Width / 2 .Top = winner.Top + winner.Height / 2 - .Height / 2 End With
End Sub
(ぶらっと)
↑とかえてはいないけど、最後に winBallが少しフラッシュする。 お好みならこちらを。
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long
Sub がらがら5() Const adjustX As Long = 50 Dim v(1 To 5) As Shape '玉の数分 Dim sp As Variant Dim winner As Shape Dim maxL As Double Dim winBall As Shape Dim basket As Shape Dim bRotation As Long Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double Dim z As Long
With ActiveSheet Set basket = .Shapes("basket") With basket bTop = .Top + adjustX bBottom = .Top + .Height - adjustX bLeft = .Left + adjustX bRight = .Left + .Width - adjustX End With Set v(1) = .Shapes("ovlBlue") Set v(2) = .Shapes("ovlred") Set v(3) = .Shapes("ovlblack") Set v(4) = .Shapes("ovlyellow") Set v(5) = .Shapes("ovlgreen") For Each sp In v sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) Next
Set winner = .Shapes("Winner") End With
Do If GetAsyncKeyState(vbKeyShift) <> 0 Then Exit Do 'シフトキーがおされたら終了 For Each sp In v 'がらがら実行 sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) bRotation = bRotation + 1 basket.Rotation = bRotation Next Sleep 10 DoEvents Loop
For Each sp In v If sp.Left > maxL Then maxL = sp.Left Set winBall = sp End If Next
basket.Rotation = 0
With winBall .Left = winner.Left + winner.Width / 2 - .Width / 2 .Top = winner.Top + winner.Height / 2 - .Height / 2 For z = 1 To 100 .Visible = Not .Visible DoEvents Sleep 10 Next End With
End Sub
(ぶらっと)
またまた横から失礼します。
(ぶらっと)さん、スゴいですっ!
ありがとうございました。 楽しくて、また何度も回してしまいました。
私は最初のがらがらの動きのほうが好きなので、 「再びがらがらする前に、winBallをbasketに戻して再スタートするには」の記述は どこでしょうか? ↑自分で組み合わせてみようと思ったのですが、よくわからなくて…
何度もすみません。よろしくお願いします。
(茶々)
To 茶々さん
>「再びがらがらする前に、winBallをbasketに戻して再スタートするには」の記述は どこでしょうか?
最初のほうにある
For Each sp In v sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) Next
ここで、5つのシェープに対して、ランダムな縦位置、横位置を与えている。
To ラッキー男さん
>basket.Rotation = 0 でカゴを回転させていると思うのですが0を1000に変えてもあまり早くなりません。
いやいや、これは、最後にとまった時に、かごの角度を 0 つまり回転なしの状態に戻しているところ。 回転は、
bRotation = bRotation + 1 basket.Rotation = bRotation
ここでやっている。 シェープ.Rotation が、回転角度。ループの中で 1度ずつアップしている。 これを + 2 とか + 3 とかにすれば、回る速度が速くなる。
(ぶらっと)
(ぶらっと)さん、ありがとうございました。
(ラッキー男)さん、横から失礼しました!
(茶々)
上のほうでアップした がらがら5 は、アイデア倒れというか、フラッシュさせても だから、どうなんだ? という印象だったね。
動きを早くしたいというラッキー男さんのコメントで、ふと思いついて。 以下は(もう、これで最後にするけど)終わりのフラッシュはやめて 新しく
・ゆ〜っくり回転。ボールもかごの下のほうで動くだけ。(レベル1) ・回転中に ↑矢印キーでレベル2に移行。回転が速くなり、ボールの動きも かごの中全体になる。 ・↓矢印キーでレベル1にもどる。回転中、↑キー、↓キーを何度でもおすことができる。
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long Private Const adjustX As Long = 50
Sub がらがら6() Dim v(1 To 5) As Shape '玉の数分 Dim sp As Variant Dim winner As Shape Dim maxL As Double Dim winBall As Shape Dim basket As Shape Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double Dim winLoop As Long Dim winSleep As Long Dim z As Long Dim hWnd As Long Dim i As Long Dim moveUp As Boolean Dim rtnS As Long Dim rtnZ As Long Dim rtnU As Long Dim rtnD As Long Dim udChange As Boolean Dim addRote As Long
With ActiveSheet Set basket = .Shapes("basket")
bRangeSet moveUp, basket, bLeft, bRight, bTop, bBottom
Set v(1) = .Shapes("ovlBlue") Set v(2) = .Shapes("ovlred") Set v(3) = .Shapes("ovlblack") Set v(4) = .Shapes("ovlyellow") Set v(5) = .Shapes("ovlgreen")
BallSet v, bLeft, bRight, bTop, bBottom Set winner = .Shapes("Winner") End With
Do rtnS = GetAsyncKeyState(vbKeyShift) If rtnS <> 0 Then Exit Do 'シフトキーがおされたら終了 rtnD = GetAsyncKeyState(vbKeyDown) rtnU = GetAsyncKeyState(vbKeyUp) udChange = False If rtnU And &H80000000 <> 0 Then moveUp = True udChange = True ElseIf rtnD And &H80000000 <> 0 Then moveUp = False udChange = True End If
If udChange Then bRangeSet moveUp, basket, bLeft, bRight, bTop, bBottom Else 'がらがら実行 addRote = 100 If moveUp Then addRote = 4 End If For Each sp In v BallSet v, bLeft, bRight, bTop, bBottom basket.Rotation = basket.Rotation + addRote If Not moveUp Then Sleep 10 Next End If Sleep 10 DoEvents Loop
For Each sp In v If sp.Left > maxL Then maxL = sp.Left Set winBall = sp End If Next
basket.Rotation = 0
With winBall .Left = winner.Left + winner.Width / 2 - .Width / 2 .Top = winner.Top + winner.Height / 2 - .Height / 2 End With
End Sub
Private Sub BallSet(v As Variant, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double) Dim sp As Variant For Each sp In v sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) Next End Sub
Private Sub bRangeSet(moveUp As Boolean, basket As Shape, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double) With basket If moveUp Then bTop = .Top + .Height / 4 Else bTop = .Top + .Height / 4 * 3 End If bBottom = .Top + .Height - adjustX bLeft = .Left + adjustX bRight = .Left + .Width - adjustX End With
End Sub
(ぶらっと)
>チョット長く回していると(18秒ほど)実行時エラー -2147024809(80070057) >指定された値は境界を超えています。
こちらでも、まったく別のアプリだけど、同じような制御を取り入れたもので、同じエラーが 発生するバグがあって、「限界値を超えないような」対応を組み込んだ。
がらがらの、どこに、どう組み込まばいいか、ちょっとさぐってみるので、しばしお待ちを。
ところで、使っているのが、どのバージョン? 最後にアップした、動きのレベルが2段階のもの?
(ぶらっと)
こちらでは、今、3分回したけどエラーにはならない。ただし Win7 + 2010 以下のように ★のコードを追加したらどうなるかな?
bRotation = bRotation Mod 360 '★ 追加 basket.Rotation = bRotation
(ぶらっと)
まず、今後、がらがら5 をベースにするか がらがら6 をベースにするか確認お願い。 先ほど連絡した basket.Rotation = bRotation も、がらがら6なら、少しコードが異なるので。 (対処の考え方は同じだけど)
>太さのポイントを大きくしたら玉が埋まってしまいます
これは具体的にはどういうことかな?
・最後に当選ボールを入れる箱のことを言っている? で、この枠を太くしたら、ボールの端っこが枠の下に埋もれてしまう?
★もし、そういうことなら、枠の上に表示されるように1行コードを追加する。
・それとも、がらがらのかご?
★もし、そういうことなら、Private Const adjustX As Long = 50 の数字を少し大きくすると その分、動きが内側に狭められる。
どちらのことか連絡お願いね。
余談)あれから、こちらでは がらがら6 で、当選したボールが Winner に納められる際に ポーンと、弧を描いて飛び込むようにしたバージョン、がらがら7 にしている。 また、このバージョンは、ボールが何個でもOK。(名前が ovl●● のものをすべて対象にしている) ご希望ならコードをアップする。
それと、今ふと思ったんだけど、通常、このゲームは、たとえば赤玉がでれば、その玉は勝ち抜け。 次に回すときは、赤玉は除くよね。そういうこともオプションで可能にした、がらがら8 も作ってみようかなと 思っている。
(ぶらっと)
で、この枠を太くしたら、ボールの端っこが枠の下に埋もれてしまう? そうです。
わたしも、動かしていて玉の数を増やすには面倒でも同じように書かないと行け無いなあと思っていました。
それと、玉が減らなくなったのがチョットと思っています。がらがら1〜3までは減りましたから・・・
でも玉が多すぎると低スペックなパソコンでは無理なのかと思ったりしています。
(ラッキー男)
一度、以下で総入れ替えして、がらがら8 を試してみてくれないかな? イメージ的に、今いちで、がらがら5 のベースにしたいということなら、がらがら5に、今回の要件を 追加するので。
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long Private Const adjustX As Long = 50 'バスケット領域内の"クライアント領域"の調整値 '以下は状況に応じて数値を変更 Private Const addRote1 As Long = 1 'レベル1 の各ボール位置移動後の回転角度単位 Private Const addRote2 As Long = 4 'レベル2 の各ボール位置移動後の回転角度単位 Private Const sleepA1 As Long = 10 'レベル1 の各ボール位置移動後のSleepミリ秒 Private Const sleepA2 As Long = 0 'レベル2 の各ボール位置移動後のSleepミリ秒 Private Const sleepB1 As Long = 20 'レベル1 の全ボール位置移動後のSleepミリ秒 Private Const sleepB2 As Long = 5 'レベル2 の全ボール位置移動後のSleepミリ秒
Sub がらがら8() Dim v() As Shape Dim vFlag As Boolean Dim sp As Variant Dim winner As Shape Dim maxL As Double Dim winBall As Shape Dim basket As Shape Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double Dim winLoop As Long Dim winSleep As Long Dim z As Long Dim hWnd As Long Dim i As Long Dim moveUp As Boolean Dim rtnS As Long Dim rtnZ As Long Dim rtnU As Long Dim rtnD As Long Dim udChange As Boolean Dim addRote As Long Dim ballCnt As Long Dim sleepA As Long Dim sleepB As Long Dim BallOK As Boolean
With ActiveSheet
If Not makeBall(v) Then MsgBox "回すボールがありませんよ" End If
Set basket = .Shapes("basket")
bRangeSet moveUp, basket, bLeft, bRight, bTop, bBottom
BallSet v, bLeft, bRight, bTop, bBottom, basket Set winner = .Shapes("Winner") End With
Do rtnS = GetAsyncKeyState(vbKeyShift) If rtnS <> 0 Then Exit Do 'シフトキーがおされたら終了 rtnD = GetAsyncKeyState(vbKeyDown) rtnU = GetAsyncKeyState(vbKeyUp) udChange = False If rtnU And &H80000000 <> 0 Then moveUp = True udChange = True ElseIf rtnD And &H80000000 <> 0 Then moveUp = False udChange = True End If
If udChange Then bRangeSet moveUp, basket, bLeft, bRight, bTop, bBottom Else 'がらがら実行 addRote = addRote1 sleepA = sleepA1 sleepB = sleepB1 If moveUp Then addRote = addRote2 sleepA = sleepA2 sleepB = sleepB2 End If For Each sp In v BallSet v, bLeft, bRight, bTop, bBottom, basket basket.Rotation = (basket.Rotation + addRote) Mod 360 Sleep sleepA Next End If Sleep sleepB DoEvents Loop
For Each sp In v If sp.Visible Then If sp.Left > maxL Then maxL = sp.Left Set winBall = sp End If End If Next
basket.Rotation = 0
Call Win(winBall, winner.Left + winner.Width / 2, winner.Top + winner.Height / 2) winner.ZOrder msoSendToBack
If MsgBox("おめでとうございます。このボールを勝ち抜けにしますか?", vbYesNo) = vbYes Then winBall.Visible = False
End Sub
Private Sub BallSet(v As Variant, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double, basket As Shape) Dim sp As Variant For Each sp In v sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) Next basket.ZOrder msoSendToBack End Sub
Private Sub bRangeSet(moveUp As Boolean, basket As Shape, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double) With basket If moveUp Then bTop = .Top + .Height / 4 Else bTop = .Top + .Height / 4 * 2.5 End If bBottom = .Top + .Height - adjustX bLeft = .Left + adjustX bRight = .Left + .Width - adjustX End With
End Sub
Private Sub Win(myBall As Shape, p As Double, q As Double)
Dim x As Double, y As Double Dim w As Double, h As Double Dim a As Double Const grids As Long = 50 Dim graduation As Double
Dim z As Long
With myBall x = .Left + .Width / 2 y = .Top + .Height / 2 w = .Width h = .Height End With
graduation = (p - x) / grids
a = (y - q) / (x - p) ^ 2
For z = 1 To grids
If z = grids Then x = p y = q Else x = x + graduation y = a * (x - p) ^ 2 + q End If
myBall.Left = x - w / 2 myBall.Top = y - h / 2
Sleep 10 DoEvents DoEvents
Next
End Sub
Private Function makeBall(v() As Shape) As Boolean Dim sp As Shape Dim vFlag As Boolean
With ActiveSheet For Each sp In .Shapes If sp.Name Like "ovl*" And sp.Visible Then If vFlag Then ReDim Preserve v(1 To UBound(v) + 1) Else ReDim v(1 To 1) vFlag = True End If Set v(UBound(v)) = sp makeBall = True End If Next End With
End Function
Sub Reset8() Dim sp As Shape Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double Dim v() As Shape Dim vFlag As Boolean Dim basket As Shape
With ActiveSheet .DrawingObjects.Visible = True makeBall v Set basket = .Shapes("basket") bRangeSet False, basket, bLeft, bRight, bTop, bBottom BallSet v, bLeft, bRight, bTop, bBottom, basket End With
End Sub
(ぶらっと)
追伸
ボールが対象外になっていってがらがらの中のボールが少なくなっていき、最後はなくなってしまうね。 で、もう一度、ボールをがらがらに入れなおすのが Reset8 。 このReset8 は、何個か消えた後に途中で実行してもOK。
(ぶらっと)
x = .Left + .Width / 2 で止まっています。
(ラッキー男)
え? ボール名は ovl で始まっているんだよね?
メッセージの後、終わらないでエラーになってしまったのは、コードアップ時のミス。(ごめん)
MsgBox "回すボールがありませんよ"
このあとに
Exit Sub
これを入れて。
ただ、なぜ、そう見なされたかが・・・・・?? ちゃんと、名前が ovl で始まり、表示されているボールはあるんだよねぇ・・・・
(ぶらっと)
回転は、 bRotation = bRotation + 1 basket.Rotation = bRotation ココが無くなりカゴの回転が非常に遅くなり今一つ・・・です。 無理ばかり言いますがカゴの回転も速くならないでしょうか?
(ラッキー男)
>ココが無くなりカゴの回転が非常に遅くなり今一つ・・・です。 >無理ばかり言いますがカゴの回転も速くならないでしょうか?
従来の
bRotation = bRotation + 1 basket.Rotation = bRotation
これは、がらがら8 では
basket.Rotation = (basket.Rotation + addRote) Mod 360
で、この増分のaddRote は レベルによって 1 ないしは 4 になっている。 この 1 や 4 は、
'以下は状況に応じて数値を変更 Private Const addRote1 As Long = 1 'レベル1 の各ボール位置移動後の回転角度単位 Private Const addRote2 As Long = 4 'レベル2 の各ボール位置移動後の回転角度単位 Private Const sleepA1 As Long = 10 'レベル1 の各ボール位置移動後のSleepミリ秒 Private Const sleepA2 As Long = 0 'レベル2 の各ボール位置移動後のSleepミリ秒 Private Const sleepB1 As Long = 20 'レベル1 の全ボール位置移動後のSleepミリ秒 Private Const sleepB2 As Long = 5 'レベル2 の全ボール位置移動後のSleepミリ秒
こういったところで規定しているので、これら数字をいじくると、動きに変化がでると思う。 ただ、こちらで、ボールを10個ぐらいにして動かしているんだけど、遅いかなぁ?
念のため、最初に、がらがら6 をアップしたときに、矢印キー(↑ や ↓)によるレベルの変化の 説明をしていて、このがらがら8 は、がらがら6の改訂版の、そのまた改訂版。 そのときの説明にもあるけど、最初は、すごく、ゆっくり動く。↑キーをおすとレベル2になって 早く回る。レベル2からレベル1に戻すこともできる。シフトキーは、どのレベルのときにでも おすことはできる。
で、レベル2でも遅いということ?
(ぶらっと)
がらがら8 の確認ももらっていない状況で、混乱するかもしれないけど参考として、こちらの最新版 がらがら9 と Reset9 もアップしておくね。 がらがら8 では、当選ボールが当選かごに弧を描いて放り込まれるところまで組み込んだけど がらがら9は、それに加えて、
・勝ち抜け に対して No を選んだときに、ボールをがらがらに、弧を描いて戻す。 ・勝ち抜け に対して Yes を選んで消えたボールを、Reset9 でがらがらに戻す際に、1つずつ弧を描いて戻す。
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long Private Const adjustX As Long = 50 'バスケット領域内の"クライアント領域"の調整値 '以下は状況に応じて数値を変更 Private Const addRote1 As Long = 1 'レベル1 の各ボール位置移動後の回転角度単位 Private Const addRote2 As Long = 4 'レベル2 の各ボール位置移動後の回転角度単位 Private Const sleepA1 As Long = 10 'レベル1 の各ボール位置移動後のSleepミリ秒 Private Const sleepA2 As Long = 0 'レベル2 の各ボール位置移動後のSleepミリ秒 Private Const sleepB1 As Long = 20 'レベル1 の全ボール位置移動後のSleepミリ秒 Private Const sleepB2 As Long = 5 'レベル2 の全ボール位置移動後のSleepミリ秒
Sub がらがら9() Dim v() As Shape Dim vFlag As Boolean Dim sp As Variant Dim winner As Shape Dim maxL As Double Dim winBall As Shape Dim basket As Shape Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double Dim winLoop As Long Dim winSleep As Long Dim z As Long Dim hWnd As Long Dim i As Long Dim moveUp As Boolean Dim rtnS As Long Dim rtnZ As Long Dim rtnU As Long Dim rtnD As Long Dim udChange As Boolean Dim addRote As Long Dim ballCnt As Long Dim sleepA As Long Dim sleepB As Long Dim BallOK As Boolean Dim svX As Double Dim svY As Double
With ActiveSheet
If Not makeBall(v) Then MsgBox "回すボールがありませんよ" Exit Sub End If
Set basket = .Shapes("basket")
bRangeSet moveUp, basket, bLeft, bRight, bTop, bBottom
BallSet v, bLeft, bRight, bTop, bBottom, basket Set winner = .Shapes("Winner") End With
Do rtnS = GetAsyncKeyState(vbKeyShift) If rtnS <> 0 Then Exit Do 'シフトキーがおされたら終了 rtnD = GetAsyncKeyState(vbKeyDown) rtnU = GetAsyncKeyState(vbKeyUp) udChange = False If rtnU And &H80000000 <> 0 Then moveUp = True udChange = True ElseIf rtnD And &H80000000 <> 0 Then moveUp = False udChange = True End If
If udChange Then bRangeSet moveUp, basket, bLeft, bRight, bTop, bBottom Else 'がらがら実行 addRote = addRote1 sleepA = sleepA1 sleepB = sleepB1 If moveUp Then addRote = addRote2 sleepA = sleepA2 sleepB = sleepB2 End If For Each sp In v BallSet v, bLeft, bRight, bTop, bBottom, basket basket.Rotation = (basket.Rotation + addRote) Mod 360 Sleep sleepA Next End If Sleep sleepB DoEvents Loop
For Each sp In v If sp.Visible Then If sp.Left > maxL Then maxL = sp.Left Set winBall = sp End If End If Next
basket.Rotation = 0
With winBall svX = .Left + .Width / 2 svY = .Top + .Height / 2 End With
Call Parabola(winBall, winner.Left + winner.Width / 2, winner.Top + winner.Height / 2) winner.ZOrder msoSendToBack
If MsgBox("おめでとうございます。このボールを勝ち抜けにしますか?", vbYesNo) = vbYes Then winBall.Visible = False Else Call Parabola(winBall, svX, svY) End If
End Sub
Private Sub BallSet(v As Variant, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double, basket As Shape) Dim sp As Variant For Each sp In v sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) Next basket.ZOrder msoSendToBack End Sub
Private Sub bRangeSet(moveUp As Boolean, basket As Shape, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double) With basket If moveUp Then bTop = .Top + .Height / 4 Else bTop = .Top + .Height / 4 * 2.5 End If bBottom = .Top + .Height - adjustX bLeft = .Left + adjustX bRight = .Left + .Width - adjustX End With
End Sub
Private Sub Parabola(myBall As Variant, p As Double, q As Double)
Dim x As Double, y As Double Dim w As Double, h As Double Dim a As Double Const grids As Long = 50 Dim graduation As Double
Dim z As Long
With myBall x = .Left + .Width / 2 y = .Top + .Height / 2 w = .Width h = .Height End With
graduation = (p - x) / grids
a = (y - q) / (x - p) ^ 2
For z = 1 To grids
If z = grids Then x = p y = q Else x = x + graduation y = a * (x - p) ^ 2 + q End If
myBall.Left = x - w / 2 myBall.Top = y - h / 2
Sleep 10 DoEvents DoEvents
Next
End Sub
Private Function makeBall(v() As Shape) As Boolean Dim sp As Shape Dim vFlag As Boolean
With ActiveSheet For Each sp In .Shapes If sp.Name Like "ovl*" And sp.Visible Then If vFlag Then ReDim Preserve v(1 To UBound(v) + 1) Else ReDim v(1 To 1) vFlag = True End If Set v(UBound(v)) = sp makeBall = True End If Next End With
End Function
Sub Reset9() Dim sp As Shape Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double Dim v() As Shape Dim vFlag As Boolean Dim basket As Shape
With ActiveSheet
Set basket = .Shapes("basket") bRangeSet False, basket, bLeft, bRight, bTop, bBottom
For Each sp In .Shapes If sp.Name Like "ovl*" And Not sp.Visible Then sp.Visible = True Call Parabola(sp, Int((bLeft + sp.Width / 2 - (bRight - sp.Width / 2) + 1) * Rnd + (bRight - sp.Width / 2)), Int((bTop - sp.Height / 2 - (bBottom - sp.Height / 2) + 1) * Rnd + (bBottom - sp.Height / 2))) End If Next End With
End Sub
(ぶらっと)
>それでも早く回したい、今も同じ気持ちです。
レベル2 にしても遅いということ? PCの性能や玉の数にも関係するけど、レベル2のスピードをあげる調整をしてみようか?
>玉はやっぱりかごの中に入っていないと・・・そして飛び出す。 >一応回っている間はどんな動きをしているか、かごの中が見えるように透明度は10%にして >そうするとシルエットが見えてリアルになります。 >かごを常に前面にはならないでしょうか?
がらがら の 枠を若干太めにしたのかなと、そう思っていた。 で、その太めの枠の裏側に玉が隠れてしまう・・ そう理解したので、逆に、がらがら を再背面にしたんだけど、そうじゃないんだね。 極端に言えば がらがらの枠というより、がらがら全体の下で 玉が動く。で、回っているときは シルエットが浮かび上がるようにする。
そういうことだったのかな? ということなら、その線で 効果をつけることはできると思う。
(ぶらっと)
そちらの感覚に合うかどうか・・・・
なお、がらがらの透明度については
Private Const transBusy As Double = 0.1 '回っているときのがらがらの透明度 '★ 追加 Private Const transCalm As Double = 0.4 '止まっているときのがらがらの透明度 '★ 追加
ここで規定しているので、そちらの感覚に合うような数字に調整して。 がらがらの回る速さ(というか、見た目)が、これでも遅いということなら、う〜ん・・・ コードの上のほうの Const群での規定数値を増やしたり減らしたりして、調整お願い。(でも、限界はあるかな)
なお、最初に、以下の Reset10 を実行して、がらがらの透明度をセットしておいてね。
改訂した部分だけをアップするとかえってわかりにくくなると思うので がらがら10、Reset10 として 一式アップ。
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long Private Const adjustX As Long = 50 'バスケット領域内の"クライアント領域"の調整値 '以下は状況に応じて数値を変更 Private Const addRote1 As Long = 1 'レベル1 の各ボール位置移動後の回転角度単位 Private Const addRote2 As Long = 1 'レベル2 の各ボール位置移動後の回転角度単位 '★ 修正 Private Const sleepA1 As Long = 10 'レベル1 の各ボール位置移動後のSleepミリ秒 Private Const sleepA2 As Long = 0 'レベル2 の各ボール位置移動後のSleepミリ秒 Private Const sleepB1 As Long = 20 'レベル1 の全ボール位置移動後のSleepミリ秒 Private Const sleepB2 As Long = 1 'レベル2 の全ボール位置移動後のSleepミリ秒 '★ 修正 Private Const transBusy As Double = 0.1 '回っているときのがらがらの透明度 '★ 追加 Private Const transCalm As Double = 0.4 '止まっているときのがらがらの透明度 '★ 追加
Dim moveUp As Boolean '★定義の場所を変更 Dim addRote As Long '★定義の場所を変更
Sub がらがら10() Dim v() As Shape Dim vFlag As Boolean Dim sp As Variant Dim winner As Shape Dim maxL As Double Dim winBall As Shape Dim basket As Shape Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double Dim winLoop As Long Dim winSleep As Long Dim z As Long Dim hWnd As Long Dim i As Long Dim rtnS As Long Dim rtnZ As Long Dim rtnU As Long Dim rtnD As Long Dim udChange As Boolean Dim ballCnt As Long Dim sleepA As Long Dim sleepB As Long Dim BallOK As Boolean Dim svX As Double Dim svY As Double
'モジュールレベル変数の初期化 '★追加 addRote = 0 moveUp = False
With ActiveSheet
If Not makeBall(v) Then MsgBox "回すボールがありませんよ" Exit Sub End If
Set basket = .Shapes("basket")
bRangeSet moveUp, basket, bLeft, bRight, bTop, bBottom
BallSet v, bLeft, bRight, bTop, bBottom, basket Set winner = .Shapes("Winner") End With
Do rtnS = GetAsyncKeyState(vbKeyShift) If rtnS <> 0 Then Exit Do 'シフトキーがおされたら終了 rtnD = GetAsyncKeyState(vbKeyDown) rtnU = GetAsyncKeyState(vbKeyUp) udChange = False If rtnU And &H80000000 <> 0 Then moveUp = True udChange = True ElseIf rtnD And &H80000000 <> 0 Then moveUp = False udChange = True End If
If udChange Then bRangeSet moveUp, basket, bLeft, bRight, bTop, bBottom Else 'がらがら実行 basket.Fill.Transparency = transBusy '★ 追加 addRote = addRote1 sleepA = sleepA1 sleepB = sleepB1 If moveUp Then addRote = addRote2 sleepA = sleepA2 sleepB = sleepB2 End If For Each sp In v BallSet v, bLeft, bRight, bTop, bBottom, basket basket.Rotation = (basket.Rotation + addRote) Mod 360 Sleep sleepA Next End If Sleep sleepB DoEvents Loop
For Each sp In v If sp.Visible Then If sp.Left > maxL Then maxL = sp.Left Set winBall = sp End If End If Next
basket.Rotation = 0
With winBall svX = .Left + .Width / 2 svY = .Top + .Height / 2 End With
Call Parabola(winBall, winner.Left + winner.Width / 2, winner.Top + winner.Height / 2) winner.ZOrder msoSendToBack
If MsgBox("おめでとうございます。このボールを勝ち抜けにしますか?", vbYesNo) = vbYes Then winBall.Visible = False Else Call Parabola(winBall, svX, svY) End If
basket.Fill.Transparency = transCalm '★ 追加
End Sub
Private Sub BallSet(v As Variant, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double, basket As Shape) Dim sp As Variant For Each sp In v sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) If moveUp Then basket.Rotation = (basket.Rotation + addRote) Mod 360 '★追加 Next basket.ZOrder msoBringToFront '★ 変更 End Sub
Private Sub bRangeSet(moveUp As Boolean, basket As Shape, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double) With basket If moveUp Then bTop = .Top + .Height / 4 Else bTop = .Top + .Height / 4 * 2.5 End If bBottom = .Top + .Height - adjustX bLeft = .Left + adjustX bRight = .Left + .Width - adjustX End With End Sub
Private Sub Parabola(myBall As Variant, p As Double, q As Double) Dim x As Double, y As Double Dim w As Double, h As Double Dim a As Double Const grids As Long = 50 Dim graduation As Double Dim z As Long
With myBall x = .Left + .Width / 2 y = .Top + .Height / 2 w = .Width h = .Height End With
graduation = (p - x) / grids
a = (y - q) / (x - p) ^ 2
For z = 1 To grids
If z = grids Then x = p y = q Else x = x + graduation y = a * (x - p) ^ 2 + q End If
myBall.Left = x - w / 2 myBall.Top = y - h / 2
Sleep 10 DoEvents DoEvents
Next
End Sub
Private Function makeBall(v() As Shape) As Boolean Dim sp As Shape Dim vFlag As Boolean
With ActiveSheet For Each sp In .Shapes If sp.Name Like "ovl*" And sp.Visible Then If vFlag Then ReDim Preserve v(1 To UBound(v) + 1) Else ReDim v(1 To 1) vFlag = True End If Set v(UBound(v)) = sp makeBall = True End If Next End With
End Function
Sub Reset10() Dim sp As Shape Dim bTop As Double, bLeft As Double, bRight As Double, bBottom As Double Dim v() As Shape Dim vFlag As Boolean Dim basket As Shape
With ActiveSheet
Set basket = .Shapes("basket") basket.ZOrder msoBringToFront '★ 追加 basket.Fill.Transparency = transCalm '★ 追加
bRangeSet False, basket, bLeft, bRight, bTop, bBottom
For Each sp In .Shapes If sp.Name Like "ovl*" And Not sp.Visible Then sp.Visible = True Call Parabola(sp, Int((bLeft + sp.Width / 2 - (bRight - sp.Width / 2) + 1) * Rnd + (bRight - sp.Width / 2)), Int((bTop - sp.Height / 2 - (bBottom - sp.Height / 2) + 1) * Rnd + (bBottom - sp.Height / 2))) End If Next
End With
End Sub
(ぶらっと)
レベル1からレベル2に移行したときのがらがらの角度によっては、逆に、がらがらの回転が止まっているように 見える場合がある。 そういう場合は、↓キーでレベル1に戻した後、再度 ↑キーでレベル2にあげて試してみてね。
(ぶらっと)
addRote2 を 5 あたりにすると、比較的、安定して早く回っているように見えるかも。
Private Const addRote2 As Long = 5 'レベル2 の各ボール位置移動後の回転角度単位 '★ 修正
それと、
Private Const transBusy As Double = 0.05 '回っているときのがらがらの透明度 '★ 追加
このあたりにしておくとより、シルエットのような感じになるかな?
(ぶらっと)
どうも、レベル2 にしたときに回転が止まって見えるケースが増えた様な気がする・・・・ このあたり、もう少し、あれこれ、いじってみるけど、そちらでの結果を教えてね・
(ぶらっと)
こちらで以下にすると、レベル2で、安定して回転している。
Private Const addRote2 As Long = 10 'レベル2 の各ボール位置移動後の回転角度単位 '★ 修正
で、BallSet を
Private Sub BallSet(v As Variant, bLeft As Double, bRight As Double, bTop As Double, bBottom As Double, basket As Shape) Dim sp As Variant For Each sp In v sp.Left = Int((bLeft - (bRight - sp.Width) + 1) * Rnd + (bRight - sp.Width)) sp.Top = Int((bTop - (bBottom - sp.Height) + 1) * Rnd + (bBottom - sp.Height)) If moveUp Then basket.Rotation = (basket.Rotation + addRote) Mod 360 '★追加 DoEvents End If Next basket.ZOrder msoBringToFront '★ 変更 End Sub
(ぶらっと)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.