スロットの絵柄をループ処理で への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 モウヘイ  (高校生)
投稿日時
2009/3/31 01:39:09
多くのことをアドバイスしていただき、皆様、本当にありがとうございます!これらを参考に、もう一度しっかりと学習し、プログラム作成に役立てたいと思います。
投稿者 拓  (社会人)
投稿日時
2009/3/30 19:12:03
ちなみに絵柄を3つから4つに表示を変更するときには下記のようになります。
ublic Class Form1
Dim iti As Integer
Dim slot() As Integer = New Integer() {4, 3, 2, 1, 3, 0, 2, 4, 1} 'ImageList1の画像サイズは「80,80」
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
PictureBox1.Image = New Bitmap(80, 320)
iti = 0
drawslot(PictureBox1, iti)
End Sub
Private Sub drawslot(ByRef pb As PictureBox, ByVal p As Integer)
Dim i As Integer
Dim g As Graphics = Graphics.FromImage(pb.Image)
For i = 0 To 3
g.DrawImage(ImageList1.Images(slot((p + i) Mod 9)), 0, 240 - i * 80)
Next
g.Dispose()
pb.Invalidate()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
iti = (iti + 1) Mod 9
drawslot(PictureBox1, iti)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer1.Enabled = True
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Enabled = False
End Sub
End Class
ublic Class Form1
Dim iti As Integer
Dim slot() As Integer = New Integer() {4, 3, 2, 1, 3, 0, 2, 4, 1} 'ImageList1の画像サイズは「80,80」
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
PictureBox1.Image = New Bitmap(80, 320)
iti = 0
drawslot(PictureBox1, iti)
End Sub
Private Sub drawslot(ByRef pb As PictureBox, ByVal p As Integer)
Dim i As Integer
Dim g As Graphics = Graphics.FromImage(pb.Image)
For i = 0 To 3
g.DrawImage(ImageList1.Images(slot((p + i) Mod 9)), 0, 240 - i * 80)
Next
g.Dispose()
pb.Invalidate()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
iti = (iti + 1) Mod 9
drawslot(PictureBox1, iti)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer1.Enabled = True
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Enabled = False
End Sub
End Class
投稿者 よねKEN  (社会人)
投稿日時
2009/3/30 18:58:35
#上の方の2つの(削除)は私が削除したものです。質問のコードを読み間違えて
#見当はずれなことを書いていたので削除しましたm(_ _)m
> できれば同じ処理がある所はまとめるようなシンプルな書き方にしたいのですが。
こちらについてのみコメントします。
改善すべきポイントはいくつかありますが、一遍にやろうとすると大変ですから、
まずは似た機能を関数化するところから始めましょう。
メソッドの作り方の基本的なところは以下を参照してください。
「第11回 メソッドを作る」
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard11.htm
○オリジナルのソースから以下を抜粋して関数化の流れを書いて見ます。
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Randomize()
x = Int(11 * Rnd())
Select Case x
Case 0
PictureBox1.Image = PictureBox4.Image
Case 1
PictureBox1.Image = PictureBox5.Image
・
・
・
Case 9
PictureBox1.Image = PictureBox13.Image
End Select
End Sub
○ステップ1
似たような処理はとりあえず、引数、戻り値なしのメソッドとして切り出す。
以下のような感じになります。
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
SetSlotImage()
End Sub
Private Sub SetSlotImage()
Randomize()
x = Int(11 * Rnd())
Select Case x
Case 0
PictureBox1.Image = PictureBox4.Image
Case 1
PictureBox1.Image = PictureBox5.Image
・
・
・
Case 9
PictureBox1.Image = PictureBox13.Image
End Select
End Sub
○ステップ2
この処理はTimer1、Timer2、Timer3での処理でほとんどが同じです。
違うのは、乱数用の変数とスロットの画像のセットする対象のピクチャーボックスが違うところです。
3つの乱数用の変数x,y,zはこのままでは扱いにくいので配列にします。
x,y,zは削除して代わりに以下の宣言を追加します。
private currentSlotImageIndex(2) As Integer
x →currentSlotImageIndex(0)、y →currentSlotImageIndex(1)、z →currentSlotImageIndex(2)が対応します。
そして、SetSlotImageメソッドを改造して、どのリール(あの回転している部分の名称。言葉が正しいかはあまり自信なし)の番号を0~2で指定できるようにします。
対象(=target)のピクチャーボックスを指定できるように修正します。
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
SetSlotImage(0, PictureBox1)
End Sub
Private Sub SetSlotImage(ByVal slotIndex As Integer, ByVal target As PictureBox)
Randomize()
currentSlotImageIndex(slotIndex) = Int(11 * Rnd())
Select Case currentSlotImageIndex(slotIndex)
Case 0
target.Image = PictureBox4.Image
Case 1
target.Image = PictureBox5.Image
・
・
・
Case 9
target.Image = PictureBox13.Image
End Select
End Sub
○ステップ3
Timer2_Tick、Timer3_Tickの処理を同様に
SetSlotImage(1, PictureBox2)、SetSlotImage(2, PictureBox3)
と書き換えることで共通化ができます。
これである程度共通化されました。しかし、まだ中途半端感のある実装ですね。
続きは考えてみてください。
また他のの改善点として気になるのは、PictureBox4.Image~PictureBox13.Imageです。
これらはPictureBox1~3に表示するイメージが準備してあるのだと思いますが、
PictureBoxを使う必要はないのではないでしょうか。
拓さんのご指摘にあるImageListコントロールを使ってもよいでしょうし、
Imageクラスの配列やリスト(コレクション)に格納しておくのでもよいでしょう。
そのためにはまずは以下の講座を熟読してみるのがよいのではないでしょうか。
「第27回 配列」
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard27.htm
「第28回 コレクション」
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard28.htm
#見当はずれなことを書いていたので削除しましたm(_ _)m
> できれば同じ処理がある所はまとめるようなシンプルな書き方にしたいのですが。
こちらについてのみコメントします。
改善すべきポイントはいくつかありますが、一遍にやろうとすると大変ですから、
まずは似た機能を関数化するところから始めましょう。
メソッドの作り方の基本的なところは以下を参照してください。
「第11回 メソッドを作る」
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard11.htm
○オリジナルのソースから以下を抜粋して関数化の流れを書いて見ます。
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Randomize()
x = Int(11 * Rnd())
Select Case x
Case 0
PictureBox1.Image = PictureBox4.Image
Case 1
PictureBox1.Image = PictureBox5.Image
・
・
・
Case 9
PictureBox1.Image = PictureBox13.Image
End Select
End Sub
○ステップ1
似たような処理はとりあえず、引数、戻り値なしのメソッドとして切り出す。
以下のような感じになります。
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
SetSlotImage()
End Sub
Private Sub SetSlotImage()
Randomize()
x = Int(11 * Rnd())
Select Case x
Case 0
PictureBox1.Image = PictureBox4.Image
Case 1
PictureBox1.Image = PictureBox5.Image
・
・
・
Case 9
PictureBox1.Image = PictureBox13.Image
End Select
End Sub
○ステップ2
この処理はTimer1、Timer2、Timer3での処理でほとんどが同じです。
違うのは、乱数用の変数とスロットの画像のセットする対象のピクチャーボックスが違うところです。
3つの乱数用の変数x,y,zはこのままでは扱いにくいので配列にします。
x,y,zは削除して代わりに以下の宣言を追加します。
private currentSlotImageIndex(2) As Integer
x →currentSlotImageIndex(0)、y →currentSlotImageIndex(1)、z →currentSlotImageIndex(2)が対応します。
そして、SetSlotImageメソッドを改造して、どのリール(あの回転している部分の名称。言葉が正しいかはあまり自信なし)の番号を0~2で指定できるようにします。
対象(=target)のピクチャーボックスを指定できるように修正します。
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
SetSlotImage(0, PictureBox1)
End Sub
Private Sub SetSlotImage(ByVal slotIndex As Integer, ByVal target As PictureBox)
Randomize()
currentSlotImageIndex(slotIndex) = Int(11 * Rnd())
Select Case currentSlotImageIndex(slotIndex)
Case 0
target.Image = PictureBox4.Image
Case 1
target.Image = PictureBox5.Image
・
・
・
Case 9
target.Image = PictureBox13.Image
End Select
End Sub
○ステップ3
Timer2_Tick、Timer3_Tickの処理を同様に
SetSlotImage(1, PictureBox2)、SetSlotImage(2, PictureBox3)
と書き換えることで共通化ができます。
これである程度共通化されました。しかし、まだ中途半端感のある実装ですね。
続きは考えてみてください。
また他のの改善点として気になるのは、PictureBox4.Image~PictureBox13.Imageです。
これらはPictureBox1~3に表示するイメージが準備してあるのだと思いますが、
PictureBoxを使う必要はないのではないでしょうか。
拓さんのご指摘にあるImageListコントロールを使ってもよいでしょうし、
Imageクラスの配列やリスト(コレクション)に格納しておくのでもよいでしょう。
そのためにはまずは以下の講座を熟読してみるのがよいのではないでしょうか。
「第27回 配列」
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard27.htm
「第28回 コレクション」
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard28.htm
投稿者 拓  (社会人)
投稿日時
2009/3/30 18:54:42
簡単に作ってみました。
Public Class Form1
Dim iti As Integer
Dim slot() As Integer = New Integer() {4, 3, 2, 1, 3, 0, 2, 4, 1} 'ImageList1の画像サイズは「80,80」
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
PictureBox1.Image = New Bitmap(80, 240)
iti = 0
drawslot(PictureBox1, iti)
End Sub
Private Sub drawslot(ByRef pb As PictureBox, ByVal p As Integer)
Dim i As Integer
Dim g As Graphics = Graphics.FromImage(pb.Image)
For i = 0 To 2
g.DrawImage(ImageList1.Images(slot((p + i) Mod 9)), 0, 160 - i * 80)
Next
g.Dispose()
pb.Invalidate()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
iti = (iti + 1) Mod 9
drawslot(PictureBox1, iti)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer1.Enabled = True
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Enabled = False
End Sub
End Class
Public Class Form1
Dim iti As Integer
Dim slot() As Integer = New Integer() {4, 3, 2, 1, 3, 0, 2, 4, 1} 'ImageList1の画像サイズは「80,80」
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
PictureBox1.Image = New Bitmap(80, 240)
iti = 0
drawslot(PictureBox1, iti)
End Sub
Private Sub drawslot(ByRef pb As PictureBox, ByVal p As Integer)
Dim i As Integer
Dim g As Graphics = Graphics.FromImage(pb.Image)
For i = 0 To 2
g.DrawImage(ImageList1.Images(slot((p + i) Mod 9)), 0, 160 - i * 80)
Next
g.Dispose()
pb.Invalidate()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
iti = (iti + 1) Mod 9
drawslot(PictureBox1, iti)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer1.Enabled = True
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Enabled = False
End Sub
End Class
投稿者 (削除されました)  ()
投稿日時
2009/3/30 18:37:57
(削除されました)
投稿者 (削除されました)  ()
投稿日時
2009/3/30 18:36:07
(削除されました)
投稿者 あにす  (社会人)
投稿日時
2009/3/30 18:29:37
無理やりシンプルにしようとしてわかりにくくなった例
ごめんなさい面白そうなんで書いてみただけです。
Public Class Form1
Const min As Integer = 0
Const max As Integer = 9
Const drumSize As Integer = 100
Dim imageList1 As New ImageList()
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
imageList1.ImageSize = New Size(drumSize, drumSize)
'画像が無いので自分で描いてるだけ
For i As Integer = min To max
Dim img As New Bitmap(drumSize, drumSize)
Using g As Graphics = Graphics.FromImage(img)
'サイズは適当に収まるように設定
Dim fnt As New Font(Me.Font.FontFamily.Name, drumSize * 0.8)
g.DrawString(i.ToString(), fnt, Brushes.Black, 0, 0)
End Using
Me.imageList1.Images.Add(img)
Next
'ドラムを作成して配置、スタート
For i As Integer = 0 To 3 - 1
Dim drum As New Drum(500, Me.imageList1)
Me.Controls.Add(drum)
drum.Location = New Point(i * drum.Width, 0)
drum.DrumStart()
Next
End Sub
End Class
Class Drum
Inherits PictureBox
WithEvents timer_ As New Timer()
Dim imgList As ImageList
Dim index As Integer = 0 - 1
''' <summary>
''' ドラムを初期化
''' </summary>
''' <param name="interval">ドラムの回転間隔</param>
''' <param name="imgList">ドラムの図柄リスト</param>
Sub New(ByVal interval As Integer, ByVal imgList As ImageList)
Me.imgList = imgList
timer_.Interval = interval
Me.Size = New Size(100, 100)
timer_Tick(timer_, EventArgs.Empty)
End Sub
''' <summary>
''' ドラムを回す
''' </summary>
Public Sub DrumStart()
timer_.Start()
End Sub
''' <summary>
''' ドラムを止める
''' </summary>
''' <remarks></remarks>
Public Sub DrumStop()
timer_.Stop()
End Sub
Private Sub timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timer_.Tick
If index = imgList.Images.Count - 1 Then
index = 0
Else
index += 1
End If
Me.Image = imgList.Images(index)
End Sub
End Class
ごめんなさい面白そうなんで書いてみただけです。
投稿者 拓  (社会人)
投稿日時
2009/3/30 15:56:29
1ドラムのデータ(絵柄)slotの配列を作成
2絵柄を格納するのにImageListコントロールを使う
3各絵柄(要素)の表示は剰余を使う
4ドラムを表示する関数を作る
というのはどうでしょうか?
2絵柄を格納するのにImageListコントロールを使う
3各絵柄(要素)の表示は剰余を使う
4ドラムを表示する関数を作る
というのはどうでしょうか?
投稿者 neptune  (社会人)
投稿日時
2009/3/30 07:49:55
私の基準で言うと、
>シンプルな書き方にしたいのですが
の必要なし。です。
無理やりやってもわかりにくくなりそう。
他の識者の意見もお待ちください。
>シンプルな書き方にしたいのですが
の必要なし。です。
無理やりやってもわかりにくくなりそう。
他の識者の意見もお待ちください。
投稿者 モウヘイ  (高校生)
投稿日時
2009/3/30 06:07:49
こんばんは、またまたお世話になります。スロットの絵柄を乱数を使わずにx,y,zのそれぞれを順に増やして0に戻すといったループで処理を行いたいのですが、どうすればいいでしょうか?できれば同じ処理がある所はまとめるようなシンプルな書き方にしたいのですが。アドバイスよろしくお願いします。↓は乱数を使ったときのものです。
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Randomize()
x = Int(11 * Rnd())
Select Case x
Case 0
PictureBox1.Image = PictureBox4.Image
Case 1
PictureBox1.Image = PictureBox5.Image
・
・
・
Case 9
PictureBox1.Image = PictureBox13.Image
End Select
End Sub
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
Randomize()
y = Int(11 * Rnd())
Select Case y
Case 0
PictureBox2.Image = PictureBox4.Image
Case 1
PictureBox2.Image = PictureBox5.Image
・
・
・
Case 9
PictureBox2.Image = PictureBox13.Image
End Select
End Sub
Private Sub Timer3_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer3.Tick
Randomize()
z = Int(11 * Rnd())
Select Case z
Case 0
PictureBox3.Image = PictureBox4.Image
・
・
・
Case 9
PictureBox3.Image = PictureBox13.Image
End Select
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Randomize()
x = Int(11 * Rnd())
Select Case x
Case 0
PictureBox1.Image = PictureBox4.Image
Case 1
PictureBox1.Image = PictureBox5.Image
・
・
・
Case 9
PictureBox1.Image = PictureBox13.Image
End Select
End Sub
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
Randomize()
y = Int(11 * Rnd())
Select Case y
Case 0
PictureBox2.Image = PictureBox4.Image
Case 1
PictureBox2.Image = PictureBox5.Image
・
・
・
Case 9
PictureBox2.Image = PictureBox13.Image
End Select
End Sub
Private Sub Timer3_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer3.Tick
Randomize()
z = Int(11 * Rnd())
Select Case z
Case 0
PictureBox3.Image = PictureBox4.Image
・
・
・
Case 9
PictureBox3.Image = PictureBox13.Image
End Select
End Sub