質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.36%

ランダムに表示される画像に合わせて、それぞれ対応した音声ファイルを再生したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 500

kubonos

score 6

android studioでアプリを作っています。

ランダムに表示される画像(a.png~z.png)に合わせて、それぞれ対応した音声(a.wav~z.wav)を再生したいです。

<やりたい挙動>

(※画像はランダムな順番で表示されます。)

1、画像a.pngが表示される

2、ボタンを押す

3、音声a.wavが再生される。

↓(次の画像へ)

1、画像r.pngが表示される

2、ボタンを押す

3、音声r.wavが再生される。

↓(次の画像へ)

1、画像p.pngが表示される

2、ボタンを押す

3、音声p.wavが再生される。

というような挙動を作りたいです。

<試していること>

if (questionImage == a){
soundPlayer.playaSound();

}else if (questionImage.equals("b.png")){
soundPlayer.playbSound();
}

みたいな書き方でいけるのかな、、と思っているのですが、エラーが出ています。

if (questionImage == a)
の部分をどう書けばよいのか分かりません。

drawable/a.png
と書いてもおかしくなりますし・・。

素人的な間違いをしているのは分かっているのですが、3日間検索し続けても解決できません・・。

ドットインストールやyoutubeなどで検索しているのですが、同じような動作をするコードがないため、どのように画像を指定したらよいのか分かりません。

音はきちんと鳴っているので、画像のif処理のやり方を知りたいです。

とにかく、コードの書き方が分かりません・・。

ランダムに表示された画像がf.pngであったら、f.wavを再生する、というコードを書きたいです。

ポケモンクイズで、ピカチュウの画像が出てきたら、ピカチュウの鳴き声が再生されるようなプログラムも作ってみたいなと思っています(著作権には配慮します)。

下にコードを書いているのですが、2週間程度独学でやっているのですが、半分以上意味が分からず書いています。

見にくいエラー付のコードで大変申し訳ござ

コード
package com.test.java;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Random;

//波かっこ1(メイン)開始
public class MainActivity extends AppCompatActivity {

 private TextView countLabel;
 private ImageView questionImage; //ImageViewは絵を入れるための額縁
 //private TextView questionLabel;
 private Button answerBtn1;
 private Button answerBtn2;
 private Button answerBtn3;
 private Button answerBtn4;

 private String rightAnswer; //String文字型であることに注目したい
 private int rightAnswerCount = 0; //初期化=定義
 private int quizCount = 1; //初期化=定義
static final private int QUIZ_COUNT = 50; //全部の出題数を入れるのだ!!

 ArrayList<ArrayList<String>> quizArray = new ArrayList<>(); //ああ・・・これもよく分からねえ
 //ArrayList<ArrayList<String>> って普通の書き方なの?あとnewもよくわからねえ

//クイズデータ並べる
 String quizData[][] = { //[][]は多次元配列というらしい
 //{"画像名","正解",("選択2","選択3","選択4"},
 //,←これ[,]が必要なんだ!!!
 {"one","1"}, //[0][0],[0][1],...
 {"two","2"}, //[1][0],[1][1],
 {"three","3"},

 };
//クイズデータ並べた

 MySound mySound = new MySound(); // ① サウンド準備


//オーヴァーライド波かっこ(2)開始
 @Override
 protected void onCreate(Bundle savedInstanceState) { //よく分からない定型文
 super.onCreate(savedInstanceState); //よく分からない定型文2
 setContentView(R.layout.activity_main); //xmlを表示

// ② 効果音の準備wavだけどmp3sで定義されている。クイズデータと同じ並びで並べる
 int[] mp3s = {
 R.raw.a, //[0]
 R.raw.b, //[1]
 R.raw.c, //[2]
 };
 mySound.onCreate(this,mp3s); // ③ 初期化、言葉がまぎらわしいがただ定義(代入)しただけ

 countLabel = findViewById(R.id.countLabel);
 questionImage = findViewById(R.id.questionImage);
 answerBtn1 = findViewById(R.id.answerBtn1);
 answerBtn2 = findViewById(R.id.answerBtn2);
 answerBtn3 = findViewById(R.id.answerBtn3);
 answerBtn4 = findViewById(R.id.answerBtn4);

//quizDataからクイズ出題用のquizArrayを作成する
 for (int i = 0; i < quizData.length; i++) {
 //lengthは配列の要素の数を返す、length()は文字列の文字数を返すんだって
 //多次元配列だけど、[0][0],[0][1],の最初の[0]だけ返すのかな??
 //新しいArrayListを用意
 ArrayList<String> tmpArray = new ArrayList<>(); //要素を格納するためのリスト箱

 //クイズデータを追加
 tmpArray.add(quizData[i][0]); //画像名
 tmpArray.add(quizData[i][1]); //正解
 //tmpArray.add(quizData[i][2]); //選択2
 //tmpArray.add(quizData[i][3]); //選択3
 //tmpArray.add(quizData[i][4]); //選択4

 //tmpArrayの追加順番は、quizData多次元配列[0][0],[0][1],[0][2],[0][3],[0][4],[1][0],[1][1],
 //つまりtmpArrayは、ただの配列の[0],[1],[2]..になるのかな?
 //↑は多分違うようだ。tmpArrayも、多次元配列[0][0],[0][1],[0][2]のままなんだと思う。

 //tmpArrayをquizArrayに追加する
 quizArray.add(tmpArray); //ここがよく分からん。どういうことなのか?配列に配列を追加とは
 //"one","1"は[0]で取り出せるらしい。quizArrayもまだ多次元配列[0][0],[0][1],[0][2]っぽい。
 }
//quizDataからクイズ出題用のquizArrayを作成した
 showNextQuiz(); //実行showNextQuiz
 //すぐ下に処理内容が書いてある

 }
//オーヴァーライド波かっこ(2)とじ・・・とじていいのか??


// showNextQuiz波かっこ開始
 public void showNextQuiz() {
 //クイズカウントラベルを更新
 countLabel.setText("Q" + quizCount);


//ランダムな数字を取得・・下の2行で1セット文章
 Random rand = new Random();
 int randomNum = rand.nextInt(quizArray.size()); //quizArray多次元配列の[0][0]の左の数字を指すと思う
 //0~quizArrayの数-1のどこかの数字を取り出す


//音声で共通に取り出せない問題がある

 //randomNumを使ってquizArrayからクイズを一つ取り出す
 ArrayList<String> quiz = quizArray.get(randomNum); //なぜStringになるのか??
 //おそらく、["one","1"]の文字配列を呼び出しているのだろう。

//randomNumを使ってquizArrayから音を取り出せるのでは
//試しに音を鳴らしてみよう
 mySound.onPlay(randomNum);
 //おお。。ここに書く分には大丈夫そうです。第一問の時はなぜか鳴りませんけど・・


 //画像をセットする
 questionImage.setImageResource(
 getResources().getIdentifier(quiz.get(0), "drawable", getPackageName())
 ); //配列から画像名を取り出す時は quiz.get(0)

 //正解をrightAnswerにセット
 rightAnswer = quiz.get(1); //正解を取り出す時は quiz.get(1)

 //このクイズをquizArrayから削除<消したいけど消すと挙動がおかしくなる
 //quizArray.remove(randomNum);
 //消しても大丈夫そうなので消してみた。完全なるランダムになる





 } //ここに}があるから、randomNumが参照できねえ!!97行付近のshowNextQuiz

// checkAnswer波かっこ開始
 public void checkAnswer(View view){ //意味も分からん。他の書き方できないのかなあ・・・

 //どのボタンが押されたか
 Button answerBtn = findViewById(view.getId()); //意味分からん

 //ボタンのテキストを取得
 String btnText = answerBtn.getText().toString(); //ボタンテキストを取得

 String alertTitle;
//if elseの波かっこ群開始
 if (btnText.equals(rightAnswer)) {
 alertTitle = "せいかい!!";
 rightAnswerCount++;

 //mySound.onPlay(randomNum); // ④ 再生
//mySound.onPlay(1); // 0ならcが再生
//クイズ画像=cならsoundPlayer.playc();的な感じかと思う



 }else {
 alertTitle = "まちがっているよ";
 } //if elseの波かっこ群終了

//ダイアログを作成
 AlertDialog.Builder builder = new AlertDialog.Builder(this);
 builder.setTitle(alertTitle);
 builder.setMessage("こたえは" + rightAnswer + "だよ");
 builder.setPositiveButton("つぎへいく", new DialogInterface.OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 if (quizCount == QUIZ_COUNT){
 //結果画面へ移動
 Intent intent = new Intent(getApplicationContext(), ResultActivity.class);
 intent.putExtra("RIGHT_ANSWER_COUNT", rightAnswerCount);
 startActivity(intent);

 }else {
 quizCount++;
 showNextQuiz(); //showNextQuiz実行する
 } //elseとじ

 } //160行付近のpublic void onClick(DialogInterface dialog, int which) とじ
 }); //"つぎへいく"のsetPositeveButton とじ
 builder.setCancelable(false);
 builder.show();



 } // checkAnswer波かっことじ
} //大きいMainとじ

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"


    android:layout_height="fill_parent"

    tools:context=".MainActivity"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:background="@android:color/white">



    <ImageView
        android:id="@+id/questionImage"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:src="@drawable/a"/>


    <LinearLayout
        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:orientation="horizontal"
        android:gravity="center_horizontal"
        >

        <Button
            android:id="@+id/answerBtn1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:onClick="checkAnswer"
            android:text="c" />


    </LinearLayout>
</LinearLayout>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

まずif文はざっくり言うと同じ型のものでしか比較できません。
if (questionImage == a)
ではImageViewと変数aを比較しているわけですが、そもそも変数aを宣言していないのでエラーになります。(ImageViewもそのものではなくidやtagで比較した方がいいかと。。。)
ここで比較する案をしてもいいのですが、a~zまでを比較しif文を繋げていくのは面倒ですよね。。。

解決案としては思いつくのはMapを使う方法ですね。
Mapは調べたら使い方は沢山でてきます。
それで正解画像のidをキーにしてSoundPlayerをオブジェクトにしたMapを作れば
map.get(questionImage.getId()).soumdPlay();
で再生できます。(プログラムを読んでいる感じだと、SoundPlayerは独自のクラスで、soundaPlay()~soundzPlayまで作るつもりなのだと思いますが、オブジェクト指向では、1つのSoundPlayerには1つの効果音を入れるのがいいと思います)

プログラムが分からないときは、処理を1行ずつ理解していきそのときのメソッドは何をしているのか調べ、そのときの変数はどういったものが入っているのかを調べ理解していけば、効率良く勉強出来ると思いますよ。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/12/23 00:00

    ちなみにrandomNumを書く場所はそのまま変えないで大丈夫でした。

    キャンセル

  • 2019/12/23 00:05

    なんで突然うまくいったのかなあ?と思ったらjimbeさんのアドバイスより
    private int randomNum;
    を追加したからでした。

    お二方、大変ありがとうございました!!!

    キャンセル

  • 2019/12/23 01:13

    上手くいかれたようで良かったです!!
    お身体には気をつけてプログラム楽しんでください!

    キャンセル

0

まず, questionImage が何なのかを分かっておられません.

ImageView questionImage

と書いてありますので, questionImage は「画像」では無く「画像を張り付けるモノ」, 言わば額縁です. 「額縁」を見て「北斎の絵」か?「モネの絵」か?と調べても分かるわけありません.

一つの方法は, 正解を後で判定できるように rightAnswer に正解の値を保存しているのと同じく, 画像や音のファイル名等も(保存用の変数を作って)保存しておき, 後でそれを使うという方法です.

ただ…

半分以上意味が分からず書いています

というのでは, ハッキリ申し上げてこのまま作り続けても時間が掛かるばかりで, 動いても動かなくても理由が分からず, 質問し続けることになるかと思います.
独学にせよスクールで学ぶにせよ, 少なくとも元となったコードの理解を優先したほうが宜しいのではと思います.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/12/23 00:12

    勉強しながら頑張ります!

    「まあよく分からんけど動けばいいか・・」
    的な性格もあり、上手く動いたら、なぜ成功したのか、どうしたら動かなくなるのか、と考える方が、性に合っているようです。

    ここで質問させていただいたのは、アプリでどうしても欲しい挙動でしたので、本当にうれしいです。

    ありがとうございました!!
    しばらくはdartの勉強をします。

    キャンセル

  • 2019/12/23 01:08

    > 上手く動いたら、なぜ成功したのか、どうしたら動かなくなるのか、と考える方が、性に合っているようです。

    まぁ勉強の仕方は人ぞれぞれではありますが, ただやはり基礎というものはありまして, 応用をいくら試行錯誤しても基礎が無ければなかなかステップアップが進みません. (「応用を一般化して基礎を知る」ことが出来るならもちろん問題無いですが. )
    Gonnnn さんが回答のコメントでおっしゃっていた「変数のスコープ(使える範囲)」について, また(javaにおいて)スコープをどう設計するが良い(とされている)のかという点等も是非お調べになって頂けたらと思います.

    キャンセル

  • 2019/12/23 13:46

    そういえば確か One,Two 等の音声を聞いて数字を当てるような子供向けクイズを作成されていたと思いましたが, 少し路線変更されたのでしょうか.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る