[[20121112093649]] 『がらがらを作りたいのですが・・・』(ラッキー男) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『がらがらを作りたいのですが・・・』(ラッキー男)
はじめまして。
年末の抽選くじを用意するように指示された不運な事務員です。
オートシェイプでそれらしく絵を描きました。赤玉、青玉、黄玉、緑玉、黒玉と。
この玉をぐるぐると動かして一つだけ飛び出すように動かす方法を教えてください。
名案、代案、紹介等何でも良いので教えてください。
よろしくお願いします。
Excel2003、WindowsXP

 おもしろそうなので。
 シェープの名前はなんでもいいけど、コードでは以下にしている。

 かご "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

 (ぶらっと)

↑ 1行、アップ忘れ。 この標準モジュールの最初に

 Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

 (ぶらっと)

 なお、↑は、ガラガラ回数を、コードで規定しているけど、たとえば 何かのキー(シフトキーとか)
 を押すまでは、がらがら回し、キーをおしたときに止めるということもできる。

 コードで規定するとしてアップしたコードの 50回は、すくなすぎるかも。
 200回ぐらいのほうが、回しているという感じがでるかな?

 (ぶらっと)

くじならなんでもよいなら、三角くじがあります
http://download.seesaa.jp/contents/win/ent/e_other/14332/

 これどこかでリンクされていたのを試しに使ってみただけですが、色付ではないですが、
 同じ事は出来ると思いますよ

 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に戻して再スタートするには」の記述は
 どこでしょうか?
 ↑自分で組み合わせてみようと思ったのですが、よくわからなくて…

 何度もすみません。よろしくお願いします。

 (茶々)


(ぶらっと)さん
ラッキー男です。
作って頂き感謝しています。これで準備万端、後は景品を買うだけです。
後一つ疑問が・・イイですか?
basket.Rotation = 0 でカゴを回転させていると思うのですが0を1000に変えてもあまり早くなりません。
こんなものでしょうか?


 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)
指定された値は境界を超えています。
basket.Rotation = bRotation 此処で留まります。
最大30秒は回したいのですが、対応策がありましたら教えてください。
(ラッキー男)

 >チョット長く回していると(18秒ほど)実行時エラー -2147024809(80070057) 
 >指定された値は境界を超えています。 

 こちらでも、まったく別のアプリだけど、同じような制御を取り入れたもので、同じエラーが
 発生するバグがあって、「限界値を超えないような」対応を組み込んだ。

 がらがらの、どこに、どう組み込まばいいか、ちょっとさぐってみるので、しばしお待ちを。

 ところで、使っているのが、どのバージョン?
 最後にアップした、動きのレベルが2段階のもの?

 (ぶらっと)

 こちらでは、今、3分回したけどエラーにはならない。ただし Win7 + 2010
 以下のように ★のコードを追加したらどうなるかな?

    bRotation = bRotation Mod 360    '★ 追加
    basket.Rotation = bRotation  

 (ぶらっと)      

ぶらっと、見ていてくれてありがとうございます。
ホント、ラッキーな男です。
使わせていただいてるのは、がらがら5()です。
最後のはイイのですが着色したら重くて回らないので諦めました。
(ラッキー男)


ぶらっとさん、衝突してしまいました。
こちらは、WinXpで2003の環境です。
いま、動かしました。凄いの一言です。本物そっくり!!
もう一ついいですか!玉が落ちる Set winner = .Shapes("Winner")
なのですが、リアルにと思い太さのポイントを大きくしたら玉が埋まってしまいます。
これはどこを直せば良くなるのでしょうか?
(ラッキー男)

 まず、今後、がらがら5 をベースにするか がらがら6 をベースにするか確認お願い。
 先ほど連絡した basket.Rotation = bRotation  も、がらがら6なら、少しコードが異なるので。
 (対処の考え方は同じだけど)

 >太さのポイントを大きくしたら玉が埋まってしまいます

 これは具体的にはどういうことかな?

 ・最後に当選ボールを入れる箱のことを言っている?
  で、この枠を太くしたら、ボールの端っこが枠の下に埋もれてしまう?

  ★もし、そういうことなら、枠の上に表示されるように1行コードを追加する。

 ・それとも、がらがらのかご? 

  ★もし、そういうことなら、Private Const adjustX As Long = 50 の数字を少し大きくすると
   その分、動きが内側に狭められる。

 どちらのことか連絡お願いね。

 余談)あれから、こちらでは がらがら6 で、当選したボールが Winner に納められる際に
    ポーンと、弧を描いて飛び込むようにしたバージョン、がらがら7 にしている。
    また、このバージョンは、ボールが何個でもOK。(名前が ovl●● のものをすべて対象にしている)
    ご希望ならコードをアップする。

    それと、今ふと思ったんだけど、通常、このゲームは、たとえば赤玉がでれば、その玉は勝ち抜け。
    次に回すときは、赤玉は除くよね。そういうこともオプションで可能にした、がらがら8 も作ってみようかなと
      思っている。

 (ぶらっと)

ぶらっとさん、こんばんは。
わたしは、がらがら5が気に入り準備しています。
はい、最後に当選ボールを入れる箱のことを言っている?
  で、この枠を太くしたら、ボールの端っこが枠の下に埋もれてしまう?
そうです。

わたしも、動かしていて玉の数を増やすには面倒でも同じように書かないと行け無いなあと思っていました。
それと、玉が減らなくなったのがチョットと思っています。がらがら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。

 (ぶらっと)

ぶらっとさん。コードありがとうございます。
凄く長いのに驚いています。
「回すボールがありませんよ」で止まりそれでも「実行中」で実行時エラー91
オブジェクト変数またはWithブロック変数が設定されていません。
 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

 (ぶらっと)

ぶらっとさん、今拝見しました。
お忙しい中を本当に申し訳有りません。
素晴らしいの一言に尽きます。
子供の頃を思い出しました。
かごをグルグル早く回して係りの人から「もっとゆっくり回さないと玉が出てこない」と言われたのを思い出しています。
それでも早く回したい、今も同じ気持ちです。
気づいたことがもう一点あるのですがイイですか?
かごを最前面に移動させても回り出すと玉が最前面に出てきます。
玉はやっぱりかごの中に入っていないと・・・そして飛び出す。
一応回っている間はどんな動きをしているか、かごの中が見えるように透明度は10%にして
そうするとシルエットが見えてリアルになります。
かごを常に前面にはならないでしょうか?
勝手ばかり言いワガママですみません。
(ラッキー男)

 >それでも早く回したい、今も同じ気持ちです。

 レベル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

 (ぶらっと)

こんばんは、ぶらっとさん
ご返事・確認が遅くなり失礼しました。
完璧です!!、こんなの見たことがない!
素晴らしい仕上がりです。
わたしのワガママなお願いに10度もの修正を頂き本当に感謝いたします。
きっと今もこれからも大勢の方が見られて驚愕することでしょう。
ありがとうございました。
(ラッキー男)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.