C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

画像の切替 0の時は画像0を、1の時は画像1を…

[トピック内 18 記事 (1 - 18 表示)]  << 0 >>

■86965 / inTopicNo.1)  画像の切替 0の時は画像0を、1の時は画像1を…
  
□投稿者/ 無理ゲー (1回)-(2018/04/05(Thu) 21:05:22)

分類:[C#] 

C#で画像の切替をしたいのですが
数値を変動させるボタンの上げ下げを用意し、数値で0の時は画像0を1の時は画像1を、2の時は画像2を、3の時は画像3を…
というようなことがしたいです。
具体的にどのようなコードを使って書いたらいいですか?
引用返信 編集キー/
■86966 / inTopicNo.2)  Re[1]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ WebSurfer (1453回)-(2018/04/05(Thu) 21:23:17)
No86965 (無理ゲー さん) に返信

あなたが何を作っているか(Windows Forms? WPF? ASP.NET Web Forms? その他?)と
自分の開発環境(OS, Visual Studio, .NET のバージョンなど)ぐらいは質問の一行
あたりに書きませんか?
引用返信 編集キー/
■86967 / inTopicNo.3)  Re[2]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 無理ゲー (2回)-(2018/04/05(Thu) 21:34:21)
No86966 (WebSurfer さん) に返信
> ■No86965 (無理ゲー さん) に返信
>
> あなたが何を作っているか(Windows Forms? WPF? ASP.NET Web Forms? その他?)と
> 自分の開発環境(OS, Visual Studio, .NET のバージョンなど)ぐらいは質問の一行
> あたりに書きませんか?

スミマセン。。。。
Visual Studioで作成してます。
具体的にはゲームのライフカウンターを作成してまして、
マッチポイントを☆で表示したいのです。
画像は用意してあるので☆が3つ並んだ状態での

☆☆☆ コレを ★☆☆ とか ★★☆ みたいに上げ下げしたい内容になります。

素人なもんで作ってみてるのでお力添えください。。。。

引用返信 編集キー/
■86968 / inTopicNo.4)  Re[3]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ WebSurfer (1454回)-(2018/04/05(Thu) 21:53:49)
No86967 (無理ゲー さん) に返信

ゲームと言うと Unity とかでしょうか? 何にせよゲームでは自分はお役に立てそうもありません。

すみませんが、他の方の回答をお待ちいただくようお願いします。
引用返信 編集キー/
■86974 / inTopicNo.5)  Re[1]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 魔界の仮面弁士 (1606回)-(2018/04/06(Fri) 10:00:04)
No86965 (無理ゲー さん) に返信
> 数値を変動させるボタンの上げ下げを用意し、数値で0の時は画像0を1の時は画像1を、2の時は画像2を、3の時は画像3を…
> というようなことがしたいです。

アプリケーションの作成時に、どのプロジェクト テンプレートを使用しましたか?

Visual Studio + C# と一口に言っても、プロジェクトの種類ごとに
異なるライブラリが使われており、そのそれぞれで記述が異なってきます。

ブラウザー上で動かす Web アプリとか(ASP.NET Web Forms、ASP.NET MVC 等々)
デスクトップ上で動かすアプリとか(Windows Forms、WPF、UWP 等々)
そのほかにも Xamarin.Forms や Unity 等々、いろいろなものがあります。


> 具体的にどのようなコードを使って書いたらいいですか?

とりあえず Windows フォーム アプリケーションと仮定して回答してみます。

画像は準備済みとのことなので、プロジェクトのプロパティの[リソース]タブから、
それぞれの画像を埋め込んでおき、それを利用するようにしてみます。その上で、
番号でアクセスしやすいよう、それをコレクション(List<Bitmap> など)あるいは配列( Bitmap[] など)に詰めなおします。

 private List<Bitmap> LifeImages = new List<Bitmap>();
 private void Form1_Load(object sender, EventArgs e)
 {
   // リソース名は、実際の画像名に合わせておきます
   LifeImages.Add(Properties.Resources.画像0);
   LifeImages.Add(Properties.Resources.画像1);
   LifeImages.Add(Properties.Resources.画像2);
 }

あとはその画像を表示したいところで、
 int matchPoint = 1; // マッチポイントを表す整数値
を使って
 pictureBox1.Image = LifeImages[matchPoint];
などと指定してみるのはどうでしょう。
引用返信 編集キー/
■86985 / inTopicNo.6)  Re[2]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 無理ゲー (1回)-(2018/04/06(Fri) 16:47:38)
返信ありがとうございます。

> とりあえず Windows フォーム アプリケーションと仮定して回答してみます。

Windowsフォームアプリケーションです。素人なもんで具体的に書けずスミマセン。

とりあえず以下のように書いてみましたが、星が1個しか動かず…
何気にマウスホイール絡ませてみちゃってるのでややこしいのかも…

本当にド素人で興味本位でつくってみてるので悪いところたくさんあるかも知れませんが
手直しお願いします。本当に調べてもわからない。。。。。。

int y = 0;
        
        private List<Bitmap> StarImages = new List<Bitmap>();
        private void UserMatchStar_MouseWheel(object sender, MouseEventArgs e)
        {
            StarImages.Add(Properties.Resources.MATCH_STAR_0);
            StarImages.Add(Properties.Resources.MATCH_STAR_1);
            StarImages.Add(Properties.Resources.MATCH_STAR_2);
            StarImages.Add(Properties.Resources.MATCH_STAR_3);
        

            if (!UserMatchStar.Bounds.Contains(e.Location)) return;
            if (e.Delta > 0)

            {
                ++y;
                if (y >= 3) y = 3;
                
                {
                    int matchPoint = 1;
                    UserMatchStar.Image = StarImages[matchPoint];
                }
                

            }

            else if (e.Delta < 0)

            {
                --y;
                if (y <= 0) y = 0;
                int matchPoint = 0;
                UserMatchStar.Image = StarImages[matchPoint];

            }

        }

引用返信 編集キー/
■86987 / inTopicNo.7)  Re[3]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 魔界の仮面弁士 (1609回)-(2018/04/06(Fri) 17:16:17)
No86985 (無理ゲー さん) に返信
> private void UserMatchStar_MouseWheel(object sender, MouseEventArgs e)
> {
>  StarImages.Add(Properties.Resources.MATCH_STAR_0);
>  StarImages.Add(Properties.Resources.MATCH_STAR_1);

まずココが間違ってます。
これだと、ホイールを回すたびに Add されているので、
StarImages.Count が 0→4→8→12→16→… のように、
画像が 4 ずつ増えてしまうことになります。


必要なのは StarImages[0]〜StarImages[3] だけなのですから、
同じ画像を繰り返し Add する必要はありません。

Form が Load されたタイミングでのみ Add しておけば十分です。
先ほど私は
>> private void Form1_Load(object sender, EventArgs e)
と書いていましたよね。


それと Properties.Resources.MATCH_STAR_0 は、
リソース内に埋め込まれたバイナリデータを元にして、
新たな Bitmap インスタンスを生成する処理であることにも注意が必要です。

たとえば、MATCH_STAR_0 を 2 回呼び出して
 Bitmap image1 = Properties.Resources.MATCH_STAR_0;
 Bitmap image2 = Properties.Resources.MATCH_STAR_0;
 if (image1 == image2) {
  textBox1.Text = "同じインスタンス";
 } else {
  textBox1.Text = "異なるインスタンス";
 }
とした場合、image1 と image2 は異なるインスタンスを意味します。

むやみに呼び出すと、その分メモリ消費が増えることになりますので、
StarImages に蓄えた後は、StarImages[0]〜StarImages[3]のみを使うようにし、
Properties.Resources.MATCH_STAR_0 の使用を避けるようにします。



> ++y;
> if (y >= 3) y = 3;
> {
>  int matchPoint = 1;
>  UserMatchStar.Image = StarImages[matchPoint];
> }

波括弧の対応を確認しなおしてみてください。
上記は要するに、
 ++y;
 if (y >= 3)
 {
  y = 3;
 }
 UserMatchStar.Image = StarImages[1];
という意味になってしまっています。



変数 y がホイールに合わせて増減し、0〜3 の範囲に収まるようにしたいのなら、
  y = Math.Max(0, Math.Min(3, y + Math.Sign(e.Delta)));
  UserMatchStar.Image = StarImages[y];
という 2 行で済みます。
引用返信 編集キー/
■86990 / inTopicNo.8)  Re[4]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 無理ゲー (3回)-(2018/04/06(Fri) 19:03:14)
ハンドルされてない例外????
なんか一瞬できたような気がするんですが、、、、
まためちゃくちゃになってしまいました。
うーん。。。。。


int y = 0;
        
        private List<Bitmap> StarImages = new List<Bitmap>();
        private void Form1_Load(object sender, EventArgs e)
            {
                StarImages.Add(Properties.Resources.MATCH_STAR_1);
                StarImages.Add(Properties.Resources.MATCH_STAR_2);
                StarImages.Add(Properties.Resources.MATCH_STAR_3);
            }

            private void UserMatchStar_MouseWheel(object sender, MouseEventArgs e)
            {
                if (!UserMatchStar.Bounds.Contains(e.Location)) return;
                if (e.Delta > 0)
                    ++y;
                {
                    y = Math.Max(0, Math.Min(3, y + Math.Sign(e.Delta)));
                    UserMatchStar.Image = StarImages[y];
                }
            }

引用返信 編集キー/
■86994 / inTopicNo.9)  Re[5]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 魔界の仮面弁士 (1611回)-(2018/04/06(Fri) 19:47:27)
2018/04/06(Fri) 21:14:03 編集(投稿者)

No86990 (無理ゲー さん) に返信
> ハンドルされてない例外????
どの行で例外が発生し、その時の変数の値が何であるかを調べてみると、
解決に近づくかと思いますよ。


> StarImages.Add(Properties.Resources.MATCH_STAR_1);
> StarImages.Add(Properties.Resources.MATCH_STAR_2);
> StarImages.Add(Properties.Resources.MATCH_STAR_3);

MATCH_STAR_0 は使わないようになったのですね。

先ほどは Add を 4 回ずつ呼び出していましたが、
今回は、 Add が 3 回だけ呼ばれているわけです。

そしてこれによって StarImages[0]、StarImages[1]、StarImages[2] が
用意されたということになります。インデックスの範囲が 0〜2 となるので
[-1] や [3] を渡さないよう注意してくださいね。


> if (!UserMatchStar.Bounds.Contains(e.Location)) return;
これは
 if (!UserMatchStar.Bounds.Contains(e.Location))
 {
  return;
 }
と同義ですよね。


> if (e.Delta > 0)
>  ++y;
> {
>   y = Math.Max(0, Math.Min(3, y + Math.Sign(e.Delta)));
>   UserMatchStar.Image = StarImages[y];
> }

これは、
 if (e.Delta > 0)
 {
  ++y;
 }
 {
   y = Math.Max(0, Math.Min(3, y + Math.Sign(e.Delta)));
   UserMatchStar.Image = StarImages[y];
 }
と同じ意味であり、すなわち
 if (e.Delta > 0)
 {
  ++y;
 }
 y = Math.Max(0, Math.Min(3, y + Math.Sign(e.Delta)));
 UserMatchStar.Image = StarImages[y];
ということになりますが、その点は把握されていますでしょうか。


それと
 y = Math.Max(0, Math.Min(3, y + Math.Sign(e.Delta)));
が何をやっているかは分かりますか?
(分かりにくいようであれば、無理に Math を使う必要は無いと思います)


【ヒント】
Math.Max(0, intValue) は、常に「0 以上の整数」を返します。
Math.Min(3, intValue) は、常に「3 以下の整数」を返します。
Math.Sign( intValue ) は、intValue の符号にあわせて「-1」「0」「+1」のいずれかを返します。
引用返信 編集キー/
■87001 / inTopicNo.10)  Re[6]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 無理ゲー (4回)-(2018/04/06(Fri) 22:11:44)
Mathは使わない事にします。
段々わかってきたような気がする。。。。
試しに以下のようにしたら(結局元に戻してみた。)

int y = 0;

        private List<Bitmap> StarImageList = new List<Bitmap>();
        private void Form1_Load(object sender, EventArgs e)
        {

            StarImageList.Add(Properties.Resources.MATCH_STAR_1);
            StarImageList.Add(Properties.Resources.MATCH_STAR_2);
            StarImageList.Add(Properties.Resources.MATCH_STAR_3);
        }

        private void UserMatchStar_MouseWheel(object sender, MouseEventArgs e)
        {

            if (!UserMatchStar.Bounds.Contains(e.Location)) return;
            if (e.Delta > 0)
            {
                ++y;
                if (y >= 3) y = 3;
                UserMatchStar.Image = Properties.Resources.MATCH_STAR_3;
        
        // 試しにココをリソースから拾ってみたらいけたので、StarImageList.AddからStarImageList[y]に反映が
         うまくいってないような気がします。これはどうすればよいのでしょうか? 

      

            }
            else if (e.Delta < 0)
            {
                --y;
                if (y <= 0) y = 0;
                UserMatchStar.Image = StarImageList[y];
            }


        }

引用返信 編集キー/
■87002 / inTopicNo.11)  Re[7]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 魔界の仮面弁士 (1615回)-(2018/04/06(Fri) 22:52:51)
No87001 (無理ゲー さん) に返信
> StarImageList.Add(Properties.Resources.MATCH_STAR_1);
> StarImageList.Add(Properties.Resources.MATCH_STAR_2);
> StarImageList.Add(Properties.Resources.MATCH_STAR_3);

最初の質問では
 「0の時は画像0を1の時は画像1を、2の時は画像2を、3の時は画像3を」
と言っていたので、画像数は最低でも 4 つあるはずです。

でも今回 Add したのは、3 つだけですよね。どちらが正しいのでしょうか?


> if (y >= 3) y = 3;

先ほども書きましたが、インデックスの範囲を確認してください。

画像が 3 つなら、y が取りうる範囲は 0〜2 でなければなりません。
画像が 4 つなら、y が取りうる範囲は 0〜3 でなければなりません。
画像が 9 つなら、y が取りうる範囲は 0〜8 でなければなりません。


とりうる画像数が不定であるのなら、指定可能な最大値を
 int maxIndex = StarImages.GetUpperBound(0);
で調べることもできます。登録した画像数が 4 個なら、maxIndex に 3 が入ります。


> Mathは使わない事にします。

ちなみに、

 if (e.Delta > 0) {
  y++;
 } else if (e.Delta < 0) {
  y--;
 }

という処理は、if 文を使わずとも

 y += Math.Sign(e.Delta);

という一行で表すことができます。


なので、これらをまとめると

private int y = 0;
private int MaxIndex = 0;
private List<Bitmap> StarImageList = new List<Bitmap>();
private void Form1_Load(object sender, EventArgs e)
{
 // 番号でアクセスできるよう、画像を保持しておく
 StarImageList.Add(Properties.Resources.MATCH_STAR_0);
 StarImageList.Add(Properties.Resources.MATCH_STAR_1);
 StarImageList.Add(Properties.Resources.MATCH_STAR_2);
 StarImageList.Add(Properties.Resources.MATCH_STAR_3);
 StarImageList.Add(Properties.Resources.MATCH_STAR_4);
 StarImageList.Add(Properties.Resources.MATCH_STAR_5);

 // 指定できる最大番号
 MaxIndex = StarImages.GetUpperBound(0);
}

private void UserMatchStar_MouseWheel(object sender, MouseEventArgs e)
{
 if (!UserMatchStar.Bounds.Contains(e.Location)) { return; }

 // ホイールを回すたびに ±1 する
 y += Math.Sign(e.Delta);

 // 上限値を超えたり、下限値 0 を下回ったりしないように補正
 if ( maxIndex < y ) { y = maxIndex; }
 else if ( y < 0 ) { y = 0; }

 // 番号を使って画像を取得
 UserMatchStar.Image = StarImageList[y];
}

ということになります。


MouseWheel のイベント部は、さらに圧縮して下記のようにも書けますが、
いくら何でもこれは読みにくいですね。

private void UserMatchStar_MouseWheel(object sender, MouseEventArgs e)
{
 if (UserMatchStar.Bounds.Contains(e.Location))
 {
  UserMatchStar.Image = StarImageList[y = Math.Max(0, Math.Min(y + Math.Sign(e.Delta), StarImages.GetUpperBound(0)))];
 }
}

引用返信 編集キー/
■87004 / inTopicNo.12)  Re[8]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 無理ゲー (5回)-(2018/04/06(Fri) 23:43:36)
こと細かに書いてくださってありがとうございます。。。。


> 最初の質問では
>  「0の時は画像0を1の時は画像1を、2の時は画像2を、3の時は画像3を」
> と言っていたので、画像数は最低でも 4 つあるはずです。
>
> でも今回 Add したのは、3 つだけですよね。どちらが正しいのでしょうか?

星の数は3つで
☆☆☆ ★☆☆ ★★☆ ★★★ の全部で4つの画像があります。


> 先ほども書きましたが、インデックスの範囲を確認してください。
>
> 画像が 3 つなら、y が取りうる範囲は 0〜2 でなければなりません。
> 画像が 4 つなら、y が取りうる範囲は 0〜3 でなければなりません。
> 画像が 9 つなら、y が取りうる範囲は 0〜8 でなければなりません。


これに関しては理解できました。


>  // 指定できる最大番号
>  MaxIndex = StarImages.GetUpperBound(0);
> }

コピペしてみましたが
StarImagesはStarImageListの間違いですよね?変更すると今度はGetUpperBoundに赤波が入ってしまいます。
それとやはりyが取得できてないようです。

引用返信 編集キー/
■87005 / inTopicNo.13)  Re[9]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 魔界の仮面弁士 (1617回)-(2018/04/07(Sat) 00:14:23)
No87004 (無理ゲー さん) に返信
> StarImagesはStarImageListの間違いですよね?変更すると今度はGetUpperBoundに赤波が入ってしまいます。

失礼しました。未テストのまま、掲示板上に直接コードを書いてしまいました。
GetUpperBound は配列の場合に使うメソッドですが、今回は配列ではなく、List<> を提示していたんでしたっけ…。


最大値は個数 -1 なので、この場合は
 MaxIndex = StarImageList.Count - 1;
にしておいてください。
といっても、画像数が 4 個固定なのであれば、ここは常に 3 になるでしょうけれども。


> // 上限値を超えたり、下限値 0 を下回ったりしないように補正
> if ( maxIndex < y ) { y = maxIndex; }
> else if ( y < 0 ) { y = 0; }

ここの maxIndex は、MaxIndex の間違いです。
引用返信 編集キー/
■87006 / inTopicNo.14)  Re[10]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 無理ゲー (6回)-(2018/04/07(Sat) 00:29:51)
ずっと付き合ってもらってスイマセン。。。。
自分でちゃんとしなきゃダメですよね。。。。

うーん。。。。
やはり

// 番号を使って画像を取得
UserMatchStar.Image = StarImageList[y];

のところに

ハンドルされていない例外
System.ArgumentOutOfRangeException: 'インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
パラメーター名:index'

というのが出ます。これってなんなんでしょう????
引用返信 編集キー/
■87007 / inTopicNo.15)  Re[11]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 魔界の仮面弁士 (1618回)-(2018/04/07(Sat) 00:31:33)
No87006 (無理ゲー さん) に返信
> ハンドルされていない例外
> System.ArgumentOutOfRangeException: 'インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
> パラメーター名:index'

そのエラーが発生した際に、変数 y の値が何を指しているのかを確認してみてください。
引用返信 編集キー/
■87008 / inTopicNo.16)  Re[12]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 無理ゲー (8回)-(2018/04/07(Sat) 00:35:35)
No87007 (魔界の仮面弁士 さん) に返信
> ■No87006 (無理ゲー さん) に返信
>>ハンドルされていない例外
>>System.ArgumentOutOfRangeException: 'インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
>>パラメーター名:index'
>
> そのエラーが発生した際に、変数 y の値が何を指しているのかを確認してみてください。

[y]の所にカーソルをあてると0と表示されます。
引用返信 編集キー/
■87009 / inTopicNo.17)  Re[13]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 無理ゲー (3回)-(2018/04/07(Sat) 00:37:27)
int Form1.y かな?
引用返信 編集キー/
■87010 / inTopicNo.18)  Re[13]: 画像の切替 0の時は画像0を、1の時は画像1を…
□投稿者/ 魔界の仮面弁士 (1619回)-(2018/04/07(Sat) 00:47:39)
2018/04/07(Sat) 00:54:15 編集(投稿者)

No87008 (無理ゲー さん) に返信
>>>System.ArgumentOutOfRangeException: 'インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
>>>パラメーター名:index'
>>そのエラーが発生した際に、変数 y の値が何を指しているのかを確認してみてください。
> [y]の所にカーソルをあてると0と表示されます。

変数 y が 0 でエラーになるということは、
 UserMatchStar.Image = StarImageList[0];
へのアクセスが失敗しているという事ですね。

ということは、一度も StarImageList.Add が呼ばれておらず、
StarImageList.Count == 0 な状態に陥っている可能性が考えられます。
Form1_Load のイベント割り当てが漏れているということはありませんか?

Load イベントにブレークポイントをはるなどして、
StarImageList.Add の行を通過しているか確認してみてください。


また、StarImageList の準備が完了する前に、MouseWheel のイベントが
処理されてしまってもエラーにならぬよう、MouseWheel イベントの先頭で
 if (StarImageList.Count == 0) { return; }
などとしてガードしておいた方が良いかもしれません。
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ