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

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

ただいまの
回答率

89.10%

データベースを利用したゲームを作っています。

解決済

回答 1

投稿 編集

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

問題文をデータベースから取り出す形式のタイピングゲームを作成しています。

問題文をデータベースから取り出してゲーム画面に表示させるところまではできたのですが、正解した際に問題文を変更するプログラムがうまく作れません。

<?php
require_once("lib/util.php");
$clock = 0;
$level = 1;


//データベースユーザー
$user = "user";
$password = "password";

$dbname = "typinggame";
$host = "localhost:";
$dsn = "mysql:host{$host};dbname={$dbname};charset=utf8";

?>

<?php
//mysqlに接続
try{
    $pdo = new PDO($dsn, $user, $password);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);

    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    //SQL文を作る 
    $sql = "SELECT * FROM typinggame.textlist WHERE level = $level ORDER BY RAND() LIMIT 20";
    $stm = $pdo->prepare($sql);
    $stm->execute();
    $result = $stm->fetchAll(PDO::FETCH_ASSOC);

    foreach($result as $row){
      $my_array[] = $row["subject"];
      $varjs = json_encode($my_array[$clock]);
      }


} catch (Exeption $e) {
    echo '<span class="error">エラーがありました。</span><br>';
    echo $e->getMessage();
    exit();
}

?>



<!DOCTYPE html>

<head>
<meta charset="utf-8">
<pre class="lang:js decode:true">  
<script type="text/javascript" src="textfile.js"></script>
<link rel="stylesheet" href="style.css">
</head>

<div id="body">
<h1>タイピングゲーム</h1>
<div id="status">
<h2><p id="point"><p id="timer"></p></h2>
</div>
<div id="mondai">
<p id="subject"></p>
</div>


<form name="typing"  onsubmit="return false;">

        <input name="input" style="width:30%;padding:10px;font-size:16px;" autocomplete="off" type="text"><input name="btn" type="submit" style="width:3%;padding:10px;font-size:16px;" value="解答" >
        <input name="start" type="button" style="width:10%;padding:10px;font-size:16px;" value="ゲームスタート"><input type="button" name="button" value="アリーヴェデルチ" style="width:10%;padding:10px;font-size:16px;"
        onclick=closewindow()>

</form>
<h3><p id="message"></p></h3>

<div id="rule">
<h1>ルール説明 How to play</h1>
<p>
  出題された文字を間違えずに入力しろ!制限時間は1問につき10秒だけ。<br>
  正解すれば1点がもらえて次の問題へ。間違えたり時間切れになった場合は即失格。<br>
  問題は正解数が増えるごとに難しくなっていくので注意!<br>
</p>
</div>

<div id="footer">
  <p>copyright 2020 xxxx all.rights.reserved</p>
</div>


</div>

<script>
//ここからJavaScript


const subject = document.getElementById('subject');
const timer = document.getElementById('timer');
const point = document.getElementById("point");
const stock = document.getElementById("life");
const message = document.getElementById("message");
const start = document.getElementById("start");
const form = document.forms.typing;



let rank;
let TIME = 10;
let count = 0;
let state = false;
let wrong = 0;
let life = 1;
let ins = 1;
let fiveup = 1;
let mondai;
let gamestart = 0;
let countdown;


var useitem = new Audio("https://xxx");
var doitem = new Audio("https://xxx");
var mainbgm = new Audio("https://xxx");
var finishbgm = new Audio("https://xxx");

point.textContent = "ポイント:" + 0; 
timer.textContent = "Prease Start Button";
subject.textContent = "ゲームスタートを押してね";

//制限時間
function gametimer(){
   countdown = setInterval(function() {
  if(gamestart == 1){

  timer.textContent = '制限時間:' + --TIME + '秒';
  if(TIME <= 0) {
    life--;
  if (life <= 0) finish()

  }
  }
}, 1000);
}




//正誤判定
form.btn.addEventListener('click', function(e) {
  if(!state) return;

  if(form.input.value === subject.textContent) {
    count++;
    point.textContent = "ポイント:" + count;

    timer.textContent = "制限時間:" + 10 + "秒";
    TIME = 10;

    if(life == 2){
      life--;

    }
    <?php $clock++; ?>
    init();

  } else {
    life--;

    if(life > 0){
    timer.textContent = "制限時間:" + 10 + "秒";
    TIME = 10;
    message.textContent = "アイテムの効果が発動し、不正解による失格を防いだ!"
    subject.textContent = mondai;
    form.input.value = '';
    doitem.play();
    }

    else {
      wrong++;
      finish();
    }
  } 
});


//出題
function init() {

  var rnd =JSON.parse('<?php echo $varjs; ?>');
  subject.textContent = rnd;
  form.input.value = '';
  form.input.focus();
}

//ゲームオーバー時の処理
function finish() {
  clearInterval(countdown);
  state = false;
  if(wrong <= 0){
  mainbgm.pause();

  mainbgm.currentTime = 0;
  finishbgm.play();
  point.textcontent = "";
  timer.textContent = "プレイしてくれてありがとう!\nもっかいプレイするなんて酔狂な真似をするかい?";
  message.textContent = "";
  subject.textContent = 'GAME OVER\n時間切れにつき終了!正解数は' + count + '個でした!';
  gamestart = 0;
  state = false;
  } else {
  mainbgm.pause();
  mainbgm.currentTime = 0;
  finishbgm.play();
  point.textcontent = "";
  timer.textContent = "プレイしてくれてありがとう!\nもっかいプレイするなんて酔狂な真似をするかい?";
  message.textContent = "";
  subject.textContent = 'GAME OVER\n時間切れにつき終了!正解数は' + count + '個でした!';
  gamestart = 0;
  }
}  





//スタートボタン
form.start.addEventListener('click', function(e) {

  if(gamestart == 0){
   state = true;
    gamestart = 1;
    init();
    mainbgm.play();
    count = 0;
    life = 1;
    ins = 1;
    fiveup = 1;
    point.textContent = "ポイント:" + count;
    gametimer();
  };


});


function closewindow(){
  alert("こんなゲームをプレイしてくれてありがとう!\n完");
  window.close();
}



</script>
</pre>

</html>

$my_arrayの配列にはランダムに入れた問題文が入っています。それを$clockの数値を切り替えることで問題文を変更できるようにしたいのですが、うまく動作しませんでした。$clockの位置を変えたりしてもうまくいきません。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • Matsuta174320

    2020/06/30 16:31

    それは想定していない動作です。
    ikeda様の言うように、問題文は1種類しか表示されず、更新すると別の問題に切り替わり、次の更新まで切り替わった問題だけが繰り返し出題されるという状況です。

    キャンセル

  • gogoweb_ikeda

    2020/06/30 16:42

    正解したときにどのような方法で問題を更新するのを想定しているのでしょうか?
    現状ですと問題文は一問しかセットされておらず、正答後initを実行しても同じ問題が実行されると思います。(この時点ですでにphpは実行完了しているのでAjaxでもないかぎりphp側からデータを変更はできません)
    そのため考えられるのは
    1.複数の問題をまとめて取得して配列に保存しておく
    2.Ajax通信で正解後に改めて問題を取得する
    3.正解後パラメータを追加してページを再読み込みする(おすすめしません)
    等でしょうか?

    キャンセル

  • Matsuta174320

    2020/06/30 16:48

    3つの中で一番近いのは1の複数の問題をまとめて取得して配列に保存する方法です。

    キャンセル

回答 1

checkベストアンサー

0

foreach($result as $row){
$my_array[] = $row["subject"];
$varjs = json_encode($my_array[$clock]);
}


この部分を

foreach($result as $row){
$my_array[] = $row["subject"];
}
$varjs = json_encode($my_array);


に変更することで問題が配列で取得できると思われます。
そのあと

var rnd =JSON.parse('<?php echo $varjs; ?>');
  subject.textContent = rnd;


の部分でrndを配列でデータを取得する形にすればいいのではないでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/01 15:39

    ご回答ありがとうございます。
    あれから実際にphpの部分を変更し、rndに<?php echo $varjs[($clock)]; ?>');を代入しましたが、「SyntaxError: Unexpected token '<'」と出てしまい問題がうまく抽出されませんでした。
    また、一度$clockを消去し、$varjs[rand(0,19)]に変更すると、エラーは出ませんでしたが問題文ではなく配列の番号(1や7など)が出題され、回答を入力してもランダム出題はされませんでした。
    もしかしたらうまく配列からデータを取得できていないのかもしれませんが、この状況をどう直せばいいでしょうか?

    キャンセル

  • 2020/07/01 16:17

    $clockを消してrndに代入後console.log(rnd)をしてみてください。
    コンソールにおそらく["a","b","c","d"]のような値が表示されていると思いますがどうでしょうか?
    phpとjavascirptを混合しているように見えますが一度サーバーから出力された時点でphpの役目は終わりになります。そのため$clockの値や$varjsの値を変更しても意味はありません。
    操作するならjsonデータが入っているrndの方です。

    キャンセル

  • 2020/07/01 16:51 編集

    rndの中には挿入した配列が入っていました。
    その後、少しソースコードを変えて、phpで配列を挿入しJavascriptに配列データを送った後、Javascript側でランダム出題の処理をすることでランダム出題の処理を実装させることができました。この度はありがとうございました。

    キャンセル

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

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

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